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