]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/config/locale/gnu/monetary_members.cc
acconfig.h: Remove _GLIBCXX_USE_LONG_DOUBLE entry, not used anymore.
[thirdparty/gcc.git] / libstdc++-v3 / config / locale / gnu / monetary_members.cc
CommitLineData
72e2386f
BK
1// std::moneypunct implementation details, GNU version -*- C++ -*-
2
f942e78d 3// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
72e2386f
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
8// Free Software Foundation; either version 2, 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// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING. If not, write to the Free
18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction. Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License. This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30//
31// ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions
32//
33
34// Written by Benjamin Kosnik <bkoz@redhat.com>
35
36#include <locale>
6aa43d99 37#include <bits/c++locale_internal.h>
72e2386f
BK
38
39namespace std
40{
69971cd8
BK
41 // Construct and return valid pattern consisting of some combination of:
42 // space none symbol sign value
43 money_base::pattern
754d9299 44 money_base::_S_construct_pattern(char __precedes, char __space, char __posn)
69971cd8
BK
45 {
46 pattern __ret;
47
48 // This insanely complicated routine attempts to construct a valid
49 // pattern for use with monyepunct. A couple of invariants:
50
754d9299 51 // if (__precedes) symbol -> value
69971cd8
BK
52 // else value -> symbol
53
54 // if (__space) space
55 // else none
56
57 // none == never first
58 // space never first or last
59
60 // Any elegant implementations of this are welcome.
61 switch (__posn)
62 {
63 case 0:
64 case 1:
65 // 1 The sign precedes the value and symbol.
cc0c2f79 66 __ret.field[0] = sign;
69971cd8
BK
67 if (__space)
68 {
69 // Pattern starts with sign.
754d9299 70 if (__precedes)
69971cd8
BK
71 {
72 __ret.field[1] = symbol;
69971cd8
BK
73 __ret.field[3] = value;
74 }
75 else
76 {
77 __ret.field[1] = value;
69971cd8
BK
78 __ret.field[3] = symbol;
79 }
f7ba331c 80 __ret.field[2] = space;
69971cd8
BK
81 }
82 else
83 {
84 // Pattern starts with sign and ends with none.
754d9299 85 if (__precedes)
69971cd8
BK
86 {
87 __ret.field[1] = symbol;
88 __ret.field[2] = value;
89 }
90 else
91 {
92 __ret.field[1] = value;
93 __ret.field[2] = symbol;
94 }
69971cd8
BK
95 __ret.field[3] = none;
96 }
97 break;
98 case 2:
99 // 2 The sign follows the value and symbol.
100 if (__space)
101 {
102 // Pattern either ends with sign.
754d9299 103 if (__precedes)
69971cd8
BK
104 {
105 __ret.field[0] = symbol;
69971cd8
BK
106 __ret.field[2] = value;
107 }
108 else
109 {
110 __ret.field[0] = value;
69971cd8
BK
111 __ret.field[2] = symbol;
112 }
cc0c2f79 113 __ret.field[1] = space;
69971cd8
BK
114 __ret.field[3] = sign;
115 }
116 else
117 {
118 // Pattern ends with sign then none.
754d9299 119 if (__precedes)
69971cd8
BK
120 {
121 __ret.field[0] = symbol;
122 __ret.field[1] = value;
123 }
124 else
125 {
126 __ret.field[0] = value;
127 __ret.field[1] = symbol;
128 }
129 __ret.field[2] = sign;
130 __ret.field[3] = none;
131 }
132 break;
133 case 3:
134 // 3 The sign immediately precedes the symbol.
142b798b 135 if (__precedes)
69971cd8 136 {
142b798b
PC
137 __ret.field[0] = sign;
138 __ret.field[1] = symbol;
139 if (__space)
69971cd8 140 {
69971cd8
BK
141 __ret.field[2] = space;
142 __ret.field[3] = value;
143 }
144 else
145 {
142b798b
PC
146 __ret.field[2] = value;
147 __ret.field[3] = none;
69971cd8
BK
148 }
149 }
150 else
151 {
142b798b
PC
152 __ret.field[0] = value;
153 if (__space)
69971cd8 154 {
142b798b
PC
155 __ret.field[1] = space;
156 __ret.field[2] = sign;
157 __ret.field[3] = symbol;
69971cd8
BK
158 }
159 else
160 {
69971cd8
BK
161 __ret.field[1] = sign;
162 __ret.field[2] = symbol;
142b798b 163 __ret.field[3] = none;
69971cd8 164 }
69971cd8
BK
165 }
166 break;
167 case 4:
142b798b
PC
168 // 4 The sign immediately follows the symbol.
169 if (__precedes)
69971cd8 170 {
142b798b
PC
171 __ret.field[0] = symbol;
172 __ret.field[1] = sign;
173 if (__space)
69971cd8 174 {
69971cd8
BK
175 __ret.field[2] = space;
176 __ret.field[3] = value;
177 }
178 else
179 {
142b798b
PC
180 __ret.field[2] = value;
181 __ret.field[3] = none;
69971cd8
BK
182 }
183 }
184 else
185 {
142b798b
PC
186 __ret.field[0] = value;
187 if (__space)
69971cd8 188 {
142b798b
PC
189 __ret.field[1] = space;
190 __ret.field[2] = symbol;
191 __ret.field[3] = sign;
69971cd8
BK
192 }
193 else
194 {
69971cd8
BK
195 __ret.field[1] = symbol;
196 __ret.field[2] = sign;
142b798b 197 __ret.field[3] = none;
69971cd8 198 }
69971cd8
BK
199 }
200 break;
201 default:
202 ;
203 }
204 return __ret;
205 }
206
72e2386f
BK
207 template<>
208 void
fdf7e809
BK
209 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
210 const char*)
72e2386f 211 {
fea4065d 212 if (!_M_data)
fe932e50 213 _M_data = new __moneypunct_cache<char, true>;
fea4065d 214
aa53f832 215 if (!__cloc)
72e2386f
BK
216 {
217 // "C" locale
fea4065d
BK
218 _M_data->_M_decimal_point = '.';
219 _M_data->_M_thousands_sep = ',';
220 _M_data->_M_grouping = "";
fe932e50 221 _M_data->_M_grouping_size = 0;
fea4065d 222 _M_data->_M_curr_symbol = "";
fe932e50 223 _M_data->_M_curr_symbol_size = 0;
fea4065d 224 _M_data->_M_positive_sign = "";
fe932e50 225 _M_data->_M_positive_sign_size = 0;
fea4065d 226 _M_data->_M_negative_sign = "";
fe932e50 227 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
228 _M_data->_M_frac_digits = 0;
229 _M_data->_M_pos_format = money_base::_S_default_pattern;
230 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
231
232 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
233 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
72e2386f
BK
234 }
235 else
236 {
237 // Named locale.
fea4065d
BK
238 _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT,
239 __cloc));
240 _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
241 __cloc));
242 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
fe932e50 243 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
fea4065d 244 _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
fe932e50 245 _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
d3a193e3
BK
246
247 char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
248 if (!__nposn)
fea4065d 249 _M_data->_M_negative_sign = "()";
d3a193e3 250 else
fea4065d
BK
251 _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN,
252 __cloc);
fe932e50 253 _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign);
69971cd8
BK
254
255 // _Intl == true
fea4065d 256 _M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
fe932e50 257 _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
fea4065d
BK
258 _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
259 __cloc));
754d9299 260 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
69971cd8
BK
261 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
262 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
fea4065d
BK
263 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
264 __pposn);
754d9299 265 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
69971cd8 266 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
fea4065d
BK
267 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
268 __nposn);
69971cd8
BK
269 }
270 }
271
272 template<>
273 void
fdf7e809
BK
274 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
275 const char*)
69971cd8 276 {
fea4065d 277 if (!_M_data)
fe932e50 278 _M_data = new __moneypunct_cache<char, false>;
fea4065d 279
aa53f832 280 if (!__cloc)
69971cd8
BK
281 {
282 // "C" locale
fea4065d
BK
283 _M_data->_M_decimal_point = '.';
284 _M_data->_M_thousands_sep = ',';
285 _M_data->_M_grouping = "";
fe932e50 286 _M_data->_M_grouping_size = 0;
fea4065d 287 _M_data->_M_curr_symbol = "";
fe932e50 288 _M_data->_M_curr_symbol_size = 0;
fea4065d 289 _M_data->_M_positive_sign = "";
fe932e50 290 _M_data->_M_positive_sign_size = 0;
fea4065d 291 _M_data->_M_negative_sign = "";
fe932e50 292 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
293 _M_data->_M_frac_digits = 0;
294 _M_data->_M_pos_format = money_base::_S_default_pattern;
295 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
296
297 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
298 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
69971cd8
BK
299 }
300 else
301 {
302 // Named locale.
fea4065d
BK
303 _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT,
304 __cloc));
305 _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
306 __cloc));
307 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
fe932e50 308 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
fea4065d 309 _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
fe932e50 310 _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
d3a193e3
BK
311
312 char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
313 if (!__nposn)
fea4065d 314 _M_data->_M_negative_sign = "()";
d3a193e3 315 else
fe932e50 316 _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN,
fea4065d 317 __cloc);
fe932e50 318 _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign);
69971cd8
BK
319
320 // _Intl == false
fea4065d 321 _M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
fe932e50 322 _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
fea4065d 323 _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
754d9299 324 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
69971cd8
BK
325 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
326 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
fea4065d
BK
327 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
328 __pposn);
754d9299 329 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
69971cd8 330 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
fea4065d
BK
331 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
332 __nposn);
72e2386f
BK
333 }
334 }
335
d3a193e3
BK
336 template<>
337 moneypunct<char, true>::~moneypunct()
fea4065d 338 { delete _M_data; }
d3a193e3
BK
339
340 template<>
341 moneypunct<char, false>::~moneypunct()
fea4065d 342 { delete _M_data; }
d3a193e3 343
3d7c150e 344#ifdef _GLIBCXX_USE_WCHAR_T
72e2386f
BK
345 template<>
346 void
fdf7e809 347 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
bce58224
PC
348#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
349 const char*)
350#else
fdf7e809 351 const char* __name)
bce58224 352#endif
72e2386f 353 {
fea4065d 354 if (!_M_data)
fe932e50 355 _M_data = new __moneypunct_cache<wchar_t, true>;
fea4065d 356
aa53f832 357 if (!__cloc)
72e2386f
BK
358 {
359 // "C" locale
fea4065d
BK
360 _M_data->_M_decimal_point = L'.';
361 _M_data->_M_thousands_sep = L',';
362 _M_data->_M_grouping = "";
fe932e50 363 _M_data->_M_grouping_size = 0;
fea4065d 364 _M_data->_M_curr_symbol = L"";
fe932e50 365 _M_data->_M_curr_symbol_size = 0;
fea4065d 366 _M_data->_M_positive_sign = L"";
fe932e50 367 _M_data->_M_positive_sign_size = 0;
fea4065d 368 _M_data->_M_negative_sign = L"";
fe932e50 369 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
370 _M_data->_M_frac_digits = 0;
371 _M_data->_M_pos_format = money_base::_S_default_pattern;
372 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
373
374 // Use ctype::widen code without the facet...
fe932e50 375 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
af55af57
PC
376 _M_data->_M_atoms[__i] =
377 static_cast<wchar_t>(money_base::_S_atoms[__i]);
72e2386f
BK
378 }
379 else
380 {
381 // Named locale.
9a6d2071
JJ
382#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
383 __c_locale __old = __uselocale(__cloc);
384#else
385 // Switch to named locale so that mbsrtowcs will work.
fdf7e809
BK
386 char* __old = strdup(setlocale(LC_ALL, NULL));
387 setlocale(LC_ALL, __name);
9a6d2071 388#endif
fdf7e809 389
43be7fe7 390 union __s_and_w { const char *__s; unsigned int __w; } __u;
f332a090 391 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
fea4065d 392 _M_data->_M_decimal_point = static_cast<wchar_t>(__u.__w);
86176835 393
f332a090 394 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
fea4065d 395 _M_data->_M_thousands_sep = static_cast<wchar_t>(__u.__w);
f332a090 396 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
fe932e50 397 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
55dea7b1 398
d3a193e3
BK
399 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
400 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
401 const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
55dea7b1 402
f991b1d8
PC
403 wchar_t* __wcs_ps = 0;
404 wchar_t* __wcs_ns = 0;
405 const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
406 try
55dea7b1 407 {
f991b1d8
PC
408 mbstate_t __state;
409 size_t __len = strlen(__cpossign);
410 if (__len)
411 {
412 ++__len;
413 memset(&__state, 0, sizeof(mbstate_t));
414 __wcs_ps = new wchar_t[__len];
415 mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
416 _M_data->_M_positive_sign = __wcs_ps;
417 }
418 else
419 _M_data->_M_positive_sign = L"";
fe932e50 420 _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
f991b1d8
PC
421
422 __len = strlen(__cnegsign);
423 if (!__nposn)
424 _M_data->_M_negative_sign = L"()";
425 else if (__len)
426 {
427 ++__len;
428 memset(&__state, 0, sizeof(mbstate_t));
429 __wcs_ns = new wchar_t[__len];
430 mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
431 _M_data->_M_negative_sign = __wcs_ns;
432 }
433 else
434 _M_data->_M_negative_sign = L"";
fe932e50 435 _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
f991b1d8
PC
436
437 // _Intl == true.
438 __len = strlen(__ccurr);
439 if (__len)
440 {
441 ++__len;
442 memset(&__state, 0, sizeof(mbstate_t));
443 wchar_t* __wcs = new wchar_t[__len];
444 mbsrtowcs(__wcs, &__ccurr, __len, &__state);
445 _M_data->_M_curr_symbol = __wcs;
446 }
447 else
448 _M_data->_M_curr_symbol = L"";
fe932e50 449 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
55dea7b1 450 }
f991b1d8 451 catch (...)
55dea7b1 452 {
f991b1d8
PC
453 delete _M_data;
454 _M_data = 0;
455 delete __wcs_ps;
456 delete __wcs_ns;
f942e78d
AS
457#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
458 __uselocale(__old);
459#else
460 setlocale(LC_ALL, __old);
461 free(__old);
462#endif
f991b1d8
PC
463 __throw_exception_again;
464 }
465
fea4065d
BK
466 _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
467 __cloc));
754d9299 468 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
69971cd8
BK
469 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
470 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
fea4065d
BK
471 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
472 __pposn);
754d9299 473 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
69971cd8 474 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
fea4065d
BK
475 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
476 __nposn);
fdf7e809 477
9a6d2071
JJ
478#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
479 __uselocale(__old);
480#else
fdf7e809
BK
481 setlocale(LC_ALL, __old);
482 free(__old);
9a6d2071 483#endif
69971cd8
BK
484 }
485 }
486
487 template<>
f991b1d8
PC
488 void
489 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
490#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
491 const char*)
bce58224 492#else
f991b1d8 493 const char* __name)
bce58224 494#endif
f991b1d8
PC
495 {
496 if (!_M_data)
fe932e50 497 _M_data = new __moneypunct_cache<wchar_t, false>;
fea4065d 498
f991b1d8 499 if (!__cloc)
69971cd8
BK
500 {
501 // "C" locale
fea4065d
BK
502 _M_data->_M_decimal_point = L'.';
503 _M_data->_M_thousands_sep = L',';
504 _M_data->_M_grouping = "";
fe932e50 505 _M_data->_M_grouping_size = 0;
fea4065d 506 _M_data->_M_curr_symbol = L"";
fe932e50 507 _M_data->_M_curr_symbol_size = 0;
fea4065d 508 _M_data->_M_positive_sign = L"";
fe932e50 509 _M_data->_M_positive_sign_size = 0;
fea4065d 510 _M_data->_M_negative_sign = L"";
fe932e50 511 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
512 _M_data->_M_frac_digits = 0;
513 _M_data->_M_pos_format = money_base::_S_default_pattern;
514 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
515
516 // Use ctype::widen code without the facet...
fe932e50 517 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
af55af57
PC
518 _M_data->_M_atoms[__i] =
519 static_cast<wchar_t>(money_base::_S_atoms[__i]);
69971cd8
BK
520 }
521 else
522 {
523 // Named locale.
9a6d2071
JJ
524#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
525 __c_locale __old = __uselocale(__cloc);
526#else
527 // Switch to named locale so that mbsrtowcs will work.
fdf7e809
BK
528 char* __old = strdup(setlocale(LC_ALL, NULL));
529 setlocale(LC_ALL, __name);
9a6d2071 530#endif
fdf7e809 531
43be7fe7 532 union __s_and_w { const char *__s; unsigned int __w; } __u;
f332a090 533 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
fea4065d 534 _M_data->_M_decimal_point = static_cast<wchar_t>(__u.__w);
43be7fe7 535
f332a090 536 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
fea4065d 537 _M_data->_M_thousands_sep = static_cast<wchar_t>(__u.__w);
f332a090 538 _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
fe932e50 539 _M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
55dea7b1 540
d3a193e3
BK
541 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
542 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
543 const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
55dea7b1 544
f991b1d8
PC
545 wchar_t* __wcs_ps = 0;
546 wchar_t* __wcs_ns = 0;
547 const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
548 try
549 {
550 mbstate_t __state;
551 size_t __len;
552 __len = strlen(__cpossign);
553 if (__len)
554 {
555 ++__len;
556 memset(&__state, 0, sizeof(mbstate_t));
557 __wcs_ps = new wchar_t[__len];
558 mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
559 _M_data->_M_positive_sign = __wcs_ps;
560 }
561 else
562 _M_data->_M_positive_sign = L"";
fe932e50 563 _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
f991b1d8
PC
564
565 __len = strlen(__cnegsign);
566 if (!__nposn)
567 _M_data->_M_negative_sign = L"()";
568 else if (__len)
569 {
570 ++__len;
571 memset(&__state, 0, sizeof(mbstate_t));
572 __wcs_ns = new wchar_t[__len];
573 mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
574 _M_data->_M_negative_sign = __wcs_ns;
575 }
576 else
577 _M_data->_M_negative_sign = L"";
fe932e50
PC
578 _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
579
f991b1d8
PC
580 // _Intl == true.
581 __len = strlen(__ccurr);
582 if (__len)
583 {
584 ++__len;
585 memset(&__state, 0, sizeof(mbstate_t));
586 wchar_t* __wcs = new wchar_t[__len];
587 mbsrtowcs(__wcs, &__ccurr, __len, &__state);
588 _M_data->_M_curr_symbol = __wcs;
589 }
590 else
591 _M_data->_M_curr_symbol = L"";
fe932e50 592 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
55dea7b1 593 }
f991b1d8 594 catch (...)
55dea7b1 595 {
f991b1d8
PC
596 delete _M_data;
597 _M_data = 0;
598 delete __wcs_ps;
599 delete __wcs_ns;
f942e78d
AS
600#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
601 __uselocale(__old);
602#else
603 setlocale(LC_ALL, __old);
604 free(__old);
605#endif
f991b1d8 606 __throw_exception_again;
55dea7b1 607 }
55dea7b1 608
fea4065d 609 _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
754d9299 610 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
69971cd8
BK
611 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
612 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
fea4065d
BK
613 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
614 __pposn);
754d9299 615 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
69971cd8 616 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
fea4065d
BK
617 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
618 __nposn);
fdf7e809 619
9a6d2071
JJ
620#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
621 __uselocale(__old);
622#else
fdf7e809
BK
623 setlocale(LC_ALL, __old);
624 free(__old);
9a6d2071 625#endif
72e2386f
BK
626 }
627 }
d3a193e3
BK
628
629 template<>
630 moneypunct<wchar_t, true>::~moneypunct()
631 {
fe932e50 632 if (_M_data->_M_positive_sign_size)
fea4065d 633 delete [] _M_data->_M_positive_sign;
fe932e50
PC
634 if (_M_data->_M_negative_sign_size
635 && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
fea4065d 636 delete [] _M_data->_M_negative_sign;
fe932e50 637 if (_M_data->_M_curr_symbol_size)
fea4065d
BK
638 delete [] _M_data->_M_curr_symbol;
639 delete _M_data;
d3a193e3
BK
640 }
641
642 template<>
643 moneypunct<wchar_t, false>::~moneypunct()
644 {
fe932e50 645 if (_M_data->_M_positive_sign_size)
fea4065d 646 delete [] _M_data->_M_positive_sign;
fe932e50
PC
647 if (_M_data->_M_negative_sign_size
648 && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
fea4065d 649 delete [] _M_data->_M_negative_sign;
fe932e50 650 if (_M_data->_M_curr_symbol_size)
fea4065d
BK
651 delete [] _M_data->_M_curr_symbol;
652 delete _M_data;
d3a193e3 653 }
72e2386f
BK
654#endif
655}