1*e4b17023SJohn Marino // Wrapper for underlying C-language localization -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4*e4b17023SJohn Marino // Free Software Foundation, Inc. 5*e4b17023SJohn Marino // 6*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 7*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 8*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 9*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 10*e4b17023SJohn Marino // any later version. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 13*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 14*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*e4b17023SJohn Marino // GNU General Public License for more details. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 18*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 19*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 20*e4b17023SJohn Marino 21*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 22*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 23*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 25*e4b17023SJohn Marino 26*e4b17023SJohn Marino // 27*e4b17023SJohn Marino // ISO C++ 14882: 22.8 Standard locale categories. 28*e4b17023SJohn Marino // 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino // Written by Benjamin Kosnik <bkoz@redhat.com> 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino #include <cerrno> // For errno 33*e4b17023SJohn Marino #include <cmath> // For isinf, finite, finitef, fabs 34*e4b17023SJohn Marino #include <cstdlib> // For strof, strtold 35*e4b17023SJohn Marino #include <cstring> 36*e4b17023SJohn Marino #include <cstdio> 37*e4b17023SJohn Marino #include <locale> 38*e4b17023SJohn Marino #include <limits> 39*e4b17023SJohn Marino 40*e4b17023SJohn Marino #ifdef _GLIBCXX_HAVE_IEEEFP_H 41*e4b17023SJohn Marino #include <ieeefp.h> 42*e4b17023SJohn Marino #endif 43*e4b17023SJohn Marino 44*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 45*e4b17023SJohn Marino { 46*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 47*e4b17023SJohn Marino 48*e4b17023SJohn Marino template<> 49*e4b17023SJohn Marino void __convert_to_v(const char * __s,float & __v,ios_base::iostate & __err,const __c_locale &)50*e4b17023SJohn Marino __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 51*e4b17023SJohn Marino const __c_locale&) throw() 52*e4b17023SJohn Marino { 53*e4b17023SJohn Marino // Assumes __s formatted for "C" locale. 54*e4b17023SJohn Marino char* __old = setlocale(LC_ALL, 0); 55*e4b17023SJohn Marino const size_t __len = strlen(__old) + 1; 56*e4b17023SJohn Marino char* __sav = new char[__len]; 57*e4b17023SJohn Marino memcpy(__sav, __old, __len); 58*e4b17023SJohn Marino setlocale(LC_ALL, "C"); 59*e4b17023SJohn Marino char* __sanity; 60*e4b17023SJohn Marino bool __overflow = false; 61*e4b17023SJohn Marino 62*e4b17023SJohn Marino #if !__FLT_HAS_INFINITY__ 63*e4b17023SJohn Marino errno = 0; 64*e4b17023SJohn Marino #endif 65*e4b17023SJohn Marino 66*e4b17023SJohn Marino #ifdef _GLIBCXX_HAVE_STRTOF 67*e4b17023SJohn Marino __v = strtof(__s, &__sanity); 68*e4b17023SJohn Marino #else 69*e4b17023SJohn Marino double __d = strtod(__s, &__sanity); 70*e4b17023SJohn Marino __v = static_cast<float>(__d); 71*e4b17023SJohn Marino #ifdef _GLIBCXX_HAVE_FINITEF 72*e4b17023SJohn Marino if (!finitef (__v)) 73*e4b17023SJohn Marino __overflow = true; 74*e4b17023SJohn Marino #elif defined (_GLIBCXX_HAVE_FINITE) 75*e4b17023SJohn Marino if (!finite (static_cast<double> (__v))) 76*e4b17023SJohn Marino __overflow = true; 77*e4b17023SJohn Marino #elif defined (_GLIBCXX_HAVE_ISINF) 78*e4b17023SJohn Marino if (isinf (static_cast<double> (__v))) 79*e4b17023SJohn Marino __overflow = true; 80*e4b17023SJohn Marino #else 81*e4b17023SJohn Marino if (fabs(__d) > numeric_limits<float>::max()) 82*e4b17023SJohn Marino __overflow = true; 83*e4b17023SJohn Marino #endif 84*e4b17023SJohn Marino #endif // _GLIBCXX_HAVE_STRTOF 85*e4b17023SJohn Marino 86*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 87*e4b17023SJohn Marino // 23. Num_get overflow result. 88*e4b17023SJohn Marino if (__sanity == __s || *__sanity != '\0') 89*e4b17023SJohn Marino { 90*e4b17023SJohn Marino __v = 0.0f; 91*e4b17023SJohn Marino __err = ios_base::failbit; 92*e4b17023SJohn Marino } 93*e4b17023SJohn Marino else if (__overflow 94*e4b17023SJohn Marino #if __FLT_HAS_INFINITY__ 95*e4b17023SJohn Marino || __v == numeric_limits<float>::infinity() 96*e4b17023SJohn Marino || __v == -numeric_limits<float>::infinity() 97*e4b17023SJohn Marino #else 98*e4b17023SJohn Marino || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE) 99*e4b17023SJohn Marino #endif 100*e4b17023SJohn Marino ) 101*e4b17023SJohn Marino { 102*e4b17023SJohn Marino if (__v > 0.0f) 103*e4b17023SJohn Marino __v = numeric_limits<float>::max(); 104*e4b17023SJohn Marino else 105*e4b17023SJohn Marino __v = -numeric_limits<float>::max(); 106*e4b17023SJohn Marino __err = ios_base::failbit; 107*e4b17023SJohn Marino } 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino setlocale(LC_ALL, __sav); 110*e4b17023SJohn Marino delete [] __sav; 111*e4b17023SJohn Marino } 112*e4b17023SJohn Marino 113*e4b17023SJohn Marino template<> 114*e4b17023SJohn Marino void __convert_to_v(const char * __s,double & __v,ios_base::iostate & __err,const __c_locale &)115*e4b17023SJohn Marino __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 116*e4b17023SJohn Marino const __c_locale&) throw() 117*e4b17023SJohn Marino { 118*e4b17023SJohn Marino // Assumes __s formatted for "C" locale. 119*e4b17023SJohn Marino char* __old = setlocale(LC_ALL, 0); 120*e4b17023SJohn Marino const size_t __len = strlen(__old) + 1; 121*e4b17023SJohn Marino char* __sav = new char[__len]; 122*e4b17023SJohn Marino memcpy(__sav, __old, __len); 123*e4b17023SJohn Marino setlocale(LC_ALL, "C"); 124*e4b17023SJohn Marino char* __sanity; 125*e4b17023SJohn Marino 126*e4b17023SJohn Marino #if !__DBL_HAS_INFINITY__ 127*e4b17023SJohn Marino errno = 0; 128*e4b17023SJohn Marino #endif 129*e4b17023SJohn Marino 130*e4b17023SJohn Marino __v = strtod(__s, &__sanity); 131*e4b17023SJohn Marino 132*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 133*e4b17023SJohn Marino // 23. Num_get overflow result. 134*e4b17023SJohn Marino if (__sanity == __s || *__sanity != '\0') 135*e4b17023SJohn Marino { 136*e4b17023SJohn Marino __v = 0.0; 137*e4b17023SJohn Marino __err = ios_base::failbit; 138*e4b17023SJohn Marino } 139*e4b17023SJohn Marino else if ( 140*e4b17023SJohn Marino #if __DBL_HAS_INFINITY__ 141*e4b17023SJohn Marino __v == numeric_limits<double>::infinity() 142*e4b17023SJohn Marino || __v == -numeric_limits<double>::infinity()) 143*e4b17023SJohn Marino #else 144*e4b17023SJohn Marino (__v > 1.0 || __v < -1.0) && errno == ERANGE) 145*e4b17023SJohn Marino #endif 146*e4b17023SJohn Marino { 147*e4b17023SJohn Marino if (__v > 0.0) 148*e4b17023SJohn Marino __v = numeric_limits<double>::max(); 149*e4b17023SJohn Marino else 150*e4b17023SJohn Marino __v = -numeric_limits<double>::max(); 151*e4b17023SJohn Marino __err = ios_base::failbit; 152*e4b17023SJohn Marino } 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino setlocale(LC_ALL, __sav); 155*e4b17023SJohn Marino delete [] __sav; 156*e4b17023SJohn Marino } 157*e4b17023SJohn Marino 158*e4b17023SJohn Marino template<> 159*e4b17023SJohn Marino void __convert_to_v(const char * __s,long double & __v,ios_base::iostate & __err,const __c_locale &)160*e4b17023SJohn Marino __convert_to_v(const char* __s, long double& __v, 161*e4b17023SJohn Marino ios_base::iostate& __err, const __c_locale&) throw() 162*e4b17023SJohn Marino { 163*e4b17023SJohn Marino // Assumes __s formatted for "C" locale. 164*e4b17023SJohn Marino char* __old = setlocale(LC_ALL, 0); 165*e4b17023SJohn Marino const size_t __len = strlen(__old) + 1; 166*e4b17023SJohn Marino char* __sav = new char[__len]; 167*e4b17023SJohn Marino memcpy(__sav, __old, __len); 168*e4b17023SJohn Marino setlocale(LC_ALL, "C"); 169*e4b17023SJohn Marino 170*e4b17023SJohn Marino #if !__LDBL_HAS_INFINITY__ 171*e4b17023SJohn Marino errno = 0; 172*e4b17023SJohn Marino #endif 173*e4b17023SJohn Marino 174*e4b17023SJohn Marino #if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD) 175*e4b17023SJohn Marino char* __sanity; 176*e4b17023SJohn Marino __v = strtold(__s, &__sanity); 177*e4b17023SJohn Marino 178*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 179*e4b17023SJohn Marino // 23. Num_get overflow result. 180*e4b17023SJohn Marino if (__sanity == __s || *__sanity != '\0') 181*e4b17023SJohn Marino #else 182*e4b17023SJohn Marino typedef char_traits<char>::int_type int_type; 183*e4b17023SJohn Marino int __p = sscanf(__s, "%Lf", &__v); 184*e4b17023SJohn Marino 185*e4b17023SJohn Marino if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof()) 186*e4b17023SJohn Marino #endif 187*e4b17023SJohn Marino { 188*e4b17023SJohn Marino __v = 0.0l; 189*e4b17023SJohn Marino __err = ios_base::failbit; 190*e4b17023SJohn Marino } 191*e4b17023SJohn Marino else if ( 192*e4b17023SJohn Marino #if __LDBL_HAS_INFINITY__ 193*e4b17023SJohn Marino __v == numeric_limits<long double>::infinity() 194*e4b17023SJohn Marino || __v == -numeric_limits<long double>::infinity()) 195*e4b17023SJohn Marino #else 196*e4b17023SJohn Marino (__v > 1.0l || __v < -1.0l) && errno == ERANGE) 197*e4b17023SJohn Marino #endif 198*e4b17023SJohn Marino { 199*e4b17023SJohn Marino if (__v > 0.0l) 200*e4b17023SJohn Marino __v = numeric_limits<long double>::max(); 201*e4b17023SJohn Marino else 202*e4b17023SJohn Marino __v = -numeric_limits<long double>::max(); 203*e4b17023SJohn Marino __err = ios_base::failbit; 204*e4b17023SJohn Marino } 205*e4b17023SJohn Marino 206*e4b17023SJohn Marino setlocale(LC_ALL, __sav); 207*e4b17023SJohn Marino delete [] __sav; 208*e4b17023SJohn Marino } 209*e4b17023SJohn Marino 210*e4b17023SJohn Marino void _S_create_c_locale(__c_locale & __cloc,const char * __s,__c_locale)211*e4b17023SJohn Marino locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, 212*e4b17023SJohn Marino __c_locale) 213*e4b17023SJohn Marino { 214*e4b17023SJohn Marino // Currently, the generic model only supports the "C" locale. 215*e4b17023SJohn Marino // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html 216*e4b17023SJohn Marino __cloc = 0; 217*e4b17023SJohn Marino if (strcmp(__s, "C")) 218*e4b17023SJohn Marino __throw_runtime_error(__N("locale::facet::_S_create_c_locale " 219*e4b17023SJohn Marino "name not valid")); 220*e4b17023SJohn Marino } 221*e4b17023SJohn Marino 222*e4b17023SJohn Marino void _S_destroy_c_locale(__c_locale & __cloc)223*e4b17023SJohn Marino locale::facet::_S_destroy_c_locale(__c_locale& __cloc) 224*e4b17023SJohn Marino { __cloc = 0; } 225*e4b17023SJohn Marino 226*e4b17023SJohn Marino __c_locale _S_clone_c_locale(__c_locale &)227*e4b17023SJohn Marino locale::facet::_S_clone_c_locale(__c_locale&) throw() 228*e4b17023SJohn Marino { return __c_locale(); } 229*e4b17023SJohn Marino 230*e4b17023SJohn Marino __c_locale _S_lc_ctype_c_locale(__c_locale,const char *)231*e4b17023SJohn Marino locale::facet::_S_lc_ctype_c_locale(__c_locale, const char*) 232*e4b17023SJohn Marino { return __c_locale(); } 233*e4b17023SJohn Marino 234*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 235*e4b17023SJohn Marino } // namespace 236*e4b17023SJohn Marino 237*e4b17023SJohn Marino namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 238*e4b17023SJohn Marino { 239*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 240*e4b17023SJohn Marino 241*e4b17023SJohn Marino const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] = 242*e4b17023SJohn Marino { 243*e4b17023SJohn Marino "LC_CTYPE", 244*e4b17023SJohn Marino "LC_NUMERIC", 245*e4b17023SJohn Marino "LC_TIME", 246*e4b17023SJohn Marino "LC_COLLATE", 247*e4b17023SJohn Marino "LC_MONETARY", 248*e4b17023SJohn Marino "LC_MESSAGES" 249*e4b17023SJohn Marino }; 250*e4b17023SJohn Marino 251*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 252*e4b17023SJohn Marino } // namespace 253*e4b17023SJohn Marino 254*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 255*e4b17023SJohn Marino { 256*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino const char* const* const locale::_S_categories = __gnu_cxx::category_names; 259*e4b17023SJohn Marino 260*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 261*e4b17023SJohn Marino } // namespace 262*e4b17023SJohn Marino 263*e4b17023SJohn Marino // XXX GLIBCXX_ABI Deprecated 264*e4b17023SJohn Marino #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT 265*e4b17023SJohn Marino #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ 266*e4b17023SJohn Marino extern "C" void ldbl (void) __attribute__ ((alias (#dbl))) 267*e4b17023SJohn Marino _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi); 268*e4b17023SJohn Marino #endif // _GLIBCXX_LONG_DOUBLE_COMPAT 269