xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/config/locale/gnu/numeric_members.cc (revision 7788a0781fe6ff2cce37368b4578a7ade0850cb1)
1 // std::numpunct implementation details, GNU version -*- C++ -*-
2 
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 // Free Software Foundation, Inc.
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
9 // Free Software Foundation; either version 3, or (at your option)
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 
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.
20 
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/>.
25 
26 //
27 // ISO C++ 14882: 22.2.3.1.2  numpunct virtual functions
28 //
29 
30 // Written by Benjamin Kosnik <bkoz@redhat.com>
31 
32 #include <locale>
33 #include <bits/c++locale_internal.h>
34 
35 _GLIBCXX_BEGIN_NAMESPACE(std)
36 
37   template<>
38     void
39     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
40     {
41       if (!_M_data)
42 	_M_data = new __numpunct_cache<char>;
43 
44       if (!__cloc)
45 	{
46 	  // "C" locale
47 	  _M_data->_M_grouping = "";
48 	  _M_data->_M_grouping_size = 0;
49 	  _M_data->_M_use_grouping = false;
50 
51 	  _M_data->_M_decimal_point = '.';
52 	  _M_data->_M_thousands_sep = ',';
53 
54 	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
55 	    _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
56 
57 	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
58 	    _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
59 	}
60       else
61 	{
62 	  // Named locale.
63 	  _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT,
64 							__cloc));
65 	  _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP,
66 							__cloc));
67 
68 	  // Check for NULL, which implies no grouping.
69 	  if (_M_data->_M_thousands_sep == '\0')
70 	    {
71 	      // Like in "C" locale.
72 	      _M_data->_M_grouping = "";
73 	      _M_data->_M_grouping_size = 0;
74 	      _M_data->_M_use_grouping = false;
75 	      _M_data->_M_thousands_sep = ',';
76 	    }
77 	  else
78 	    {
79 	      const char* __src = __nl_langinfo_l(GROUPING, __cloc);
80 	      const size_t __len = strlen(__src);
81 	      if (__len)
82 		{
83 		  __try
84 		    {
85 		      char* __dst = new char[__len + 1];
86 		      memcpy(__dst, __src, __len + 1);
87 		      _M_data->_M_grouping = __dst;
88 		    }
89 		  __catch(...)
90 		    {
91 		      delete _M_data;
92 		      _M_data = 0;
93 		      __throw_exception_again;
94 		    }
95 		}
96 	      else
97 		{
98 		  _M_data->_M_grouping = "";
99 		  _M_data->_M_use_grouping = false;
100 		}
101 	      _M_data->_M_grouping_size = __len;
102 	    }
103 	}
104 
105       // NB: There is no way to extact this info from posix locales.
106       // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
107       _M_data->_M_truename = "true";
108       _M_data->_M_truename_size = 4;
109       // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
110       _M_data->_M_falsename = "false";
111       _M_data->_M_falsename_size = 5;
112     }
113 
114   template<>
115     numpunct<char>::~numpunct()
116     {
117       if (_M_data->_M_grouping_size)
118 	delete [] _M_data->_M_grouping;
119       delete _M_data;
120     }
121 
122 #ifdef _GLIBCXX_USE_WCHAR_T
123   template<>
124     void
125     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc)
126     {
127       if (!_M_data)
128 	_M_data = new __numpunct_cache<wchar_t>;
129 
130       if (!__cloc)
131 	{
132 	  // "C" locale
133 	  _M_data->_M_grouping = "";
134 	  _M_data->_M_grouping_size = 0;
135 	  _M_data->_M_use_grouping = false;
136 
137 	  _M_data->_M_decimal_point = L'.';
138 	  _M_data->_M_thousands_sep = L',';
139 
140 	  // Use ctype::widen code without the facet...
141 	  for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
142 	    _M_data->_M_atoms_out[__i] =
143 	      static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
144 
145 	  for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
146 	    _M_data->_M_atoms_in[__j] =
147 	      static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
148 	}
149       else
150 	{
151 	  // Named locale.
152 	  // NB: In the GNU model wchar_t is always 32 bit wide.
153 	  union { char *__s; wchar_t __w; } __u;
154 	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc);
155 	  _M_data->_M_decimal_point = __u.__w;
156 
157 	  __u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
158 	  _M_data->_M_thousands_sep = __u.__w;
159 
160 	  // Check for NULL, which implies no grouping.
161 	  if (_M_data->_M_thousands_sep == L'\0')
162 	    {
163 	      // Like in "C" locale.
164 	      _M_data->_M_grouping = "";
165 	      _M_data->_M_grouping_size = 0;
166 	      _M_data->_M_use_grouping = false;
167 	      _M_data->_M_thousands_sep = L',';
168 	    }
169 	  else
170 	    {
171 	      const char* __src = __nl_langinfo_l(GROUPING, __cloc);
172 	      const size_t __len = strlen(__src);
173 	      if (__len)
174 		{
175 		  __try
176 		    {
177 		      char* __dst = new char[__len + 1];
178 		      memcpy(__dst, __src, __len + 1);
179 		      _M_data->_M_grouping = __dst;
180 		    }
181 		  __catch(...)
182 		    {
183 		      delete _M_data;
184 		      _M_data = 0;
185 		      __throw_exception_again;
186 		    }
187 		}
188 	      else
189 		{
190 		  _M_data->_M_grouping = "";
191 		  _M_data->_M_use_grouping = false;
192 		}
193 	      _M_data->_M_grouping_size = __len;
194 	    }
195 	}
196 
197       // NB: There is no way to extact this info from posix locales.
198       // _M_truename = __nl_langinfo_l(YESSTR, __cloc);
199       _M_data->_M_truename = L"true";
200       _M_data->_M_truename_size = 4;
201       // _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
202       _M_data->_M_falsename = L"false";
203       _M_data->_M_falsename_size = 5;
204     }
205 
206   template<>
207     numpunct<wchar_t>::~numpunct()
208     {
209       if (_M_data->_M_grouping_size)
210 	delete [] _M_data->_M_grouping;
211       delete _M_data;
212     }
213  #endif
214 
215 _GLIBCXX_END_NAMESPACE
216