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