]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/config/locale/generic/c_locale.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / config / locale / generic / c_locale.cc
CommitLineData
0214010c
BK
1// Wrapper for underlying C-language localization -*- C++ -*-
2
8d9254fc 3// Copyright (C) 2001-2020 Free Software Foundation, Inc.
0214010c
BK
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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
0214010c
BK
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
748086b7
JJ
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/>.
0214010c
BK
24
25//
26// ISO C++ 14882: 22.8 Standard locale categories.
27//
28
29// Written by Benjamin Kosnik <bkoz@redhat.com>
30
19df3b83 31#include <cerrno> // For errno
4f363232
PC
32#include <cmath> // For isinf, finite, finitef, fabs
33#include <cstdlib> // For strof, strtold
538075fe 34#include <cstring>
4d5670aa 35#include <cstdio>
0214010c 36#include <locale>
587024cf 37#include <limits>
0214010c 38
3d7c150e 39#ifdef _GLIBCXX_HAVE_IEEEFP_H
99a4deb8
LR
40#include <ieeefp.h>
41#endif
42
12ffa228
BK
43namespace std _GLIBCXX_VISIBILITY(default)
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 46
f14decaf
JW
47 namespace
48 {
49 struct _Save_errno
50 {
51 _Save_errno() : _M_errno(errno) { errno = 0; }
52 ~_Save_errno() { if (errno == 0) errno = _M_errno; }
53 int _M_errno;
54 };
55 }
56
4b9aaf63
BK
57 template<>
58 void
32ade559
BK
59 __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
60 const __c_locale&) throw()
4b9aaf63 61 {
d04e9b7f 62 // Assumes __s formatted for "C" locale.
445877a9 63 char* __old = setlocale(LC_ALL, 0);
538075fe
PC
64 const size_t __len = strlen(__old) + 1;
65 char* __sav = new char[__len];
66 memcpy(__sav, __old, __len);
d04e9b7f
PC
67 setlocale(LC_ALL, "C");
68 char* __sanity;
5ef46f95 69 bool __overflow = false;
19df3b83
PC
70
71#if !__FLT_HAS_INFINITY__
f14decaf 72 const _Save_errno __save_errno;
19df3b83
PC
73#endif
74
5ef46f95
PC
75#ifdef _GLIBCXX_HAVE_STRTOF
76 __v = strtof(__s, &__sanity);
4b9aaf63 77#else
d04e9b7f 78 double __d = strtod(__s, &__sanity);
5ef46f95 79 __v = static_cast<float>(__d);
3d7c150e 80#ifdef _GLIBCXX_HAVE_FINITEF
5ef46f95
PC
81 if (!finitef (__v))
82 __overflow = true;
3d7c150e 83#elif defined (_GLIBCXX_HAVE_FINITE)
5ef46f95
PC
84 if (!finite (static_cast<double> (__v)))
85 __overflow = true;
3d7c150e 86#elif defined (_GLIBCXX_HAVE_ISINF)
5ef46f95
PC
87 if (isinf (static_cast<double> (__v)))
88 __overflow = true;
99a4deb8 89#else
d04e9b7f 90 if (fabs(__d) > numeric_limits<float>::max())
5ef46f95 91 __overflow = true;
99a4deb8 92#endif
5ef46f95
PC
93#endif // _GLIBCXX_HAVE_STRTOF
94
95 // _GLIBCXX_RESOLVE_LIB_DEFECTS
96 // 23. Num_get overflow result.
97 if (__sanity == __s || *__sanity != '\0')
98 {
99 __v = 0.0f;
100 __err = ios_base::failbit;
101 }
102 else if (__overflow
103#if __FLT_HAS_INFINITY__
104 || __v == numeric_limits<float>::infinity()
ffecec4d 105 || __v == -numeric_limits<float>::infinity()
19df3b83 106#else
5ef46f95 107 || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
19df3b83 108#endif
ffecec4d 109 )
5ef46f95
PC
110 {
111 if (__v > 0.0f)
112 __v = numeric_limits<float>::max();
113 else
114 __v = -numeric_limits<float>::max();
115 __err = ios_base::failbit;
116 }
19df3b83 117
538075fe
PC
118 setlocale(LC_ALL, __sav);
119 delete [] __sav;
4b9aaf63
BK
120 }
121
122 template<>
123 void
32ade559
BK
124 __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
125 const __c_locale&) throw()
4b9aaf63 126 {
d04e9b7f 127 // Assumes __s formatted for "C" locale.
445877a9 128 char* __old = setlocale(LC_ALL, 0);
538075fe
PC
129 const size_t __len = strlen(__old) + 1;
130 char* __sav = new char[__len];
131 memcpy(__sav, __old, __len);
d04e9b7f
PC
132 setlocale(LC_ALL, "C");
133 char* __sanity;
19df3b83
PC
134
135#if !__DBL_HAS_INFINITY__
f14decaf 136 const _Save_errno __save_errno;
19df3b83
PC
137#endif
138
5ef46f95
PC
139 __v = strtod(__s, &__sanity);
140
141 // _GLIBCXX_RESOLVE_LIB_DEFECTS
142 // 23. Num_get overflow result.
143 if (__sanity == __s || *__sanity != '\0')
144 {
145 __v = 0.0;
146 __err = ios_base::failbit;
147 }
148 else if (
149#if __DBL_HAS_INFINITY__
150 __v == numeric_limits<double>::infinity()
151 || __v == -numeric_limits<double>::infinity())
32ade559 152#else
5ef46f95 153 (__v > 1.0 || __v < -1.0) && errno == ERANGE)
19df3b83 154#endif
5ef46f95
PC
155 {
156 if (__v > 0.0)
157 __v = numeric_limits<double>::max();
158 else
159 __v = -numeric_limits<double>::max();
160 __err = ios_base::failbit;
161 }
19df3b83 162
538075fe
PC
163 setlocale(LC_ALL, __sav);
164 delete [] __sav;
4b9aaf63
BK
165 }
166
167 template<>
168 void
32ade559
BK
169 __convert_to_v(const char* __s, long double& __v,
170 ios_base::iostate& __err, const __c_locale&) throw()
4b9aaf63 171 {
d04e9b7f 172 // Assumes __s formatted for "C" locale.
445877a9 173 char* __old = setlocale(LC_ALL, 0);
538075fe
PC
174 const size_t __len = strlen(__old) + 1;
175 char* __sav = new char[__len];
176 memcpy(__sav, __old, __len);
d04e9b7f 177 setlocale(LC_ALL, "C");
19df3b83
PC
178
179#if !__LDBL_HAS_INFINITY__
f14decaf 180 const _Save_errno __save_errno;
19df3b83
PC
181#endif
182
18efbe51 183#if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
d04e9b7f 184 char* __sanity;
5ef46f95 185 __v = strtold(__s, &__sanity);
19df3b83 186
5ef46f95
PC
187 // _GLIBCXX_RESOLVE_LIB_DEFECTS
188 // 23. Num_get overflow result.
189 if (__sanity == __s || *__sanity != '\0')
4b9aaf63 190#else
d04e9b7f 191 typedef char_traits<char>::int_type int_type;
5ef46f95 192 int __p = sscanf(__s, "%Lf", &__v);
19df3b83 193
5ef46f95 194 if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
19df3b83 195#endif
5ef46f95
PC
196 {
197 __v = 0.0l;
198 __err = ios_base::failbit;
199 }
200 else if (
201#if __LDBL_HAS_INFINITY__
32ade559
BK
202 __v == numeric_limits<long double>::infinity()
203 || __v == -numeric_limits<long double>::infinity())
5ef46f95 204#else
32ade559 205 (__v > 1.0l || __v < -1.0l) && errno == ERANGE)
4b9aaf63 206#endif
5ef46f95
PC
207 {
208 if (__v > 0.0l)
209 __v = numeric_limits<long double>::max();
210 else
211 __v = -numeric_limits<long double>::max();
212 __err = ios_base::failbit;
213 }
19df3b83 214
538075fe
PC
215 setlocale(LC_ALL, __sav);
216 delete [] __sav;
4b9aaf63
BK
217 }
218
0214010c 219 void
32ade559 220 locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
d3a193e3 221 __c_locale)
85c39c6d 222 {
988ad90d
BK
223 // Currently, the generic model only supports the "C" locale.
224 // See http://gcc.gnu.org/ml/libstdc++/2003-02/msg00345.html
445877a9 225 __cloc = 0;
3d838e28 226 if (strcmp(__s, "C"))
ba9119ec
PC
227 __throw_runtime_error(__N("locale::facet::_S_create_c_locale "
228 "name not valid"));
85c39c6d 229 }
0214010c
BK
230
231 void
d3a193e3 232 locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
445877a9 233 { __cloc = 0; }
0214010c 234
33590f13 235 __c_locale
32ade559 236 locale::facet::_S_clone_c_locale(__c_locale&) throw()
33590f13 237 { return __c_locale(); }
aa53f832 238
c8036448
PC
239 __c_locale
240 locale::facet::_S_lc_ctype_c_locale(__c_locale, const char*)
241 { return __c_locale(); }
242
12ffa228
BK
243_GLIBCXX_END_NAMESPACE_VERSION
244} // namespace
3cbc7af0 245
12ffa228
BK
246namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
247{
248_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 249
8ae81136 250 const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
aa53f832 251 {
32ade559 252 "LC_CTYPE",
0e9501e6 253 "LC_NUMERIC",
32ade559
BK
254 "LC_TIME",
255 "LC_COLLATE",
aa53f832
PC
256 "LC_MONETARY",
257 "LC_MESSAGES"
258 };
73c4dcc6 259
12ffa228
BK
260_GLIBCXX_END_NAMESPACE_VERSION
261} // namespace
3cbc7af0 262
12ffa228
BK
263namespace std _GLIBCXX_VISIBILITY(default)
264{
265_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 266
8ae81136 267 const char* const* const locale::_S_categories = __gnu_cxx::category_names;
3cbc7af0 268
12ffa228
BK
269_GLIBCXX_END_NAMESPACE_VERSION
270} // namespace
6defecc2
JJ
271
272// XXX GLIBCXX_ABI Deprecated
273#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
274#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
275 extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
276_GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKPi, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKPi);
277#endif // _GLIBCXX_LONG_DOUBLE_COMPAT