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