]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/libstdc++-v3/contrib/libstdc++-v3-5/config/locale/gnu/monetary_members.cc
Update
[l4.git] / l4 / pkg / l4re-core / libstdc++-v3 / contrib / libstdc++-v3-5 / config / locale / gnu / monetary_members.cc
1 // std::moneypunct implementation details, GNU version -*- C++ -*-
2
3 // Copyright (C) 2001-2015 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