1 // std::moneypunct implementation details, GNU version -*- C++ -*-
3 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
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 2, or (at your option)
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31 // ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions
34 // Written by Benjamin Kosnik <bkoz@redhat.com>
37 #include "c++locale_internal.h"
41 // Construct and return valid pattern consisting of some combination of:
42 // space none symbol sign value
44 money_base::_S_construct_pattern(char __precedes, char __space, char __posn)
48 // This insanely complicated routine attempts to construct a valid
49 // pattern for use with monyepunct. A couple of invariants:
51 // if (__precedes) symbol -> value
52 // else value -> symbol
57 // none == never first
58 // space never first or last
60 // Any elegant implementations of this are welcome.
65 // 1 The sign precedes the value and symbol.
68 // Pattern starts with sign.
71 __ret.field[1] = symbol;
72 __ret.field[2] = space;
73 __ret.field[3] = value;
77 __ret.field[1] = value;
78 __ret.field[2] = space;
79 __ret.field[3] = symbol;
81 __ret.field[0] = sign;
85 // Pattern starts with sign and ends with none.
88 __ret.field[1] = symbol;
89 __ret.field[2] = value;
93 __ret.field[1] = value;
94 __ret.field[2] = symbol;
96 __ret.field[0] = sign;
97 __ret.field[3] = none;
101 // 2 The sign follows the value and symbol.
104 // Pattern either ends with sign.
107 __ret.field[0] = symbol;
108 __ret.field[1] = space;
109 __ret.field[2] = value;
113 __ret.field[0] = value;
114 __ret.field[1] = space;
115 __ret.field[2] = symbol;
117 __ret.field[3] = sign;
121 // Pattern ends with sign then none.
124 __ret.field[0] = symbol;
125 __ret.field[1] = value;
129 __ret.field[0] = value;
130 __ret.field[1] = symbol;
132 __ret.field[2] = sign;
133 __ret.field[3] = none;
137 // 3 The sign immediately precedes the symbol.
143 __ret.field[0] = sign;
144 __ret.field[1] = symbol;
145 __ret.field[2] = space;
146 __ret.field[3] = value;
150 __ret.field[0] = value;
151 __ret.field[1] = space;
152 __ret.field[2] = sign;
153 __ret.field[3] = symbol;
161 __ret.field[0] = sign;
162 __ret.field[1] = symbol;
163 __ret.field[2] = value;
167 __ret.field[0] = value;
168 __ret.field[1] = sign;
169 __ret.field[2] = symbol;
171 __ret.field[3] = none;
175 // 4 The sign immediately follows the symbol.
181 __ret.field[0] = symbol;
182 __ret.field[1] = sign;
183 __ret.field[2] = space;
184 __ret.field[3] = value;
188 __ret.field[0] = value;
189 __ret.field[1] = space;
190 __ret.field[2] = symbol;
191 __ret.field[3] = sign;
199 __ret.field[0] = symbol;
200 __ret.field[1] = sign;
201 __ret.field[2] = value;
205 __ret.field[0] = value;
206 __ret.field[1] = symbol;
207 __ret.field[2] = sign;
209 __ret.field[3] = none;
220 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
226 _M_decimal_point = '.';
227 _M_thousands_sep = ',';
230 _M_positive_sign = "";
231 _M_negative_sign = "";
233 _M_pos_format = money_base::_S_default_pattern;
234 _M_neg_format = money_base::_S_default_pattern;
239 _M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, __cloc));
240 _M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, __cloc));
241 _M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
242 _M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
244 char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
246 _M_negative_sign = "()";
248 _M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
251 _M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
252 _M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, __cloc));
253 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
254 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
255 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
256 _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn);
257 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
258 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
259 _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
265 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
271 _M_decimal_point = '.';
272 _M_thousands_sep = ',';
275 _M_positive_sign = "";
276 _M_negative_sign = "";
278 _M_pos_format = money_base::_S_default_pattern;
279 _M_neg_format = money_base::_S_default_pattern;
284 _M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, __cloc));
285 _M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, __cloc));
286 _M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
287 _M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
289 char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
291 _M_negative_sign = "()";
293 _M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
296 _M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
297 _M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
298 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
299 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
300 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
301 _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn);
302 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
303 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
304 _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
309 moneypunct<char, true>::~moneypunct()
313 moneypunct<char, false>::~moneypunct()
316 #ifdef _GLIBCPP_USE_WCHAR_T
319 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
320 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
329 _M_decimal_point = L'.';
330 _M_thousands_sep = L',';
332 _M_curr_symbol = L"";
333 _M_positive_sign = L"";
334 _M_negative_sign = L"";
336 _M_pos_format = money_base::_S_default_pattern;
337 _M_neg_format = money_base::_S_default_pattern;
342 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
343 __c_locale __old = __uselocale(__cloc);
345 // Switch to named locale so that mbsrtowcs will work.
346 char* __old = strdup(setlocale(LC_ALL, NULL));
347 setlocale(LC_ALL, __name);
350 _M_decimal_point = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w);
352 _M_thousands_sep = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w);
353 _M_grouping = __nl_langinfo_l(GROUPING, __cloc);
355 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
356 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
357 const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
360 size_t __len = strlen(__cpossign);
364 memset(&__state, 0, sizeof(mbstate_t));
365 wchar_t* __wcs = new wchar_t[__len];
366 mbsrtowcs(__wcs, &__cpossign, __len, &__state);
367 _M_positive_sign = __wcs;
370 _M_positive_sign = L"";
372 char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
373 __len = strlen(__cnegsign);
375 _M_negative_sign = L"()";
379 memset(&__state, 0, sizeof(mbstate_t));
380 wchar_t* __wcs = new wchar_t[__len];
381 mbsrtowcs(__wcs, &__cnegsign, __len, &__state);
382 _M_negative_sign = __wcs;
385 _M_negative_sign = L"";
388 __len = strlen(__ccurr);
392 memset(&__state, 0, sizeof(mbstate_t));
393 wchar_t* __wcs = new wchar_t[__len];
394 mbsrtowcs(__wcs, &__ccurr, __len, &__state);
395 _M_curr_symbol = __wcs;
398 _M_curr_symbol = L"";
400 _M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, __cloc));
401 char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
402 char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
403 char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
404 _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn);
405 char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
406 char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
407 _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
409 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
412 setlocale(LC_ALL, __old);
420 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
421 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
430 _M_decimal_point = L'.';
431 _M_thousands_sep = L',';
433 _M_curr_symbol = L"";
434 _M_positive_sign = L"";
435 _M_negative_sign = L"";
437 _M_pos_format = money_base::_S_default_pattern;
438 _M_neg_format = money_base::_S_default_pattern;
443 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
444 __c_locale __old = __uselocale(__cloc);
446 // Switch to named locale so that mbsrtowcs will work.
447 char* __old = strdup(setlocale(LC_ALL, NULL));
448 setlocale(LC_ALL, __name);
451 _M_decimal_point = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w);
452 _M_thousands_sep = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w);
453 _M_grouping = __nl_langinfo_l(GROUPING, __cloc);
455 const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
456 const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
457 const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
461 __len = strlen(__cpossign);
465 memset(&__state, 0, sizeof(mbstate_t));
466 wchar_t* __wcs = new wchar_t[__len];
467 mbsrtowcs(__wcs, &__cpossign, __len, &__state);
468 _M_positive_sign = __wcs;
471 _M_positive_sign = L"";
473 char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
474 __len = strlen(__cnegsign);
476 _M_negative_sign = L"()";
480 memset(&__state, 0, sizeof(mbstate_t));
481 wchar_t* __wcs = new wchar_t[__len];
482 mbsrtowcs(__wcs, &__cnegsign, __len, &__state);
483 _M_negative_sign = __wcs;
486 _M_negative_sign = L"";
489 __len = strlen(__ccurr);
493 memset(&__state, 0, sizeof(mbstate_t));
494 wchar_t* __wcs = new wchar_t[__len];
495 mbsrtowcs(__wcs, &__ccurr, __len, &__state);
496 _M_curr_symbol = __wcs;
499 _M_curr_symbol = L"";
501 _M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
502 char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
503 char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
504 char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
505 _M_pos_format = _S_construct_pattern(__pprecedes, __pspace, __pposn);
506 char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
507 char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
508 _M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
510 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
513 setlocale(LC_ALL, __old);
520 moneypunct<wchar_t, true>::~moneypunct()
522 if (wcslen(_M_positive_sign))
523 delete [] _M_positive_sign;
524 if (wcslen(_M_negative_sign) && (wcscmp(_M_negative_sign, L"()") != 0))
525 delete [] _M_negative_sign;
526 if (wcslen(_M_curr_symbol))
527 delete [] _M_curr_symbol;
531 moneypunct<wchar_t, false>::~moneypunct()
533 if (wcslen(_M_positive_sign))
534 delete [] _M_positive_sign;
535 if (wcslen(_M_negative_sign) && (wcscmp(_M_negative_sign, L"()") != 0))
536 delete [] _M_negative_sign;
537 if (wcslen(_M_curr_symbol))
538 delete [] _M_curr_symbol;