]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/config/locale/gnu/c_locale.cc
PR libstdc++/36104 part four
[thirdparty/gcc.git] / libstdc++-v3 / config / locale / gnu / c_locale.cc
CommitLineData
0214010c
BK
1// Wrapper for underlying C-language localization -*- C++ -*-
2
32ade559 3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
d04e9b7f 4// Free Software Foundation, Inc.
0214010c
BK
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
748086b7 9// Free Software Foundation; either version 3, or (at your option)
0214010c
BK
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
748086b7
JJ
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.
0214010c 20
748086b7
JJ
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/>.
0214010c
BK
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>
5ef46f95 34#include <limits>
0214010c 35#include <langinfo.h>
6aa43d99 36#include <bits/c++locale_internal.h>
0214010c 37
12ffa228
BK
38namespace std _GLIBCXX_VISIBILITY(default)
39{
40_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 41
4b9aaf63
BK
42 template<>
43 void
44 __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
32ade559 45 const __c_locale& __cloc) throw()
4b9aaf63 46 {
d04e9b7f 47 char* __sanity;
5ef46f95
PC
48 __v = __strtof_l(__s, &__sanity, __cloc);
49
50 // _GLIBCXX_RESOLVE_LIB_DEFECTS
51 // 23. Num_get overflow result.
52 if (__sanity == __s || *__sanity != '\0')
53 {
54 __v = 0.0f;
55 __err = ios_base::failbit;
56 }
57 else if (__v == numeric_limits<float>::infinity())
58 {
59 __v = numeric_limits<float>::max();
60 __err = ios_base::failbit;
61 }
62 else if (__v == -numeric_limits<float>::infinity())
63 {
64 __v = -numeric_limits<float>::max();
65 __err = ios_base::failbit;
66 }
4b9aaf63
BK
67 }
68
69 template<>
70 void
71 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
32ade559 72 const __c_locale& __cloc) throw()
4b9aaf63 73 {
d04e9b7f 74 char* __sanity;
5ef46f95
PC
75 __v = __strtod_l(__s, &__sanity, __cloc);
76
77 // _GLIBCXX_RESOLVE_LIB_DEFECTS
78 // 23. Num_get overflow result.
79 if (__sanity == __s || *__sanity != '\0')
80 {
81 __v = 0.0;
82 __err = ios_base::failbit;
83 }
84 else if (__v == numeric_limits<double>::infinity())
85 {
86 __v = numeric_limits<double>::max();
87 __err = ios_base::failbit;
88 }
89 else if (__v == -numeric_limits<double>::infinity())
90 {
91 __v = -numeric_limits<double>::max();
92 __err = ios_base::failbit;
93 }
4b9aaf63
BK
94 }
95
96 template<>
97 void
98 __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
32ade559 99 const __c_locale& __cloc) throw()
4b9aaf63 100 {
d04e9b7f 101 char* __sanity;
29520adf
JJ
102#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
103 // Prefer strtold_l, as __strtold_l isn't prototyped in more recent
104 // glibc versions.
5ef46f95 105 __v = strtold_l(__s, &__sanity, __cloc);
29520adf 106#else
5ef46f95 107 __v = __strtold_l(__s, &__sanity, __cloc);
29520adf 108#endif
5ef46f95
PC
109
110 // _GLIBCXX_RESOLVE_LIB_DEFECTS
111 // 23. Num_get overflow result.
112 if (__sanity == __s || *__sanity != '\0')
113 {
114 __v = 0.0l;
115 __err = ios_base::failbit;
116 }
117 else if (__v == numeric_limits<long double>::infinity())
118 {
119 __v = numeric_limits<long double>::max();
120 __err = ios_base::failbit;
121 }
122 else if (__v == -numeric_limits<long double>::infinity())
123 {
124 __v = -numeric_limits<long double>::max();
125 __err = ios_base::failbit;
126 }
4b9aaf63
BK
127 }
128
0214010c 129 void
d3a193e3
BK
130 locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
131 __c_locale __old)
0214010c 132 {
d3a193e3 133 __cloc = __newlocale(1 << LC_ALL, __s, __old);
0214010c
BK
134 if (!__cloc)
135 {
136 // This named locale is not supported by the underlying OS.
ba9119ec 137 __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
c8036448 138 "name not valid"));
0214010c
BK
139 }
140 }
c8036448 141
0214010c
BK
142 void
143 locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
aa53f832 144 {
cd6dba21 145 if (__cloc && _S_get_c_locale() != __cloc)
aa53f832
PC
146 __freelocale(__cloc);
147 }
0214010c 148
33590f13 149 __c_locale
32ade559 150 locale::facet::_S_clone_c_locale(__c_locale& __cloc) throw()
33590f13 151 { return __duplocale(__cloc); }
aa53f832 152
c8036448
PC
153 __c_locale
154 locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s)
155 {
156 __c_locale __dup = __duplocale(__cloc);
157 if (__dup == __c_locale(0))
158 __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
159 "duplocale error"));
0dca2153 160#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
c8036448 161 __c_locale __changed = __newlocale(LC_CTYPE_MASK, __s, __dup);
0dca2153
PC
162#else
163 __c_locale __changed = __newlocale(1 << LC_CTYPE, __s, __dup);
164#endif
c8036448
PC
165 if (__changed == __c_locale(0))
166 {
167 __freelocale(__dup);
168 __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
169 "newlocale error"));
170 }
171 return __changed;
172 }
173
12ffa228
BK
174_GLIBCXX_END_NAMESPACE_VERSION
175} // namespace
3cbc7af0 176
12ffa228
BK
177namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
178{
179_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 180
8ae81136 181 const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
aa53f832
PC
182 {
183 "LC_CTYPE",
0e9501e6 184 "LC_NUMERIC",
aa53f832 185 "LC_TIME",
0e9501e6 186 "LC_COLLATE",
aa53f832
PC
187 "LC_MONETARY",
188 "LC_MESSAGES",
189 "LC_PAPER",
190 "LC_NAME",
191 "LC_ADDRESS",
192 "LC_TELEPHONE",
193 "LC_MEASUREMENT",
194 "LC_IDENTIFICATION"
195 };
73c4dcc6 196
12ffa228
BK
197_GLIBCXX_END_NAMESPACE_VERSION
198} // namespace
3cbc7af0 199
12ffa228
BK
200namespace std _GLIBCXX_VISIBILITY(default)
201{
202_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 203
8ae81136 204 const char* const* const locale::_S_categories = __gnu_cxx::category_names;
3cbc7af0 205
12ffa228
BK
206_GLIBCXX_END_NAMESPACE_VERSION
207} // namespace
6defecc2
JJ
208
209// XXX GLIBCXX_ABI Deprecated
210#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
211#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
212 extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
213_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct);
214#endif // _GLIBCXX_LONG_DOUBLE_COMPAT