]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/config/locale/gnu/monetary_members.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / config / locale / gnu / monetary_members.cc
CommitLineData
72e2386f
BK
1// std::moneypunct implementation details, GNU version -*- C++ -*-
2
7adcbafe 3// Copyright (C) 2001-2022 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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
72e2386f
BK
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
748086b7
JJ
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/>.
72e2386f
BK
24
25//
26// ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions
27//
28
29// Written by Benjamin Kosnik <bkoz@redhat.com>
30
31#include <locale>
6aa43d99 32#include <bits/c++locale_internal.h>
72e2386f 33
12ffa228
BK
34namespace std _GLIBCXX_VISIBILITY(default)
35{
36_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 37
34a2b755
JW
38// This file might be compiled twice, but we only want to define the members
39// of money_base once.
40#if ! _GLIBCXX_USE_CXX11_ABI
41
69971cd8
BK
42 // Construct and return valid pattern consisting of some combination of:
43 // space none symbol sign value
44 money_base::pattern
f92ab29f 45 money_base::_S_construct_pattern(char __precedes, char __space,
32ade559 46 char __posn) throw()
f92ab29f 47 {
69971cd8
BK
48 pattern __ret;
49
50 // This insanely complicated routine attempts to construct a valid
51 // pattern for use with monyepunct. A couple of invariants:
52
754d9299 53 // if (__precedes) symbol -> value
69971cd8 54 // else value -> symbol
f92ab29f 55
69971cd8
BK
56 // if (__space) space
57 // else none
58
59 // none == never first
60 // space never first or last
61
62 // Any elegant implementations of this are welcome.
63 switch (__posn)
64 {
65 case 0:
66 case 1:
67 // 1 The sign precedes the value and symbol.
cc0c2f79 68 __ret.field[0] = sign;
69971cd8
BK
69 if (__space)
70 {
71 // Pattern starts with sign.
754d9299 72 if (__precedes)
69971cd8
BK
73 {
74 __ret.field[1] = symbol;
69971cd8
BK
75 __ret.field[3] = value;
76 }
77 else
78 {
79 __ret.field[1] = value;
69971cd8
BK
80 __ret.field[3] = symbol;
81 }
f7ba331c 82 __ret.field[2] = space;
69971cd8
BK
83 }
84 else
85 {
86 // Pattern starts with sign and ends with none.
754d9299 87 if (__precedes)
69971cd8
BK
88 {
89 __ret.field[1] = symbol;
90 __ret.field[2] = value;
91 }
92 else
93 {
94 __ret.field[1] = value;
95 __ret.field[2] = symbol;
96 }
69971cd8
BK
97 __ret.field[3] = none;
98 }
99 break;
100 case 2:
101 // 2 The sign follows the value and symbol.
102 if (__space)
103 {
104 // Pattern either ends with sign.
754d9299 105 if (__precedes)
69971cd8
BK
106 {
107 __ret.field[0] = symbol;
69971cd8
BK
108 __ret.field[2] = value;
109 }
110 else
111 {
112 __ret.field[0] = value;
69971cd8
BK
113 __ret.field[2] = symbol;
114 }
cc0c2f79 115 __ret.field[1] = space;
69971cd8
BK
116 __ret.field[3] = sign;
117 }
118 else
119 {
120 // Pattern ends with sign then none.
754d9299 121 if (__precedes)
69971cd8
BK
122 {
123 __ret.field[0] = symbol;
124 __ret.field[1] = value;
125 }
126 else
127 {
128 __ret.field[0] = value;
129 __ret.field[1] = symbol;
130 }
131 __ret.field[2] = sign;
132 __ret.field[3] = none;
133 }
134 break;
135 case 3:
136 // 3 The sign immediately precedes the symbol.
142b798b 137 if (__precedes)
69971cd8 138 {
142b798b 139 __ret.field[0] = sign;
f92ab29f 140 __ret.field[1] = symbol;
142b798b 141 if (__space)
69971cd8 142 {
69971cd8
BK
143 __ret.field[2] = space;
144 __ret.field[3] = value;
145 }
146 else
147 {
f92ab29f 148 __ret.field[2] = value;
142b798b 149 __ret.field[3] = none;
69971cd8
BK
150 }
151 }
152 else
153 {
142b798b
PC
154 __ret.field[0] = value;
155 if (__space)
69971cd8 156 {
142b798b
PC
157 __ret.field[1] = space;
158 __ret.field[2] = sign;
159 __ret.field[3] = symbol;
69971cd8
BK
160 }
161 else
162 {
69971cd8
BK
163 __ret.field[1] = sign;
164 __ret.field[2] = symbol;
142b798b 165 __ret.field[3] = none;
69971cd8 166 }
69971cd8
BK
167 }
168 break;
169 case 4:
142b798b
PC
170 // 4 The sign immediately follows the symbol.
171 if (__precedes)
69971cd8 172 {
142b798b
PC
173 __ret.field[0] = symbol;
174 __ret.field[1] = sign;
175 if (__space)
69971cd8 176 {
69971cd8
BK
177 __ret.field[2] = space;
178 __ret.field[3] = value;
179 }
180 else
181 {
142b798b
PC
182 __ret.field[2] = value;
183 __ret.field[3] = none;
69971cd8
BK
184 }
185 }
186 else
187 {
142b798b
PC
188 __ret.field[0] = value;
189 if (__space)
69971cd8 190 {
142b798b
PC
191 __ret.field[1] = space;
192 __ret.field[2] = symbol;
193 __ret.field[3] = sign;
69971cd8
BK
194 }
195 else
196 {
69971cd8
BK
197 __ret.field[1] = symbol;
198 __ret.field[2] = sign;
142b798b 199 __ret.field[3] = none;
69971cd8 200 }
69971cd8
BK
201 }
202 break;
203 default:
a780ad2f 204 __ret = pattern();
69971cd8
BK
205 }
206 return __ret;
207 }
34a2b755 208#endif
69971cd8 209
c0ace69e
JW
210 extern char __narrow_multibyte_chars(const char* s, __locale_t cloc);
211
f92ab29f 212 template<>
72e2386f 213 void
f92ab29f 214 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
fdf7e809 215 const char*)
72e2386f 216 {
fea4065d 217 if (!_M_data)
fe932e50 218 _M_data = new __moneypunct_cache<char, true>;
fea4065d 219
aa53f832 220 if (!__cloc)
72e2386f
BK
221 {
222 // "C" locale
fea4065d
BK
223 _M_data->_M_decimal_point = '.';
224 _M_data->_M_thousands_sep = ',';
225 _M_data->_M_grouping = "";
fe932e50 226 _M_data->_M_grouping_size = 0;
1d9aba81 227 _M_data->_M_use_grouping = false;
fea4065d 228 _M_data->_M_curr_symbol = "";
fe932e50 229 _M_data->_M_curr_symbol_size = 0;
fea4065d 230 _M_data->_M_positive_sign = "";
fe932e50 231 _M_data->_M_positive_sign_size = 0;
fea4065d 232 _M_data->_M_negative_sign = "";
fe932e50 233 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
234 _M_data->_M_frac_digits = 0;
235 _M_data->_M_pos_format = money_base::_S_default_pattern;
236 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
237
238 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
239 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
72e2386f
BK
240 }
241 else
242 {
243 // Named locale.
f92ab29f 244 _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT,
fea4065d 245 __cloc));
c0ace69e
JW
246 const char* thousands_sep = __nl_langinfo_l(__MON_THOUSANDS_SEP,
247 __cloc);
248 if (thousands_sep[0] != '\0' && thousands_sep[1] != '\0')
249 _M_data->_M_thousands_sep = __narrow_multibyte_chars(thousands_sep,
250 __cloc);
251 else
252 _M_data->_M_thousands_sep = *thousands_sep;
1d9aba81
PC
253
254 // Check for NULL, which implies no fractional digits.
255 if (_M_data->_M_decimal_point == '\0')
256 {
257 // Like in "C" locale.
258 _M_data->_M_frac_digits = 0;
259 _M_data->_M_decimal_point = '.';
260 }
261 else
f92ab29f 262 _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
1d9aba81
PC
263 __cloc));
264
af90c8c9
PC
265 const char* __cgroup = __nl_langinfo_l(__MON_GROUPING, __cloc);
266 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
267 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
69971cd8 268 // _Intl == true
af90c8c9
PC
269 const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
270
271 char* __group = 0;
272 char* __ps = 0;
273 char* __ns = 0;
f92ab29f 274 const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
af90c8c9
PC
275 __try
276 {
277 size_t __len;
f92ab29f 278
af90c8c9
PC
279 // Check for NULL, which implies no grouping.
280 if (_M_data->_M_thousands_sep == '\0')
281 {
282 // Like in "C" locale.
283 _M_data->_M_grouping = "";
284 _M_data->_M_grouping_size = 0;
285 _M_data->_M_use_grouping = false;
286 _M_data->_M_thousands_sep = ',';
287 }
288 else
289 {
290 __len = strlen(__cgroup);
291 if (__len)
292 {
293 __group = new char[__len + 1];
294 memcpy(__group, __cgroup, __len + 1);
295 _M_data->_M_grouping = __group;
296 }
297 else
298 {
299 _M_data->_M_grouping = "";
300 _M_data->_M_use_grouping = false;
301 }
302 _M_data->_M_grouping_size = __len;
303 }
304
305 __len = strlen(__cpossign);
306 if (__len)
307 {
308 __ps = new char[__len + 1];
309 memcpy(__ps, __cpossign, __len + 1);
310 _M_data->_M_positive_sign = __ps;
311 }
312 else
313 _M_data->_M_positive_sign = "";
314 _M_data->_M_positive_sign_size = __len;
315
316 if (!__nposn)
317 {
318 _M_data->_M_negative_sign = "()";
319 _M_data->_M_negative_sign_size = 2;
320 }
321 else
322 {
323 __len = strlen(__cnegsign);
324 if (__len)
325 {
326 __ns = new char[__len + 1];
327 memcpy(__ns, __cnegsign, __len + 1);
328 _M_data->_M_negative_sign = __ns;
329 }
330 else
331 _M_data->_M_negative_sign = "";
332 _M_data->_M_negative_sign_size = __len;
333 }
334
335 __len = strlen(__ccurr);
336 if (__len)
337 {
338 char* __curr = new char[__len + 1];
339 memcpy(__curr, __ccurr, __len + 1);
340 _M_data->_M_curr_symbol = __curr;
341 }
342 else
343 _M_data->_M_curr_symbol = "";
344 _M_data->_M_curr_symbol_size = __len;
345 }
346 __catch(...)
347 {
348 delete _M_data;
349 _M_data = 0;
350 delete [] __group;
351 delete [] __ps;
352 delete [] __ns;
f09805bb 353 __throw_exception_again;
af90c8c9
PC
354 }
355
754d9299 356 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
69971cd8
BK
357 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
358 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
af90c8c9 359 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
fea4065d 360 __pposn);
754d9299 361 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
69971cd8 362 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
af90c8c9 363 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
fea4065d 364 __nposn);
69971cd8
BK
365 }
366 }
367
f92ab29f 368 template<>
69971cd8 369 void
f92ab29f 370 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
fdf7e809 371 const char*)
69971cd8 372 {
fea4065d 373 if (!_M_data)
fe932e50 374 _M_data = new __moneypunct_cache<char, false>;
fea4065d 375
aa53f832 376 if (!__cloc)
69971cd8
BK
377 {
378 // "C" locale
fea4065d
BK
379 _M_data->_M_decimal_point = '.';
380 _M_data->_M_thousands_sep = ',';
381 _M_data->_M_grouping = "";
fe932e50 382 _M_data->_M_grouping_size = 0;
1d9aba81 383 _M_data->_M_use_grouping = false;
fea4065d 384 _M_data->_M_curr_symbol = "";
fe932e50 385 _M_data->_M_curr_symbol_size = 0;
fea4065d 386 _M_data->_M_positive_sign = "";
fe932e50 387 _M_data->_M_positive_sign_size = 0;
fea4065d 388 _M_data->_M_negative_sign = "";
fe932e50 389 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
390 _M_data->_M_frac_digits = 0;
391 _M_data->_M_pos_format = money_base::_S_default_pattern;
392 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
393
394 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
395 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
69971cd8
BK
396 }
397 else
398 {
399 // Named locale.
f92ab29f 400 _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT,
fea4065d 401 __cloc));
f92ab29f 402 _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
fea4065d 403 __cloc));
1d9aba81
PC
404
405 // Check for NULL, which implies no fractional digits.
406 if (_M_data->_M_decimal_point == '\0')
407 {
408 // Like in "C" locale.
409 _M_data->_M_frac_digits = 0;
410 _M_data->_M_decimal_point = '.';
411 }
412 else
413 _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS,
414 __cloc));
415
af90c8c9
PC
416 const char* __cgroup = __nl_langinfo_l(__MON_GROUPING, __cloc);
417 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
418 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
69971cd8 419 // _Intl == false
af90c8c9
PC
420 const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
421
422 char* __group = 0;
423 char* __ps = 0;
424 char* __ns = 0;
425 const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
426 __try
427 {
428 size_t __len;
429
430 // Check for NULL, which implies no grouping.
431 if (_M_data->_M_thousands_sep == '\0')
432 {
433 // Like in "C" locale.
434 _M_data->_M_grouping = "";
435 _M_data->_M_grouping_size = 0;
436 _M_data->_M_use_grouping = false;
437 _M_data->_M_thousands_sep = ',';
438 }
439 else
440 {
441 __len = strlen(__cgroup);
442 if (__len)
443 {
444 __group = new char[__len + 1];
445 memcpy(__group, __cgroup, __len + 1);
446 _M_data->_M_grouping = __group;
447 }
448 else
449 {
450 _M_data->_M_grouping = "";
451 _M_data->_M_use_grouping = false;
452 }
453 _M_data->_M_grouping_size = __len;
454 }
455
456 __len = strlen(__cpossign);
457 if (__len)
458 {
459 __ps = new char[__len + 1];
460 memcpy(__ps, __cpossign, __len + 1);
461 _M_data->_M_positive_sign = __ps;
462 }
463 else
464 _M_data->_M_positive_sign = "";
465 _M_data->_M_positive_sign_size = __len;
466
467 if (!__nposn)
468 {
469 _M_data->_M_negative_sign = "()";
470 _M_data->_M_negative_sign_size = 2;
471 }
472 else
473 {
474 __len = strlen(__cnegsign);
475 if (__len)
476 {
477 __ns = new char[__len + 1];
478 memcpy(__ns, __cnegsign, __len + 1);
479 _M_data->_M_negative_sign = __ns;
480 }
481 else
482 _M_data->_M_negative_sign = "";
483 _M_data->_M_negative_sign_size = __len;
484 }
485
486 __len = strlen(__ccurr);
487 if (__len)
488 {
489 char* __curr = new char[__len + 1];
490 memcpy(__curr, __ccurr, __len + 1);
491 _M_data->_M_curr_symbol = __curr;
492 }
493 else
494 _M_data->_M_curr_symbol = "";
495 _M_data->_M_curr_symbol_size = __len;
496 }
497 __catch(...)
498 {
499 delete _M_data;
500 _M_data = 0;
501 delete [] __group;
502 delete [] __ps;
503 delete [] __ns;
f09805bb 504 __throw_exception_again;
af90c8c9
PC
505 }
506
754d9299 507 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
69971cd8
BK
508 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
509 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
af90c8c9 510 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
fea4065d 511 __pposn);
754d9299 512 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
69971cd8 513 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
af90c8c9 514 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
fea4065d 515 __nposn);
72e2386f
BK
516 }
517 }
518
f92ab29f 519 template<>
d3a193e3 520 moneypunct<char, true>::~moneypunct()
af90c8c9
PC
521 {
522 if (_M_data->_M_grouping_size)
523 delete [] _M_data->_M_grouping;
524 if (_M_data->_M_positive_sign_size)
525 delete [] _M_data->_M_positive_sign;
526 if (_M_data->_M_negative_sign_size
527 && strcmp(_M_data->_M_negative_sign, "()") != 0)
528 delete [] _M_data->_M_negative_sign;
529 if (_M_data->_M_curr_symbol_size)
530 delete [] _M_data->_M_curr_symbol;
531 delete _M_data;
532 }
d3a193e3 533
f92ab29f 534 template<>
d3a193e3 535 moneypunct<char, false>::~moneypunct()
af90c8c9
PC
536 {
537 if (_M_data->_M_grouping_size)
538 delete [] _M_data->_M_grouping;
539 if (_M_data->_M_positive_sign_size)
540 delete [] _M_data->_M_positive_sign;
541 if (_M_data->_M_negative_sign_size
542 && strcmp(_M_data->_M_negative_sign, "()") != 0)
543 delete [] _M_data->_M_negative_sign;
544 if (_M_data->_M_curr_symbol_size)
545 delete [] _M_data->_M_curr_symbol;
546 delete _M_data;
547 }
d3a193e3 548
3d7c150e 549#ifdef _GLIBCXX_USE_WCHAR_T
f92ab29f 550 template<>
72e2386f 551 void
f92ab29f 552 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
bce58224
PC
553#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
554 const char*)
555#else
fdf7e809 556 const char* __name)
bce58224 557#endif
72e2386f 558 {
fea4065d 559 if (!_M_data)
fe932e50 560 _M_data = new __moneypunct_cache<wchar_t, true>;
fea4065d 561
aa53f832 562 if (!__cloc)
72e2386f
BK
563 {
564 // "C" locale
fea4065d
BK
565 _M_data->_M_decimal_point = L'.';
566 _M_data->_M_thousands_sep = L',';
567 _M_data->_M_grouping = "";
fe932e50 568 _M_data->_M_grouping_size = 0;
1d9aba81 569 _M_data->_M_use_grouping = false;
fea4065d 570 _M_data->_M_curr_symbol = L"";
fe932e50 571 _M_data->_M_curr_symbol_size = 0;
fea4065d 572 _M_data->_M_positive_sign = L"";
fe932e50 573 _M_data->_M_positive_sign_size = 0;
fea4065d 574 _M_data->_M_negative_sign = L"";
fe932e50 575 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
576 _M_data->_M_frac_digits = 0;
577 _M_data->_M_pos_format = money_base::_S_default_pattern;
578 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
579
580 // Use ctype::widen code without the facet...
fe932e50 581 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
af55af57
PC
582 _M_data->_M_atoms[__i] =
583 static_cast<wchar_t>(money_base::_S_atoms[__i]);
72e2386f
BK
584 }
585 else
586 {
587 // Named locale.
9a6d2071
JJ
588#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
589 __c_locale __old = __uselocale(__cloc);
590#else
591 // Switch to named locale so that mbsrtowcs will work.
445877a9 592 char* __old = setlocale(LC_ALL, 0);
538075fe
PC
593 const size_t __llen = strlen(__old) + 1;
594 char* __sav = new char[__llen];
595 memcpy(__sav, __old, __llen);
fdf7e809 596 setlocale(LC_ALL, __name);
9a6d2071 597#endif
fdf7e809 598
61c53cd3 599 union { char *__s; wchar_t __w; } __u;
f332a090 600 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
61c53cd3 601 _M_data->_M_decimal_point = __u.__w;
86176835 602
f332a090 603 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
61c53cd3 604 _M_data->_M_thousands_sep = __u.__w;
1d9aba81 605
1d9aba81
PC
606 // Check for NULL, which implies no fractional digits.
607 if (_M_data->_M_decimal_point == L'\0')
608 {
609 // Like in "C" locale.
610 _M_data->_M_frac_digits = 0;
611 _M_data->_M_decimal_point = L'.';
612 }
613 else
f92ab29f 614 _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
1d9aba81 615 __cloc));
55dea7b1 616
af90c8c9 617 const char* __cgroup = __nl_langinfo_l(__MON_GROUPING, __cloc);
d3a193e3
BK
618 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
619 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
620 const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
55dea7b1 621
af90c8c9 622 char* __group = 0;
f991b1d8
PC
623 wchar_t* __wcs_ps = 0;
624 wchar_t* __wcs_ns = 0;
625 const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
bc2631e0 626 __try
55dea7b1 627 {
af90c8c9
PC
628 size_t __len;
629
630 // Check for NULL, which implies no grouping.
631 if (_M_data->_M_thousands_sep == L'\0')
632 {
633 // Like in "C" locale.
634 _M_data->_M_grouping = "";
635 _M_data->_M_grouping_size = 0;
636 _M_data->_M_use_grouping = false;
637 _M_data->_M_thousands_sep = L',';
638 }
639 else
640 {
641 __len = strlen(__cgroup);
642 if (__len)
643 {
644 __group = new char[__len + 1];
645 memcpy(__group, __cgroup, __len + 1);
646 _M_data->_M_grouping = __group;
647 }
648 else
649 {
650 _M_data->_M_grouping = "";
651 _M_data->_M_use_grouping = false;
652 }
653 _M_data->_M_grouping_size = __len;
654 }
655
f991b1d8 656 mbstate_t __state;
af90c8c9 657 __len = strlen(__cpossign);
f991b1d8
PC
658 if (__len)
659 {
f991b1d8 660 memset(&__state, 0, sizeof(mbstate_t));
af90c8c9
PC
661 __wcs_ps = new wchar_t[__len + 1];
662 mbsrtowcs(__wcs_ps, &__cpossign, __len + 1, &__state);
f991b1d8
PC
663 _M_data->_M_positive_sign = __wcs_ps;
664 }
665 else
666 _M_data->_M_positive_sign = L"";
f92ab29f 667 _M_data->_M_positive_sign_size =
af90c8c9 668 wcslen(_M_data->_M_positive_sign);
f92ab29f 669
f991b1d8
PC
670 __len = strlen(__cnegsign);
671 if (!__nposn)
672 _M_data->_M_negative_sign = L"()";
673 else if (__len)
af90c8c9 674 {
f991b1d8 675 memset(&__state, 0, sizeof(mbstate_t));
af90c8c9
PC
676 __wcs_ns = new wchar_t[__len + 1];
677 mbsrtowcs(__wcs_ns, &__cnegsign, __len + 1, &__state);
f991b1d8
PC
678 _M_data->_M_negative_sign = __wcs_ns;
679 }
680 else
681 _M_data->_M_negative_sign = L"";
f92ab29f 682 _M_data->_M_negative_sign_size =
af90c8c9 683 wcslen(_M_data->_M_negative_sign);
f92ab29f 684
f991b1d8
PC
685 // _Intl == true.
686 __len = strlen(__ccurr);
687 if (__len)
688 {
f991b1d8 689 memset(&__state, 0, sizeof(mbstate_t));
af90c8c9
PC
690 wchar_t* __wcs = new wchar_t[__len + 1];
691 mbsrtowcs(__wcs, &__ccurr, __len + 1, &__state);
f991b1d8
PC
692 _M_data->_M_curr_symbol = __wcs;
693 }
694 else
695 _M_data->_M_curr_symbol = L"";
fe932e50 696 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
55dea7b1 697 }
bc2631e0 698 __catch(...)
55dea7b1 699 {
f991b1d8
PC
700 delete _M_data;
701 _M_data = 0;
af90c8c9 702 delete [] __group;
c8a5f8f2 703 delete [] __wcs_ps;
f92ab29f 704 delete [] __wcs_ns;
f942e78d
AS
705#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
706 __uselocale(__old);
707#else
538075fe
PC
708 setlocale(LC_ALL, __sav);
709 delete [] __sav;
f942e78d 710#endif
f991b1d8 711 __throw_exception_again;
f92ab29f
CG
712 }
713
754d9299 714 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
69971cd8
BK
715 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
716 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
af90c8c9 717 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
fea4065d 718 __pposn);
754d9299 719 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
69971cd8 720 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
af90c8c9 721 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
fea4065d 722 __nposn);
fdf7e809 723
9a6d2071
JJ
724#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
725 __uselocale(__old);
726#else
538075fe
PC
727 setlocale(LC_ALL, __sav);
728 delete [] __sav;
9a6d2071 729#endif
69971cd8
BK
730 }
731 }
732
f92ab29f 733 template<>
f991b1d8
PC
734 void
735 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
736#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
737 const char*)
bce58224 738#else
f991b1d8 739 const char* __name)
bce58224 740#endif
f991b1d8
PC
741 {
742 if (!_M_data)
fe932e50 743 _M_data = new __moneypunct_cache<wchar_t, false>;
fea4065d 744
f991b1d8 745 if (!__cloc)
69971cd8
BK
746 {
747 // "C" locale
fea4065d
BK
748 _M_data->_M_decimal_point = L'.';
749 _M_data->_M_thousands_sep = L',';
750 _M_data->_M_grouping = "";
fe932e50 751 _M_data->_M_grouping_size = 0;
1d9aba81 752 _M_data->_M_use_grouping = false;
fea4065d 753 _M_data->_M_curr_symbol = L"";
fe932e50 754 _M_data->_M_curr_symbol_size = 0;
fea4065d 755 _M_data->_M_positive_sign = L"";
fe932e50 756 _M_data->_M_positive_sign_size = 0;
fea4065d 757 _M_data->_M_negative_sign = L"";
fe932e50 758 _M_data->_M_negative_sign_size = 0;
fea4065d
BK
759 _M_data->_M_frac_digits = 0;
760 _M_data->_M_pos_format = money_base::_S_default_pattern;
761 _M_data->_M_neg_format = money_base::_S_default_pattern;
fe932e50
PC
762
763 // Use ctype::widen code without the facet...
fe932e50 764 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
af55af57
PC
765 _M_data->_M_atoms[__i] =
766 static_cast<wchar_t>(money_base::_S_atoms[__i]);
69971cd8
BK
767 }
768 else
769 {
770 // Named locale.
9a6d2071
JJ
771#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
772 __c_locale __old = __uselocale(__cloc);
773#else
774 // Switch to named locale so that mbsrtowcs will work.
445877a9 775 char* __old = setlocale(LC_ALL, 0);
538075fe
PC
776 const size_t __llen = strlen(__old) + 1;
777 char* __sav = new char[__llen];
778 memcpy(__sav, __old, __llen);
fdf7e809 779 setlocale(LC_ALL, __name);
9a6d2071 780#endif
fdf7e809 781
61c53cd3 782 union { char *__s; wchar_t __w; } __u;
f332a090 783 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
61c53cd3 784 _M_data->_M_decimal_point = __u.__w;
43be7fe7 785
f332a090 786 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
61c53cd3 787 _M_data->_M_thousands_sep = __u.__w;
1d9aba81 788
1d9aba81
PC
789 // Check for NULL, which implies no fractional digits.
790 if (_M_data->_M_decimal_point == L'\0')
791 {
792 // Like in "C" locale.
793 _M_data->_M_frac_digits = 0;
794 _M_data->_M_decimal_point = L'.';
795 }
796 else
797 _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS,
798 __cloc));
55dea7b1 799
af90c8c9 800 const char* __cgroup = __nl_langinfo_l(__MON_GROUPING, __cloc);
d3a193e3
BK
801 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
802 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
803 const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
55dea7b1 804
af90c8c9 805 char* __group = 0;
f991b1d8
PC
806 wchar_t* __wcs_ps = 0;
807 wchar_t* __wcs_ns = 0;
808 const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
bc2631e0 809 __try
f991b1d8 810 {
af90c8c9
PC
811 size_t __len;
812
813 // Check for NULL, which implies no grouping.
814 if (_M_data->_M_thousands_sep == L'\0')
815 {
816 // Like in "C" locale.
817 _M_data->_M_grouping = "";
818 _M_data->_M_grouping_size = 0;
819 _M_data->_M_use_grouping = false;
820 _M_data->_M_thousands_sep = L',';
821 }
822 else
823 {
824 __len = strlen(__cgroup);
825 if (__len)
826 {
827 __group = new char[__len + 1];
828 memcpy(__group, __cgroup, __len + 1);
829 _M_data->_M_grouping = __group;
830 }
831 else
832 {
833 _M_data->_M_grouping = "";
834 _M_data->_M_use_grouping = false;
835 }
836 _M_data->_M_grouping_size = __len;
837 }
838
f991b1d8 839 mbstate_t __state;
f991b1d8
PC
840 __len = strlen(__cpossign);
841 if (__len)
842 {
f991b1d8 843 memset(&__state, 0, sizeof(mbstate_t));
af90c8c9
PC
844 __wcs_ps = new wchar_t[__len + 1];
845 mbsrtowcs(__wcs_ps, &__cpossign, __len + 1, &__state);
f991b1d8
PC
846 _M_data->_M_positive_sign = __wcs_ps;
847 }
848 else
849 _M_data->_M_positive_sign = L"";
f92ab29f 850 _M_data->_M_positive_sign_size =
af90c8c9
PC
851 wcslen(_M_data->_M_positive_sign);
852
f991b1d8
PC
853 __len = strlen(__cnegsign);
854 if (!__nposn)
855 _M_data->_M_negative_sign = L"()";
856 else if (__len)
af90c8c9 857 {
f991b1d8 858 memset(&__state, 0, sizeof(mbstate_t));
af90c8c9
PC
859 __wcs_ns = new wchar_t[__len + 1];
860 mbsrtowcs(__wcs_ns, &__cnegsign, __len + 1, &__state);
f991b1d8
PC
861 _M_data->_M_negative_sign = __wcs_ns;
862 }
863 else
864 _M_data->_M_negative_sign = L"";
f92ab29f 865 _M_data->_M_negative_sign_size =
af90c8c9 866 wcslen(_M_data->_M_negative_sign);
fe932e50 867
f991b1d8
PC
868 // _Intl == true.
869 __len = strlen(__ccurr);
870 if (__len)
871 {
f991b1d8 872 memset(&__state, 0, sizeof(mbstate_t));
af90c8c9
PC
873 wchar_t* __wcs = new wchar_t[__len + 1];
874 mbsrtowcs(__wcs, &__ccurr, __len + 1, &__state);
f991b1d8
PC
875 _M_data->_M_curr_symbol = __wcs;
876 }
877 else
878 _M_data->_M_curr_symbol = L"";
fe932e50 879 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
55dea7b1 880 }
bc2631e0 881 __catch(...)
55dea7b1 882 {
f991b1d8
PC
883 delete _M_data;
884 _M_data = 0;
af90c8c9 885 delete [] __group;
c8a5f8f2 886 delete [] __wcs_ps;
f92ab29f 887 delete [] __wcs_ns;
f942e78d
AS
888#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
889 __uselocale(__old);
890#else
538075fe
PC
891 setlocale(LC_ALL, __sav);
892 delete [] __sav;
f942e78d 893#endif
f991b1d8 894 __throw_exception_again;
55dea7b1 895 }
55dea7b1 896
754d9299 897 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
69971cd8
BK
898 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
899 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
af90c8c9 900 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
fea4065d 901 __pposn);
754d9299 902 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
69971cd8 903 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
af90c8c9 904 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
fea4065d 905 __nposn);
fdf7e809 906
9a6d2071
JJ
907#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
908 __uselocale(__old);
909#else
538075fe
PC
910 setlocale(LC_ALL, __sav);
911 delete [] __sav;
9a6d2071 912#endif
72e2386f
BK
913 }
914 }
d3a193e3 915
f92ab29f 916 template<>
d3a193e3
BK
917 moneypunct<wchar_t, true>::~moneypunct()
918 {
af90c8c9
PC
919 if (_M_data->_M_grouping_size)
920 delete [] _M_data->_M_grouping;
fe932e50 921 if (_M_data->_M_positive_sign_size)
fea4065d 922 delete [] _M_data->_M_positive_sign;
fe932e50
PC
923 if (_M_data->_M_negative_sign_size
924 && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
fea4065d 925 delete [] _M_data->_M_negative_sign;
fe932e50 926 if (_M_data->_M_curr_symbol_size)
fea4065d
BK
927 delete [] _M_data->_M_curr_symbol;
928 delete _M_data;
d3a193e3
BK
929 }
930
f92ab29f 931 template<>
d3a193e3
BK
932 moneypunct<wchar_t, false>::~moneypunct()
933 {
af90c8c9
PC
934 if (_M_data->_M_grouping_size)
935 delete [] _M_data->_M_grouping;
fe932e50 936 if (_M_data->_M_positive_sign_size)
fea4065d 937 delete [] _M_data->_M_positive_sign;
fe932e50
PC
938 if (_M_data->_M_negative_sign_size
939 && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
fea4065d 940 delete [] _M_data->_M_negative_sign;
fe932e50 941 if (_M_data->_M_curr_symbol_size)
fea4065d
BK
942 delete [] _M_data->_M_curr_symbol;
943 delete _M_data;
d3a193e3 944 }
72e2386f 945#endif
3cbc7af0 946
12ffa228
BK
947_GLIBCXX_END_NAMESPACE_VERSION
948} // namespace