1 // Wrapper for underlying C-language localization -*- C++ -*- 2 3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 // 27 // ISO C++ 14882: 22.8 Standard locale categories. 28 // 29 30 // Written by Benjamin Kosnik <bkoz@redhat.com> 31 32 #include <locale> 33 #include <stdexcept> 34 #include <limits> 35 #include <langinfo.h> 36 #include <bits/c++locale_internal.h> 37 38 _GLIBCXX_BEGIN_NAMESPACE(std) 39 40 template<> 41 void 42 __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, 43 const __c_locale& __cloc) throw() 44 { 45 char* __sanity; 46 __v = __strtof_l(__s, &__sanity, __cloc); 47 48 // _GLIBCXX_RESOLVE_LIB_DEFECTS 49 // 23. Num_get overflow result. 50 if (__sanity == __s || *__sanity != '\0') 51 { 52 __v = 0.0f; 53 __err = ios_base::failbit; 54 } 55 else if (__v == numeric_limits<float>::infinity()) 56 { 57 __v = numeric_limits<float>::max(); 58 __err = ios_base::failbit; 59 } 60 else if (__v == -numeric_limits<float>::infinity()) 61 { 62 __v = -numeric_limits<float>::max(); 63 __err = ios_base::failbit; 64 } 65 } 66 67 template<> 68 void 69 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, 70 const __c_locale& __cloc) throw() 71 { 72 char* __sanity; 73 __v = __strtod_l(__s, &__sanity, __cloc); 74 75 // _GLIBCXX_RESOLVE_LIB_DEFECTS 76 // 23. Num_get overflow result. 77 if (__sanity == __s || *__sanity != '\0') 78 { 79 __v = 0.0; 80 __err = ios_base::failbit; 81 } 82 else if (__v == numeric_limits<double>::infinity()) 83 { 84 __v = numeric_limits<double>::max(); 85 __err = ios_base::failbit; 86 } 87 else if (__v == -numeric_limits<double>::infinity()) 88 { 89 __v = -numeric_limits<double>::max(); 90 __err = ios_base::failbit; 91 } 92 } 93 94 template<> 95 void 96 __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err, 97 const __c_locale& __cloc) throw() 98 { 99 char* __sanity; 100 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 101 // Prefer strtold_l, as __strtold_l isn't prototyped in more recent 102 // glibc versions. 103 __v = strtold_l(__s, &__sanity, __cloc); 104 #else 105 __v = __strtold_l(__s, &__sanity, __cloc); 106 #endif 107 108 // _GLIBCXX_RESOLVE_LIB_DEFECTS 109 // 23. Num_get overflow result. 110 if (__sanity == __s || *__sanity != '\0') 111 { 112 __v = 0.0l; 113 __err = ios_base::failbit; 114 } 115 else if (__v == numeric_limits<long double>::infinity()) 116 { 117 __v = numeric_limits<long double>::max(); 118 __err = ios_base::failbit; 119 } 120 else if (__v == -numeric_limits<long double>::infinity()) 121 { 122 __v = -numeric_limits<long double>::max(); 123 __err = ios_base::failbit; 124 } 125 } 126 127 void 128 locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, 129 __c_locale __old) 130 { 131 __cloc = __newlocale(1 << LC_ALL, __s, __old); 132 if (!__cloc) 133 { 134 // This named locale is not supported by the underlying OS. 135 __throw_runtime_error(__N("locale::facet::_S_create_c_locale " 136 "name not valid")); 137 } 138 } 139 140 void 141 locale::facet::_S_destroy_c_locale(__c_locale& __cloc) 142 { 143 if (__cloc && _S_get_c_locale() != __cloc) 144 __freelocale(__cloc); 145 } 146 147 __c_locale 148 locale::facet::_S_clone_c_locale(__c_locale& __cloc) throw() 149 { return __duplocale(__cloc); } 150 151 __c_locale 152 locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s) 153 { 154 __c_locale __dup = __duplocale(__cloc); 155 if (__dup == __c_locale(0)) 156 __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale " 157 "duplocale error")); 158 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 159 __c_locale __changed = __newlocale(LC_CTYPE_MASK, __s, __dup); 160 #else 161 __c_locale __changed = __newlocale(1 << LC_CTYPE, __s, __dup); 162 #endif 163 if (__changed == __c_locale(0)) 164 { 165 __freelocale(__dup); 166 __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale " 167 "newlocale error")); 168 } 169 return __changed; 170 } 171 172 _GLIBCXX_END_NAMESPACE 173 174 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 175 176 const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] = 177 { 178 "LC_CTYPE", 179 "LC_NUMERIC", 180 "LC_TIME", 181 "LC_COLLATE", 182 "LC_MONETARY", 183 "LC_MESSAGES", 184 "LC_PAPER", 185 "LC_NAME", 186 "LC_ADDRESS", 187 "LC_TELEPHONE", 188 "LC_MEASUREMENT", 189 "LC_IDENTIFICATION" 190 }; 191 192 _GLIBCXX_END_NAMESPACE 193 194 _GLIBCXX_BEGIN_NAMESPACE(std) 195 196 const char* const* const locale::_S_categories = __gnu_cxx::category_names; 197 198 _GLIBCXX_END_NAMESPACE 199 200 // XXX GLIBCXX_ABI Deprecated 201 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT 202 #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ 203 extern "C" void ldbl (void) __attribute__ ((alias (#dbl))) 204 _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct); 205 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT 206