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