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