1// Wrapper for underlying C-language localization -*- C++ -*- 2 3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING. If not, write to the Free 19// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20// USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// 32// ISO C++ 14882: 22.8 Standard locale categories. 33// 34 35// Written by Benjamin Kosnik <bkoz@redhat.com> 36 37#include <cerrno> // For errno 38#include <cmath> // For isinf, finite, finitef, fabs 39#include <cstdlib> // For strof, strtold 40#include <locale> 41 42#ifdef _GLIBCXX_HAVE_IEEEFP_H 43#include <ieeefp.h> 44#endif 45 46_GLIBCXX_BEGIN_NAMESPACE(std) 47 48 // Specializations for all types used in num_get. 49 template<> 50 void 51 __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 52 const __c_locale&) 53 { 54 // Assumes __s formatted for "C" locale. 55 errno = 0; 56 char* __old = strdup(setlocale(LC_ALL, NULL)); 57 setlocale(LC_ALL, "C"); 58 char* __sanity; 59#if defined(_GLIBCXX_HAVE_STRTOF) 60 float __f = strtof(__s, &__sanity); 61#else 62 double __d = strtod(__s, &__sanity); 63 float __f = static_cast<float>(__d); 64#ifdef _GLIBCXX_HAVE_FINITEF 65 if (!finitef (__f)) 66 errno = ERANGE; 67#elif defined (_GLIBCXX_HAVE_FINITE) 68 if (!finite (static_cast<double> (__f))) 69 errno = ERANGE; 70#elif defined (_GLIBCXX_HAVE_ISINF) 71 if (isinf (static_cast<double> (__f))) 72 errno = ERANGE; 73#else 74 if (fabs(__d) > numeric_limits<float>::max()) 75 errno = ERANGE; 76#endif 77#endif 78 if (__sanity != __s && errno != ERANGE) 79 __v = __f; 80 else 81 __err |= ios_base::failbit; 82 setlocale(LC_ALL, __old); 83 free(__old); 84 } 85 86 template<> 87 void 88 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 89 const __c_locale&) 90 { 91 // Assumes __s formatted for "C" locale. 92 errno = 0; 93 char* __old = strdup(setlocale(LC_ALL, NULL)); 94 setlocale(LC_ALL, "C"); 95 char* __sanity; 96 double __d = strtod(__s, &__sanity); 97 if (__sanity != __s && errno != ERANGE) 98 __v = __d; 99 else 100 __err |= ios_base::failbit; 101 setlocale(LC_ALL, __old); 102 free(__old); 103 } 104 105 template<> 106 void 107 __convert_to_v(const char* __s, long double& __v, 108 ios_base::iostate& __err, const __c_locale&) 109 { 110 // Assumes __s formatted for "C" locale. 111 errno = 0; 112 char* __old = strdup(setlocale(LC_ALL, NULL)); 113 setlocale(LC_ALL, "C"); 114#if defined(_GLIBCXX_HAVE_STRTOLD) 115 char* __sanity; 116 long double __ld = strtold(__s, &__sanity); 117 if (__sanity != __s && errno != ERANGE) 118 __v = __ld; 119#else 120 typedef char_traits<char>::int_type int_type; 121 long double __ld; 122 int __p = sscanf(__s, "%Lf", &__ld); 123 if (__p && static_cast<int_type>(__p) != char_traits<char>::eof() 124 && errno != ERANGE) 125 __v = __ld; 126#endif 127 else 128 __err |= ios_base::failbit; 129 setlocale(LC_ALL, __old); 130 free(__old); 131 } 132 133 void 134 locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, 135 __c_locale) 136 { 137 // Currently, the generic model only supports the "C" locale. 138 // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html 139 __cloc = NULL; 140 if (strcmp(__s, "C")) 141 __throw_runtime_error(__N("locale::facet::_S_create_c_locale " 142 "name not valid")); 143 } 144 145 void 146 locale::facet::_S_destroy_c_locale(__c_locale& __cloc) 147 { __cloc = NULL; } 148 149 __c_locale 150 locale::facet::_S_clone_c_locale(__c_locale&) 151 { return __c_locale(); } 152 153_GLIBCXX_END_NAMESPACE 154 155_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 156 157 const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] = 158 { 159 "LC_CTYPE", 160 "LC_NUMERIC", 161 "LC_TIME", 162 "LC_COLLATE", 163 "LC_MONETARY", 164 "LC_MESSAGES" 165 }; 166 167_GLIBCXX_END_NAMESPACE 168 169_GLIBCXX_BEGIN_NAMESPACE(std) 170 171 const char* const* const locale::_S_categories = __gnu_cxx::category_names; 172 173_GLIBCXX_END_NAMESPACE 174 175// XXX GLIBCXX_ABI Deprecated 176#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT 177#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ 178 extern "C" void ldbl (void) __attribute__ ((alias (#dbl))) 179_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi); 180#endif // _GLIBCXX_LONG_DOUBLE_COMPAT 181