xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/config/locale/dragonfly/numeric_members.cc (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 // std::numpunct implementation details, DragonFly version -*- C++ -*-
2 
3 // Copyright (C) 2015-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.2.3.1.2  numpunct virtual functions
27 //
28 
29 // Written by Benjamin Kosnik <bkoz@redhat.com>
30 // Modified for DragonFly by John Marino <gnugcc@marino.st>
31 
32 #include <locale>
33 #include <cstring>
34 
35 #include "xlocale_port.h"
36 
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
40 
41   template<>
42     void
43     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
44     {
45       if (!_M_data)
46 	_M_data = new __numpunct_cache<char>;
47 
48       if (!__cloc)
49 	{
50 	  // "C" locale
51 	  _M_data->_M_grouping = "";
52 	  _M_data->_M_grouping_size = 0;
53 	  _M_data->_M_use_grouping = false;
54 
55 	  _M_data->_M_decimal_point = '.';
56 	  _M_data->_M_thousands_sep = ',';
57 
58 	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
59 	    _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
60 
61 	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
62 	    _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
63 	}
64       else
65 	{
66 	  // Named locale.
67 	  lconv* lc = localeconv_l((locale_t) __cloc);
68 
69 	  // Decimal point should always be defined, but check null anyway
70 	  if (lc->decimal_point == NULL)
71 	    {
72 	      // Not defined, so use "C" locale default
73 	      _M_data->_M_decimal_point = '.';
74 	    }
75 	  else
76 	    {
77 	      _M_data->_M_decimal_point = lc->decimal_point[0];
78 	    }
79 	  // Check for NULL, which implies no grouping.
80 	  if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0')
81 	    {
82 	      // Like in "C" locale.
83 	      _M_data->_M_grouping = "";
84 	      _M_data->_M_grouping_size = 0;
85 	      _M_data->_M_use_grouping = false;
86 	      _M_data->_M_thousands_sep = ',';
87 	    }
88 	  else
89 	    {
90 	      _M_data->_M_thousands_sep = lc->thousands_sep[0];
91 
92 	      const char* __src = lc->grouping;
93 	      const size_t __len = strlen(__src);
94 	      if (__len)
95 		{
96 		  __try
97 		    {
98 		      char* __dst = new char[__len + 1];
99 		      memcpy(__dst, __src, __len + 1);
100 		      _M_data->_M_grouping = __dst;
101 		      _M_data->_M_use_grouping = true;
102 		    }
103 		  __catch(...)
104 		    {
105 		      delete _M_data;
106 		      _M_data = 0;
107 		      __throw_exception_again;
108 		    }
109 		}
110 	      else
111 		{
112 		  _M_data->_M_grouping = "";
113 		  _M_data->_M_use_grouping = false;
114 		}
115 	      _M_data->_M_grouping_size = __len;
116 	    }
117 	}
118 
119       // NB: There is no way to extact this info from posix locales.
120       // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
121       _M_data->_M_truename = "true";
122       _M_data->_M_truename_size = 4;
123       // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
124       _M_data->_M_falsename = "false";
125       _M_data->_M_falsename_size = 5;
126     }
127 
128   template<>
129     numpunct<char>::~numpunct()
130     {
131       if (_M_data->_M_grouping_size)
132 	delete [] _M_data->_M_grouping;
133       delete _M_data;
134     }
135 
136 #ifdef _GLIBCXX_USE_WCHAR_T
137   template<>
138     void
139     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
140     {
141       if (!_M_data)
142 	_M_data = new __numpunct_cache<wchar_t>;
143 
144       if (!__cloc)
145 	{
146 	  // "C" locale
147 	  _M_data->_M_grouping = "";
148 	  _M_data->_M_grouping_size = 0;
149 	  _M_data->_M_use_grouping = false;
150 
151 	  _M_data->_M_decimal_point = L'.';
152 	  _M_data->_M_thousands_sep = L',';
153 
154 	  // Use ctype::widen code without the facet...
155 	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
156 	    _M_data->_M_atoms_out[__i] =
157 	      static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
158 
159 	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
160 	    _M_data->_M_atoms_in[__j] =
161 	      static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
162 	}
163       else
164 	{
165 	  // Named locale.
166 	  lconv* lc = localeconv_l((locale_t) __cloc);
167 
168 	  // Decimal point should always be defined, but check null anyway
169 	  if (lc->decimal_point == NULL)
170 	    {
171 	      // Not defined, so use "C" locale default
172 	      _M_data->_M_decimal_point = L'.';
173 	    }
174 	  else
175 	    {
176 	      _M_data->_M_decimal_point = (wchar_t)lc->decimal_point[0];
177 	    }
178 	  // Check for NULL, which implies no grouping.
179 	  if (lc->thousands_sep == NULL || lc->thousands_sep[0] == '\0')
180 	    {
181 	      // Like in "C" locale.
182 	      _M_data->_M_grouping = "";
183 	      _M_data->_M_grouping_size = 0;
184 	      _M_data->_M_use_grouping = false;
185 	      _M_data->_M_thousands_sep = L',';
186 	    }
187 	  else
188 	    {
189 	      _M_data->_M_thousands_sep = (wchar_t)lc->thousands_sep[0];
190 
191   	      const char* __src = lc->grouping;
192 	      const size_t __len = strlen(__src);
193 	      if (__len)
194 		{
195 		  __try
196 		    {
197 		      char* __dst = new char[__len + 1];
198 		      memcpy(__dst, __src, __len + 1);
199 		      _M_data->_M_grouping = __dst;
200 		    }
201 		  __catch(...)
202 		    {
203 		      delete _M_data;
204 		      _M_data = 0;
205 		      __throw_exception_again;
206 		    }
207 		}
208 	      else
209 		{
210 		  _M_data->_M_grouping = "";
211 		  _M_data->_M_use_grouping = false;
212 		}
213 	      _M_data->_M_grouping_size = __len;
214 	    }
215 	}
216 
217       // NB: There is no way to extact this info from posix locales.
218       // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
219       _M_data->_M_truename = L"true";
220       _M_data->_M_truename_size = 4;
221       // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
222       _M_data->_M_falsename = L"false";
223       _M_data->_M_falsename_size = 5;
224     }
225 
226   template<>
227     numpunct<wchar_t>::~numpunct()
228     {
229       if (_M_data->_M_grouping_size)
230 	delete [] _M_data->_M_grouping;
231       delete _M_data;
232     }
233  #endif
234 
235 _GLIBCXX_END_NAMESPACE_VERSION
236 } // namespace
237