c_locale.cc revision 97403
1193323Sed// Wrapper for underlying C-language localization -*- C++ -*- 2193323Sed 3193323Sed// Copyright (C) 2001, 2002 Free Software Foundation, Inc. 4193323Sed// 5193323Sed// This file is part of the GNU ISO C++ Library. This library is free 6193323Sed// software; you can redistribute it and/or modify it under the 7193323Sed// terms of the GNU General Public License as published by the 8193323Sed// Free Software Foundation; either version 2, or (at your option) 9193323Sed// any later version. 10193323Sed 11193323Sed// This library is distributed in the hope that it will be useful, 12193323Sed// but WITHOUT ANY WARRANTY; without even the implied warranty of 13193323Sed// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14193323Sed// GNU General Public License for more details. 15193323Sed 16193323Sed// You should have received a copy of the GNU General Public License along 17193323Sed// with this library; see the file COPYING. If not, write to the Free 18218893Sdim// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19193323Sed// USA. 20193323Sed 21193323Sed// As a special exception, you may use this file as part of a free software 22193323Sed// library without restriction. Specifically, if other files instantiate 23193323Sed// templates or use macros or inline functions from this file, or you compile 24193323Sed// this file and link it with other files to produce an executable, this 25224145Sdim// file does not by itself cause the resulting executable to be covered by 26249423Sdim// the GNU General Public License. This exception does not however 27249423Sdim// invalidate any other reasons why the executable file might be covered by 28193323Sed// the GNU General Public License. 29193323Sed 30193323Sed// 31218893Sdim// ISO C++ 14882: 22.8 Standard locale categories. 32193323Sed// 33193323Sed 34221345Sdim// Written by Benjamin Kosnik <bkoz@redhat.com> 35193323Sed 36193323Sed#include <locale> 37193323Sed 38193323Sed#ifdef _GLIBCPP_HAVE_IEEEFP_H 39193323Sed#include <ieeefp.h> 40219077Sdim#endif 41219077Sdim 42219077Sdimnamespace std 43219077Sdim{ 44219077Sdim // Specializations for all types used in num_get. 45219077Sdim template<> 46193323Sed void 47218893Sdim __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 48198090Srdivacky const __c_locale&, int __base) 49198090Srdivacky { 50218893Sdim if (!(__err & ios_base::failbit)) 51203954Srdivacky { 52203954Srdivacky char* __sanity; 53218893Sdim errno = 0; 54193574Sed long __l = strtol(__s, &__sanity, __base); 55193574Sed if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 56219077Sdim __v = __l; 57219077Sdim else 58219077Sdim __err |= ios_base::failbit; 59219077Sdim } 60219077Sdim } 61219077Sdim 62193323Sed template<> 63218893Sdim void 64198090Srdivacky __convert_to_v(const char* __s, unsigned long& __v, 65198090Srdivacky ios_base::iostate& __err, const __c_locale&, int __base) 66218893Sdim { 67203954Srdivacky if (!(__err & ios_base::failbit)) 68203954Srdivacky { 69218893Sdim char* __sanity; 70193574Sed errno = 0; 71193574Sed unsigned long __ul = strtoul(__s, &__sanity, __base); 72219077Sdim if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 73219077Sdim __v = __ul; 74219077Sdim else 75219077Sdim __err |= ios_base::failbit; 76219077Sdim } 77219077Sdim } 78193323Sed 79218893Sdim#ifdef _GLIBCPP_USE_LONG_LONG 80201360Srdivacky template<> 81201360Srdivacky void 82218893Sdim __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 83203954Srdivacky const __c_locale&, int __base) 84203954Srdivacky { 85218893Sdim if (!(__err & ios_base::failbit)) 86193574Sed { 87193574Sed char* __sanity; 88219077Sdim errno = 0; 89219077Sdim long long __ll = strtoll(__s, &__sanity, __base); 90219077Sdim if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 91219077Sdim __v = __ll; 92219077Sdim else 93193323Sed __err |= ios_base::failbit; 94218893Sdim } 95218893Sdim } 96218893Sdim 97219077Sdim template<> 98219077Sdim void 99219077Sdim __convert_to_v(const char* __s, unsigned long long& __v, 100219077Sdim ios_base::iostate& __err, const __c_locale&, int __base) 101219077Sdim { 102193323Sed if (!(__err & ios_base::failbit)) 103218893Sdim { 104198090Srdivacky char* __sanity; 105198090Srdivacky errno = 0; 106218893Sdim unsigned long long __ull = strtoull(__s, &__sanity, __base); 107193323Sed if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 108193323Sed __v = __ull; 109218893Sdim else 110193323Sed __err |= ios_base::failbit; 111193323Sed } 112218893Sdim } 113193323Sed#endif 114193323Sed 115218893Sdim template<> 116193323Sed void 117193323Sed __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 118219077Sdim const __c_locale&, int) 119219077Sdim { 120219077Sdim if (!(__err & ios_base::failbit)) 121219077Sdim { 122219077Sdim // Assumes __s formatted for "C" locale. 123219077Sdim const char* __old = setlocale(LC_ALL, "C"); 124193323Sed char* __sanity; 125219077Sdim errno = 0; 126219077Sdim#if defined(_GLIBCPP_USE_C99) 127219077Sdim float __f = strtof(__s, &__sanity); 128219077Sdim#else 129219077Sdim double __d = strtod(__s, &__sanity); 130193323Sed float __f = static_cast<float>(__d); 131219077Sdim#ifdef _GLIBCPP_HAVE_FINITEF 132219077Sdim if (!finitef (__f)) 133219077Sdim errno = ERANGE; 134219077Sdim#elif defined (_GLIBCPP_HAVE_FINITE) 135219077Sdim if (!finite (static_cast<double> (__f))) 136193323Sed errno = ERANGE; 137218893Sdim#elif defined (_GLIBCPP_HAVE_ISINF) 138193323Sed if (isinf (static_cast<double> (__f))) 139193323Sed errno = ERANGE; 140218893Sdim#else 141193323Sed if (fabs(__d) > numeric_limits<float>::max()) 142193323Sed errno = ERANGE; 143218893Sdim#endif 144193323Sed#endif 145193323Sed if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 146193323Sed __v = __f; 147218893Sdim else 148218893Sdim __err |= ios_base::failbit; 149193323Sed setlocale(LC_ALL, __old); 150193323Sed } 151193323Sed } 152193323Sed 153193323Sed template<> 154193323Sed void 155193323Sed __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 156219077Sdim const __c_locale&, int) 157219077Sdim { 158219077Sdim if (!(__err & ios_base::failbit)) 159219077Sdim { 160219077Sdim // Assumes __s formatted for "C" locale. 161219077Sdim const char* __old = setlocale(LC_ALL, "C"); 162193323Sed char* __sanity; 163218893Sdim errno = 0; 164201360Srdivacky double __d = strtod(__s, &__sanity); 165201360Srdivacky if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 166218893Sdim __v = __d; 167203954Srdivacky else 168203954Srdivacky __err |= ios_base::failbit; 169218893Sdim setlocale(LC_ALL, __old); 170218893Sdim } 171218893Sdim } 172218893Sdim 173193323Sed template<> 174193323Sed void 175193323Sed __convert_to_v(const char* __s, long double& __v, 176193323Sed ios_base::iostate& __err, const __c_locale&, int) 177193323Sed { 178193323Sed if (!(__err & ios_base::failbit)) 179193323Sed { 180226633Sdim // Assumes __s formatted for "C" locale. 181226633Sdim const char* __old = setlocale(LC_ALL, "C"); 182226633Sdim#if defined(_GLIBCPP_USE_C99) 183193323Sed char* __sanity; 184239462Sdim errno = 0; 185239462Sdim long double __ld = strtold(__s, &__sanity); 186239462Sdim if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 187239462Sdim __v = __ld; 188239462Sdim#else 189239462Sdim typedef char_traits<char>::int_type int_type; 190226633Sdim long double __ld; 191226633Sdim errno = 0; 192226633Sdim int __p = sscanf(__s, "%Lf", &__ld); 193193323Sed if (errno == ERANGE) 194193323Sed __p = 0; 195226633Sdim#ifdef _GLIBCPP_HAVE_FINITEL 196226633Sdim if ((__p == 1) && !finitel (__ld)) 197226633Sdim __p = 0; 198198090Srdivacky#endif 199239462Sdim if (__p && static_cast<int_type>(__p) != char_traits<char>::eof()) 200239462Sdim __v = __ld; 201239462Sdim#endif 202239462Sdim else 203239462Sdim __err |= ios_base::failbit; 204239462Sdim setlocale(LC_ALL, __old); 205226633Sdim } 206226633Sdim } 207226633Sdim 208198090Srdivacky void 209198090Srdivacky locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*, 210193323Sed __c_locale) 211193323Sed { __cloc = NULL; } 212193323Sed 213193323Sed void 214218893Sdim locale::facet::_S_destroy_c_locale(__c_locale& __cloc) 215226633Sdim { __cloc = NULL; } 216193323Sed 217193323Sed __c_locale 218226633Sdim locale::facet::_S_clone_c_locale(__c_locale&) 219218893Sdim { return __c_locale(); } 220218893Sdim} // namespace std 221226633Sdim