]> git.ipfire.org Git - thirdparty/gcc.git/blob - 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
1 // std::moneypunct implementation details, GNU version -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 // Free Software Foundation, Inc.
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
9 // Free Software Foundation; either version 3, or (at your option)
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
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/>.
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>
33 #include <bits/c++locale_internal.h>
34
35 _GLIBCXX_BEGIN_NAMESPACE(std)
36
37 // Construct and return valid pattern consisting of some combination of:
38 // space none symbol sign value
39 money_base::pattern
40 money_base::_S_construct_pattern(char __precedes, char __space, char __posn)
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
47 // if (__precedes) symbol -> value
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.
62 __ret.field[0] = sign;
63 if (__space)
64 {
65 // Pattern starts with sign.
66 if (__precedes)
67 {
68 __ret.field[1] = symbol;
69 __ret.field[3] = value;
70 }
71 else
72 {
73 __ret.field[1] = value;
74 __ret.field[3] = symbol;
75 }
76 __ret.field[2] = space;
77 }
78 else
79 {
80 // Pattern starts with sign and ends with none.
81 if (__precedes)
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 }
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.
99 if (__precedes)
100 {
101 __ret.field[0] = symbol;
102 __ret.field[2] = value;
103 }
104 else
105 {
106 __ret.field[0] = value;
107 __ret.field[2] = symbol;
108 }
109 __ret.field[1] = space;
110 __ret.field[3] = sign;
111 }
112 else
113 {
114 // Pattern ends with sign then none.
115 if (__precedes)
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.
131 if (__precedes)
132 {
133 __ret.field[0] = sign;
134 __ret.field[1] = symbol;
135 if (__space)
136 {
137 __ret.field[2] = space;
138 __ret.field[3] = value;
139 }
140 else
141 {
142 __ret.field[2] = value;
143 __ret.field[3] = none;
144 }
145 }
146 else
147 {
148 __ret.field[0] = value;
149 if (__space)
150 {
151 __ret.field[1] = space;
152 __ret.field[2] = sign;
153 __ret.field[3] = symbol;
154 }
155 else
156 {
157 __ret.field[1] = sign;
158 __ret.field[2] = symbol;
159 __ret.field[3] = none;
160 }
161 }
162 break;
163 case 4:
164 // 4 The sign immediately follows the symbol.
165 if (__precedes)
166 {
167 __ret.field[0] = symbol;
168 __ret.field[1] = sign;
169 if (__space)
170 {
171 __ret.field[2] = space;
172 __ret.field[3] = value;
173 }
174 else
175 {
176 __ret.field[2] = value;
177 __ret.field[3] = none;
178 }
179 }
180 else
181 {
182 __ret.field[0] = value;
183 if (__space)
184 {
185 __ret.field[1] = space;
186 __ret.field[2] = symbol;
187 __ret.field[3] = sign;
188 }
189 else
190 {
191 __ret.field[1] = symbol;
192 __ret.field[2] = sign;
193 __ret.field[3] = none;
194 }
195 }
196 break;
197 default:
198 __ret = pattern();
199 }
200 return __ret;
201 }
202
203 template<>
204 void
205 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
206 const char*)
207 {
208 if (!_M_data)
209 _M_data = new __moneypunct_cache<char, true>;
210
211 if (!__cloc)
212 {
213 // "C" locale
214 _M_data->_M_decimal_point = '.';
215 _M_data->_M_thousands_sep = ',';
216 _M_data->_M_grouping = "";
217 _M_data->_M_grouping_size = 0;
218 _M_data->_M_use_grouping = false;
219 _M_data->_M_curr_symbol = "";
220 _M_data->_M_curr_symbol_size = 0;
221 _M_data->_M_positive_sign = "";
222 _M_data->_M_positive_sign_size = 0;
223 _M_data->_M_negative_sign = "";
224 _M_data->_M_negative_sign_size = 0;
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;
228
229 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
230 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
231 }
232 else
233 {
234 // Named locale.
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));
239 _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
240 _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
241
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
268 char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
269 if (!__nposn)
270 _M_data->_M_negative_sign = "()";
271 else
272 _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN,
273 __cloc);
274 _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign);
275
276 // _Intl == true
277 _M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
278 _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
279 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
280 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
281 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
282 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
283 __pposn);
284 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
285 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
286 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
287 __nposn);
288 }
289 }
290
291 template<>
292 void
293 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
294 const char*)
295 {
296 if (!_M_data)
297 _M_data = new __moneypunct_cache<char, false>;
298
299 if (!__cloc)
300 {
301 // "C" locale
302 _M_data->_M_decimal_point = '.';
303 _M_data->_M_thousands_sep = ',';
304 _M_data->_M_grouping = "";
305 _M_data->_M_grouping_size = 0;
306 _M_data->_M_use_grouping = false;
307 _M_data->_M_curr_symbol = "";
308 _M_data->_M_curr_symbol_size = 0;
309 _M_data->_M_positive_sign = "";
310 _M_data->_M_positive_sign_size = 0;
311 _M_data->_M_negative_sign = "";
312 _M_data->_M_negative_sign_size = 0;
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;
316
317 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
318 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i];
319 }
320 else
321 {
322 // Named locale.
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));
327 _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
328 _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
329
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
356 char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
357 if (!__nposn)
358 _M_data->_M_negative_sign = "()";
359 else
360 _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN,
361 __cloc);
362 _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign);
363
364 // _Intl == false
365 _M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
366 _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
367 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
368 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
369 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
370 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
371 __pposn);
372 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
373 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
374 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
375 __nposn);
376 }
377 }
378
379 template<>
380 moneypunct<char, true>::~moneypunct()
381 { delete _M_data; }
382
383 template<>
384 moneypunct<char, false>::~moneypunct()
385 { delete _M_data; }
386
387 #ifdef _GLIBCXX_USE_WCHAR_T
388 template<>
389 void
390 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
391 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
392 const char*)
393 #else
394 const char* __name)
395 #endif
396 {
397 if (!_M_data)
398 _M_data = new __moneypunct_cache<wchar_t, true>;
399
400 if (!__cloc)
401 {
402 // "C" locale
403 _M_data->_M_decimal_point = L'.';
404 _M_data->_M_thousands_sep = L',';
405 _M_data->_M_grouping = "";
406 _M_data->_M_grouping_size = 0;
407 _M_data->_M_use_grouping = false;
408 _M_data->_M_curr_symbol = L"";
409 _M_data->_M_curr_symbol_size = 0;
410 _M_data->_M_positive_sign = L"";
411 _M_data->_M_positive_sign_size = 0;
412 _M_data->_M_negative_sign = L"";
413 _M_data->_M_negative_sign_size = 0;
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;
417
418 // Use ctype::widen code without the facet...
419 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
420 _M_data->_M_atoms[__i] =
421 static_cast<wchar_t>(money_base::_S_atoms[__i]);
422 }
423 else
424 {
425 // Named locale.
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.
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);
434 setlocale(LC_ALL, __name);
435 #endif
436
437 union { char *__s; wchar_t __w; } __u;
438 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
439 _M_data->_M_decimal_point = __u.__w;
440
441 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
442 _M_data->_M_thousands_sep = __u.__w;
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));
469
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);
473
474 wchar_t* __wcs_ps = 0;
475 wchar_t* __wcs_ns = 0;
476 const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
477 __try
478 {
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"";
491 _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
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"";
506 _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
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"";
520 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol);
521 }
522 __catch(...)
523 {
524 delete _M_data;
525 _M_data = 0;
526 delete [] __wcs_ps;
527 delete [] __wcs_ns;
528 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
529 __uselocale(__old);
530 #else
531 setlocale(LC_ALL, __sav);
532 delete [] __sav;
533 #endif
534 __throw_exception_again;
535 }
536
537 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
538 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
539 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
540 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
541 __pposn);
542 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
543 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
544 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
545 __nposn);
546
547 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
548 __uselocale(__old);
549 #else
550 setlocale(LC_ALL, __sav);
551 delete [] __sav;
552 #endif
553 }
554 }
555
556 template<>
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*)
561 #else
562 const char* __name)
563 #endif
564 {
565 if (!_M_data)
566 _M_data = new __moneypunct_cache<wchar_t, false>;
567
568 if (!__cloc)
569 {
570 // "C" locale
571 _M_data->_M_decimal_point = L'.';
572 _M_data->_M_thousands_sep = L',';
573 _M_data->_M_grouping = "";
574 _M_data->_M_grouping_size = 0;
575 _M_data->_M_use_grouping = false;
576 _M_data->_M_curr_symbol = L"";
577 _M_data->_M_curr_symbol_size = 0;
578 _M_data->_M_positive_sign = L"";
579 _M_data->_M_positive_sign_size = 0;
580 _M_data->_M_negative_sign = L"";
581 _M_data->_M_negative_sign_size = 0;
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;
585
586 // Use ctype::widen code without the facet...
587 for (size_t __i = 0; __i < money_base::_S_end; ++__i)
588 _M_data->_M_atoms[__i] =
589 static_cast<wchar_t>(money_base::_S_atoms[__i]);
590 }
591 else
592 {
593 // Named locale.
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.
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);
602 setlocale(LC_ALL, __name);
603 #endif
604
605 union { char *__s; wchar_t __w; } __u;
606 __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc);
607 _M_data->_M_decimal_point = __u.__w;
608
609 __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
610 _M_data->_M_thousands_sep = __u.__w;
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));
637
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);
641
642 wchar_t* __wcs_ps = 0;
643 wchar_t* __wcs_ns = 0;
644 const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
645 __try
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"";
660 _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign);
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"";
675 _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign);
676
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"";
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 [] __wcs_ps;
696 delete [] __wcs_ns;
697 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
698 __uselocale(__old);
699 #else
700 setlocale(LC_ALL, __sav);
701 delete [] __sav;
702 #endif
703 __throw_exception_again;
704 }
705
706 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
707 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
708 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
709 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace,
710 __pposn);
711 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
712 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
713 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace,
714 __nposn);
715
716 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
717 __uselocale(__old);
718 #else
719 setlocale(LC_ALL, __sav);
720 delete [] __sav;
721 #endif
722 }
723 }
724
725 template<>
726 moneypunct<wchar_t, true>::~moneypunct()
727 {
728 if (_M_data->_M_positive_sign_size)
729 delete [] _M_data->_M_positive_sign;
730 if (_M_data->_M_negative_sign_size
731 && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
732 delete [] _M_data->_M_negative_sign;
733 if (_M_data->_M_curr_symbol_size)
734 delete [] _M_data->_M_curr_symbol;
735 delete _M_data;
736 }
737
738 template<>
739 moneypunct<wchar_t, false>::~moneypunct()
740 {
741 if (_M_data->_M_positive_sign_size)
742 delete [] _M_data->_M_positive_sign;
743 if (_M_data->_M_negative_sign_size
744 && wcscmp(_M_data->_M_negative_sign, L"()") != 0)
745 delete [] _M_data->_M_negative_sign;
746 if (_M_data->_M_curr_symbol_size)
747 delete [] _M_data->_M_curr_symbol;
748 delete _M_data;
749 }
750 #endif
751
752 _GLIBCXX_END_NAMESPACE