c_locale.cc revision 102782
1// Wrapper for underlying C-language localization -*- C++ -*- 2 3// Copyright (C) 2001, 2002 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 2, 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// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30// 31// ISO C++ 14882: 22.8 Standard locale categories. 32// 33 34// Written by Benjamin Kosnik <bkoz@redhat.com> 35 36#include <locale> 37 38#ifdef _GLIBCPP_HAVE_IEEEFP_H 39#include <ieeefp.h> 40#endif 41 42namespace std 43{ 44 // Specializations for all types used in num_get. 45 template<> 46 void 47 __convert_to_v(const char* __s, long& __v, ios_base::iostate& __err, 48 const __c_locale&, int __base) 49 { 50 if (!(__err & ios_base::failbit)) 51 { 52 char* __sanity; 53 errno = 0; 54 long __l = strtol(__s, &__sanity, __base); 55 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 56 __v = __l; 57 else 58 __err |= ios_base::failbit; 59 } 60 } 61 62 template<> 63 void 64 __convert_to_v(const char* __s, unsigned long& __v, 65 ios_base::iostate& __err, const __c_locale&, int __base) 66 { 67 if (!(__err & ios_base::failbit)) 68 { 69 char* __sanity; 70 errno = 0; 71 unsigned long __ul = strtoul(__s, &__sanity, __base); 72 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 73 __v = __ul; 74 else 75 __err |= ios_base::failbit; 76 } 77 } 78 79#ifdef _GLIBCPP_USE_LONG_LONG 80 template<> 81 void 82 __convert_to_v(const char* __s, long long& __v, ios_base::iostate& __err, 83 const __c_locale&, int __base) 84 { 85 if (!(__err & ios_base::failbit)) 86 { 87 char* __sanity; 88 errno = 0; 89 long long __ll = strtoll(__s, &__sanity, __base); 90 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 91 __v = __ll; 92 else 93 __err |= ios_base::failbit; 94 } 95 } 96 97 template<> 98 void 99 __convert_to_v(const char* __s, unsigned long long& __v, 100 ios_base::iostate& __err, const __c_locale&, int __base) 101 { 102 if (!(__err & ios_base::failbit)) 103 { 104 char* __sanity; 105 errno = 0; 106 unsigned long long __ull = strtoull(__s, &__sanity, __base); 107 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 108 __v = __ull; 109 else 110 __err |= ios_base::failbit; 111 } 112 } 113#endif 114 115 template<> 116 void 117 __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 118 const __c_locale&, int) 119 { 120 if (!(__err & ios_base::failbit)) 121 { 122 // Assumes __s formatted for "C" locale. 123 char* __old = strdup(setlocale(LC_ALL, NULL)); 124 setlocale(LC_ALL, "C"); 125 char* __sanity; 126 errno = 0; 127#if defined(_GLIBCPP_USE_C99) 128 float __f = strtof(__s, &__sanity); 129#else 130 double __d = strtod(__s, &__sanity); 131 float __f = static_cast<float>(__d); 132#ifdef _GLIBCPP_HAVE_FINITEF 133 if (!finitef (__f)) 134 errno = ERANGE; 135#elif defined (_GLIBCPP_HAVE_FINITE) 136 if (!finite (static_cast<double> (__f))) 137 errno = ERANGE; 138#elif defined (_GLIBCPP_HAVE_ISINF) 139 if (isinf (static_cast<double> (__f))) 140 errno = ERANGE; 141#else 142 if (fabs(__d) > numeric_limits<float>::max()) 143 errno = ERANGE; 144#endif 145#endif 146 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 147 __v = __f; 148 else 149 __err |= ios_base::failbit; 150 setlocale(LC_ALL, __old); 151 free(__old); 152 } 153 } 154 155 template<> 156 void 157 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 158 const __c_locale&, int) 159 { 160 if (!(__err & ios_base::failbit)) 161 { 162 // Assumes __s formatted for "C" locale. 163 char* __old = strdup(setlocale(LC_ALL, NULL)); 164 setlocale(LC_ALL, "C"); 165 char* __sanity; 166 errno = 0; 167 double __d = strtod(__s, &__sanity); 168 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 169 __v = __d; 170 else 171 __err |= ios_base::failbit; 172 setlocale(LC_ALL, __old); 173 free(__old); 174 } 175 } 176 177 template<> 178 void 179 __convert_to_v(const char* __s, long double& __v, 180 ios_base::iostate& __err, const __c_locale&, int) 181 { 182 if (!(__err & ios_base::failbit)) 183 { 184 // Assumes __s formatted for "C" locale. 185 char* __old = strdup(setlocale(LC_ALL, NULL)); 186 setlocale(LC_ALL, "C"); 187#if defined(_GLIBCPP_USE_C99) 188 char* __sanity; 189 errno = 0; 190 long double __ld = strtold(__s, &__sanity); 191 if (__sanity != __s && *__sanity == '\0' && errno != ERANGE) 192 __v = __ld; 193#else 194 typedef char_traits<char>::int_type int_type; 195 long double __ld; 196 errno = 0; 197 int __p = sscanf(__s, "%Lf", &__ld); 198 if (errno == ERANGE) 199 __p = 0; 200#ifdef _GLIBCPP_HAVE_FINITEL 201 if ((__p == 1) && !finitel (__ld)) 202 __p = 0; 203#endif 204 if (__p && static_cast<int_type>(__p) != char_traits<char>::eof()) 205 __v = __ld; 206#endif 207 else 208 __err |= ios_base::failbit; 209 setlocale(LC_ALL, __old); 210 free(__old); 211 } 212 } 213 214 void 215 locale::facet::_S_create_c_locale(__c_locale& __cloc, const char*, 216 __c_locale) 217 { __cloc = NULL; } 218 219 void 220 locale::facet::_S_destroy_c_locale(__c_locale& __cloc) 221 { __cloc = NULL; } 222 223 __c_locale 224 locale::facet::_S_clone_c_locale(__c_locale&) 225 { return __c_locale(); } 226} // namespace std 227