xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/config/locale/dragonfly/c_locale.cc (revision eceb233b9bd0dfebb902ed73b531ae6964fa3f9b)
1 // localization implementation details, DragonFly version -*- C++ -*-
2 
3 // Copyright (C) 2014-2018 Free Software Foundation, Inc.
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
8 // Free Software Foundation; either version 3, or (at your option)
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 
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/>.
24 
25 //
26 // ISO C++ 14882: 22.8  Standard locale categories.
27 //
28 
29 // Written by Benjamin Kosnik <bkoz@redhat.com>
30 // Modified for DragonFly by John Marino <gnugcc@marino.st>
31 
32 #include <cstdlib>
33 #include <locale>
34 #include <stdexcept>
35 #include <limits>
36 #include <langinfo.h>
37 #ifndef __NetBSD__
38 #include <xlocale.h>
39 #endif
40 
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 
45   template<>
46     void
47     __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
48 		   const __c_locale& __cloc) throw()
49     {
50       char* __sanity;
51       __v = strtof_l(__s, &__sanity, (locale_t)__cloc);
52 
53       // _GLIBCXX_RESOLVE_LIB_DEFECTS
54       // 23. Num_get overflow result.
55       if (__sanity == __s || *__sanity != '\0')
56 	{
57 	  __v = 0.0f;
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       else if (__v == -numeric_limits<float>::infinity())
66 	{
67 	  __v = -numeric_limits<float>::max();
68 	  __err = ios_base::failbit;
69 	}
70     }
71 
72   template<>
73     void
74     __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
75 		   const __c_locale& __cloc) throw()
76     {
77       char* __sanity;
78       __v = strtod_l(__s, &__sanity, (locale_t)__cloc);
79 
80       // _GLIBCXX_RESOLVE_LIB_DEFECTS
81       // 23. Num_get overflow result.
82       if (__sanity == __s || *__sanity != '\0')
83 	{
84 	  __v = 0.0;
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       else if (__v == -numeric_limits<double>::infinity())
93 	{
94 	  __v = -numeric_limits<double>::max();
95 	  __err = ios_base::failbit;
96 	}
97     }
98 
99   template<>
100     void
101     __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
102 		   const __c_locale& __cloc) throw()
103     {
104       char* __sanity;
105       __v = strtold_l(__s, &__sanity, (locale_t)__cloc);
106 
107       // _GLIBCXX_RESOLVE_LIB_DEFECTS
108       // 23. Num_get overflow result.
109       if (__sanity == __s || *__sanity != '\0')
110 	{
111 	  __v = 0.0l;
112 	  __err = ios_base::failbit;
113 	}
114       else if (__v == numeric_limits<long double>::infinity())
115 	{
116 	  __v = numeric_limits<long double>::max();
117 	  __err = ios_base::failbit;
118 	}
119       else if (__v == -numeric_limits<long double>::infinity())
120 	{
121 	  __v = -numeric_limits<long double>::max();
122 	  __err = ios_base::failbit;
123 	}
124     }
125 
126   void
127   locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s,
128 				    __c_locale __old)
129   {
130     __cloc = (__c_locale)newlocale(LC_ALL_MASK, __s, (locale_t)__old);
131     if (!__cloc)
132       {
133 	// This named locale is not supported by the underlying OS.
134 	__throw_runtime_error(__N("locale::facet::_S_create_c_locale "
135 				  "name not valid"));
136       }
137   }
138 
139   void
140   locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
141   {
142     if (__cloc && _S_get_c_locale() != __cloc)
143       freelocale((locale_t)__cloc);
144   }
145 
146   __c_locale
147   locale::facet::_S_clone_c_locale(__c_locale& __cloc) throw()
148   { return (__c_locale)duplocale((locale_t)__cloc); }
149 
150   __c_locale
151   locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s)
152   {
153     __c_locale __dup = (__c_locale)duplocale((locale_t)__cloc);
154     if (__dup == __c_locale(0))
155       __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
156 				"duplocale error"));
157     __c_locale __changed = (__c_locale)newlocale(LC_CTYPE_MASK, __s,
158 						 (locale_t)__dup);
159     if (__changed == __c_locale(0))
160       {
161 	freelocale((locale_t)__dup);
162 	__throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
163 				  "newlocale error"));
164       }
165     return __changed;
166   }
167 
168 _GLIBCXX_END_NAMESPACE_VERSION
169 } // namespace
170 
171 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
172 {
173 _GLIBCXX_BEGIN_NAMESPACE_VERSION
174 
175   const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
176     {
177       "LC_CTYPE",
178       "LC_NUMERIC",
179       "LC_TIME",
180       "LC_COLLATE",
181       "LC_MONETARY",
182       "LC_MESSAGES"
183     };
184 
185 _GLIBCXX_END_NAMESPACE_VERSION
186 } // namespace
187 
188 namespace std _GLIBCXX_VISIBILITY(default)
189 {
190 _GLIBCXX_BEGIN_NAMESPACE_VERSION
191 
192   const char* const* const locale::_S_categories = __gnu_cxx::category_names;
193 
194 _GLIBCXX_END_NAMESPACE_VERSION
195 } // namespace
196 
197 // XXX GLIBCXX_ABI Deprecated
198 #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
199 #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
200   extern "C" void ldbl (void) __attribute__ ((alias (#dbl)))
201 _GLIBCXX_LDBL_COMPAT(_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct, _ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct);
202 #endif // _GLIBCXX_LONG_DOUBLE_COMPAT
203