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