]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/libstdc++-v3/contrib/libstdc++-v3-4.4/config/locale/gnu/monetary_members.cc
Update
[l4.git] / l4 / pkg / l4re-core / libstdc++-v3 / contrib / libstdc++-v3-4.4 / 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