197403Sobrien// std::moneypunct implementation details, GNU version -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 497403Sobrien// 597403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 697403Sobrien// software; you can redistribute it and/or modify it under the 797403Sobrien// terms of the GNU General Public License as published by the 897403Sobrien// Free Software Foundation; either version 2, or (at your option) 997403Sobrien// any later version. 1097403Sobrien 1197403Sobrien// This library is distributed in the hope that it will be useful, 1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1497403Sobrien// GNU General Public License for more details. 1597403Sobrien 1697403Sobrien// You should have received a copy of the GNU General Public License along 1797403Sobrien// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 1997403Sobrien// USA. 2097403Sobrien 2197403Sobrien// As a special exception, you may use this file as part of a free software 2297403Sobrien// library without restriction. Specifically, if other files instantiate 2397403Sobrien// templates or use macros or inline functions from this file, or you compile 2497403Sobrien// this file and link it with other files to produce an executable, this 2597403Sobrien// file does not by itself cause the resulting executable to be covered by 2697403Sobrien// the GNU General Public License. This exception does not however 2797403Sobrien// invalidate any other reasons why the executable file might be covered by 2897403Sobrien// the GNU General Public License. 2997403Sobrien 3097403Sobrien// 3197403Sobrien// ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions 3297403Sobrien// 3397403Sobrien 3497403Sobrien// Written by Benjamin Kosnik <bkoz@redhat.com> 3597403Sobrien 3697403Sobrien#include <locale> 37117397Skan#include <bits/c++locale_internal.h> 3897403Sobrien 39169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 40169691Skan 4197403Sobrien // Construct and return valid pattern consisting of some combination of: 4297403Sobrien // space none symbol sign value 4397403Sobrien money_base::pattern 4497403Sobrien money_base::_S_construct_pattern(char __precedes, char __space, char __posn) 4597403Sobrien { 4697403Sobrien pattern __ret; 4797403Sobrien 4897403Sobrien // This insanely complicated routine attempts to construct a valid 4997403Sobrien // pattern for use with monyepunct. A couple of invariants: 5097403Sobrien 5197403Sobrien // if (__precedes) symbol -> value 5297403Sobrien // else value -> symbol 5397403Sobrien 5497403Sobrien // if (__space) space 5597403Sobrien // else none 5697403Sobrien 5797403Sobrien // none == never first 5897403Sobrien // space never first or last 5997403Sobrien 6097403Sobrien // Any elegant implementations of this are welcome. 6197403Sobrien switch (__posn) 6297403Sobrien { 6397403Sobrien case 0: 6497403Sobrien case 1: 6597403Sobrien // 1 The sign precedes the value and symbol. 66132720Skan __ret.field[0] = sign; 6797403Sobrien if (__space) 6897403Sobrien { 6997403Sobrien // Pattern starts with sign. 7097403Sobrien if (__precedes) 7197403Sobrien { 7297403Sobrien __ret.field[1] = symbol; 7397403Sobrien __ret.field[3] = value; 7497403Sobrien } 7597403Sobrien else 7697403Sobrien { 7797403Sobrien __ret.field[1] = value; 7897403Sobrien __ret.field[3] = symbol; 7997403Sobrien } 80132720Skan __ret.field[2] = space; 8197403Sobrien } 8297403Sobrien else 8397403Sobrien { 8497403Sobrien // Pattern starts with sign and ends with none. 8597403Sobrien if (__precedes) 8697403Sobrien { 8797403Sobrien __ret.field[1] = symbol; 8897403Sobrien __ret.field[2] = value; 8997403Sobrien } 9097403Sobrien else 9197403Sobrien { 9297403Sobrien __ret.field[1] = value; 9397403Sobrien __ret.field[2] = symbol; 9497403Sobrien } 9597403Sobrien __ret.field[3] = none; 9697403Sobrien } 9797403Sobrien break; 9897403Sobrien case 2: 9997403Sobrien // 2 The sign follows the value and symbol. 10097403Sobrien if (__space) 10197403Sobrien { 10297403Sobrien // Pattern either ends with sign. 10397403Sobrien if (__precedes) 10497403Sobrien { 10597403Sobrien __ret.field[0] = symbol; 10697403Sobrien __ret.field[2] = value; 10797403Sobrien } 10897403Sobrien else 10997403Sobrien { 11097403Sobrien __ret.field[0] = value; 11197403Sobrien __ret.field[2] = symbol; 11297403Sobrien } 113132720Skan __ret.field[1] = space; 11497403Sobrien __ret.field[3] = sign; 11597403Sobrien } 11697403Sobrien else 11797403Sobrien { 11897403Sobrien // Pattern ends with sign then none. 11997403Sobrien if (__precedes) 12097403Sobrien { 12197403Sobrien __ret.field[0] = symbol; 12297403Sobrien __ret.field[1] = value; 12397403Sobrien } 12497403Sobrien else 12597403Sobrien { 12697403Sobrien __ret.field[0] = value; 12797403Sobrien __ret.field[1] = symbol; 12897403Sobrien } 12997403Sobrien __ret.field[2] = sign; 13097403Sobrien __ret.field[3] = none; 13197403Sobrien } 13297403Sobrien break; 13397403Sobrien case 3: 13497403Sobrien // 3 The sign immediately precedes the symbol. 135132720Skan if (__precedes) 13697403Sobrien { 137132720Skan __ret.field[0] = sign; 138132720Skan __ret.field[1] = symbol; 139132720Skan if (__space) 14097403Sobrien { 14197403Sobrien __ret.field[2] = space; 14297403Sobrien __ret.field[3] = value; 14397403Sobrien } 14497403Sobrien else 14597403Sobrien { 146132720Skan __ret.field[2] = value; 147132720Skan __ret.field[3] = none; 14897403Sobrien } 14997403Sobrien } 15097403Sobrien else 15197403Sobrien { 152132720Skan __ret.field[0] = value; 153132720Skan if (__space) 15497403Sobrien { 155132720Skan __ret.field[1] = space; 156132720Skan __ret.field[2] = sign; 157132720Skan __ret.field[3] = symbol; 15897403Sobrien } 15997403Sobrien else 16097403Sobrien { 16197403Sobrien __ret.field[1] = sign; 16297403Sobrien __ret.field[2] = symbol; 163132720Skan __ret.field[3] = none; 16497403Sobrien } 16597403Sobrien } 16697403Sobrien break; 16797403Sobrien case 4: 168132720Skan // 4 The sign immediately follows the symbol. 169132720Skan if (__precedes) 17097403Sobrien { 171132720Skan __ret.field[0] = symbol; 172132720Skan __ret.field[1] = sign; 173132720Skan if (__space) 17497403Sobrien { 17597403Sobrien __ret.field[2] = space; 17697403Sobrien __ret.field[3] = value; 17797403Sobrien } 17897403Sobrien else 17997403Sobrien { 180132720Skan __ret.field[2] = value; 181132720Skan __ret.field[3] = none; 18297403Sobrien } 18397403Sobrien } 18497403Sobrien else 18597403Sobrien { 186132720Skan __ret.field[0] = value; 187132720Skan if (__space) 18897403Sobrien { 189132720Skan __ret.field[1] = space; 190132720Skan __ret.field[2] = symbol; 191132720Skan __ret.field[3] = sign; 19297403Sobrien } 19397403Sobrien else 19497403Sobrien { 19597403Sobrien __ret.field[1] = symbol; 19697403Sobrien __ret.field[2] = sign; 197132720Skan __ret.field[3] = none; 19897403Sobrien } 19997403Sobrien } 20097403Sobrien break; 20197403Sobrien default: 202146897Skan __ret = pattern(); 20397403Sobrien } 20497403Sobrien return __ret; 20597403Sobrien } 20697403Sobrien 20797403Sobrien template<> 20897403Sobrien void 209102782Skan moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc, 210102782Skan const char*) 21197403Sobrien { 212132720Skan if (!_M_data) 213132720Skan _M_data = new __moneypunct_cache<char, true>; 214132720Skan 215107606Sobrien if (!__cloc) 21697403Sobrien { 21797403Sobrien // "C" locale 218132720Skan _M_data->_M_decimal_point = '.'; 219132720Skan _M_data->_M_thousands_sep = ','; 220132720Skan _M_data->_M_grouping = ""; 221132720Skan _M_data->_M_grouping_size = 0; 222132720Skan _M_data->_M_curr_symbol = ""; 223132720Skan _M_data->_M_curr_symbol_size = 0; 224132720Skan _M_data->_M_positive_sign = ""; 225132720Skan _M_data->_M_positive_sign_size = 0; 226132720Skan _M_data->_M_negative_sign = ""; 227132720Skan _M_data->_M_negative_sign_size = 0; 228132720Skan _M_data->_M_frac_digits = 0; 229132720Skan _M_data->_M_pos_format = money_base::_S_default_pattern; 230132720Skan _M_data->_M_neg_format = money_base::_S_default_pattern; 231132720Skan 232132720Skan for (size_t __i = 0; __i < money_base::_S_end; ++__i) 233132720Skan _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; 23497403Sobrien } 23597403Sobrien else 23697403Sobrien { 23797403Sobrien // Named locale. 238132720Skan _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, 239132720Skan __cloc)); 240132720Skan _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, 241132720Skan __cloc)); 242132720Skan _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 243132720Skan _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 244132720Skan _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 245132720Skan _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign); 24697403Sobrien 24797403Sobrien char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); 24897403Sobrien if (!__nposn) 249132720Skan _M_data->_M_negative_sign = "()"; 25097403Sobrien else 251132720Skan _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, 252132720Skan __cloc); 253132720Skan _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign); 25497403Sobrien 25597403Sobrien // _Intl == true 256132720Skan _M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); 257132720Skan _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol); 258132720Skan _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, 259132720Skan __cloc)); 26097403Sobrien char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); 26197403Sobrien char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); 26297403Sobrien char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); 263132720Skan _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 264132720Skan __pposn); 26597403Sobrien char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); 26697403Sobrien char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); 267132720Skan _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 268132720Skan __nposn); 26997403Sobrien } 27097403Sobrien } 27197403Sobrien 27297403Sobrien template<> 27397403Sobrien void 274102782Skan moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc, 275102782Skan const char*) 27697403Sobrien { 277132720Skan if (!_M_data) 278132720Skan _M_data = new __moneypunct_cache<char, false>; 279132720Skan 280107606Sobrien if (!__cloc) 28197403Sobrien { 28297403Sobrien // "C" locale 283132720Skan _M_data->_M_decimal_point = '.'; 284132720Skan _M_data->_M_thousands_sep = ','; 285132720Skan _M_data->_M_grouping = ""; 286132720Skan _M_data->_M_grouping_size = 0; 287132720Skan _M_data->_M_curr_symbol = ""; 288132720Skan _M_data->_M_curr_symbol_size = 0; 289132720Skan _M_data->_M_positive_sign = ""; 290132720Skan _M_data->_M_positive_sign_size = 0; 291132720Skan _M_data->_M_negative_sign = ""; 292132720Skan _M_data->_M_negative_sign_size = 0; 293132720Skan _M_data->_M_frac_digits = 0; 294132720Skan _M_data->_M_pos_format = money_base::_S_default_pattern; 295132720Skan _M_data->_M_neg_format = money_base::_S_default_pattern; 296132720Skan 297132720Skan for (size_t __i = 0; __i < money_base::_S_end; ++__i) 298132720Skan _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; 29997403Sobrien } 30097403Sobrien else 30197403Sobrien { 30297403Sobrien // Named locale. 303132720Skan _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, 304132720Skan __cloc)); 305132720Skan _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, 306132720Skan __cloc)); 307132720Skan _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 308132720Skan _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 309132720Skan _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 310132720Skan _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign); 31197403Sobrien 31297403Sobrien char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); 31397403Sobrien if (!__nposn) 314132720Skan _M_data->_M_negative_sign = "()"; 31597403Sobrien else 316132720Skan _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, 317132720Skan __cloc); 318132720Skan _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign); 31997403Sobrien 32097403Sobrien // _Intl == false 321132720Skan _M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); 322132720Skan _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol); 323132720Skan _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); 32497403Sobrien char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); 32597403Sobrien char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); 32697403Sobrien char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); 327132720Skan _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 328132720Skan __pposn); 32997403Sobrien char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); 33097403Sobrien char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); 331132720Skan _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 332132720Skan __nposn); 33397403Sobrien } 33497403Sobrien } 33597403Sobrien 33697403Sobrien template<> 33797403Sobrien moneypunct<char, true>::~moneypunct() 338132720Skan { delete _M_data; } 33997403Sobrien 34097403Sobrien template<> 34197403Sobrien moneypunct<char, false>::~moneypunct() 342132720Skan { delete _M_data; } 34397403Sobrien 344132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 34597403Sobrien template<> 34697403Sobrien void 347102782Skan moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc, 348117397Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 349117397Skan const char*) 350117397Skan#else 351102782Skan const char* __name) 352117397Skan#endif 35397403Sobrien { 354132720Skan if (!_M_data) 355132720Skan _M_data = new __moneypunct_cache<wchar_t, true>; 356132720Skan 357107606Sobrien if (!__cloc) 35897403Sobrien { 35997403Sobrien // "C" locale 360132720Skan _M_data->_M_decimal_point = L'.'; 361132720Skan _M_data->_M_thousands_sep = L','; 362132720Skan _M_data->_M_grouping = ""; 363132720Skan _M_data->_M_grouping_size = 0; 364132720Skan _M_data->_M_curr_symbol = L""; 365132720Skan _M_data->_M_curr_symbol_size = 0; 366132720Skan _M_data->_M_positive_sign = L""; 367132720Skan _M_data->_M_positive_sign_size = 0; 368132720Skan _M_data->_M_negative_sign = L""; 369132720Skan _M_data->_M_negative_sign_size = 0; 370132720Skan _M_data->_M_frac_digits = 0; 371132720Skan _M_data->_M_pos_format = money_base::_S_default_pattern; 372132720Skan _M_data->_M_neg_format = money_base::_S_default_pattern; 373132720Skan 374132720Skan // Use ctype::widen code without the facet... 375132720Skan for (size_t __i = 0; __i < money_base::_S_end; ++__i) 376169691Skan _M_data->_M_atoms[__i] = 377169691Skan static_cast<wchar_t>(money_base::_S_atoms[__i]); 37897403Sobrien } 37997403Sobrien else 38097403Sobrien { 38197403Sobrien // Named locale. 382103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 383103447Skan __c_locale __old = __uselocale(__cloc); 384103447Skan#else 385103447Skan // Switch to named locale so that mbsrtowcs will work. 386102782Skan char* __old = strdup(setlocale(LC_ALL, NULL)); 387102782Skan setlocale(LC_ALL, __name); 388103447Skan#endif 389102782Skan 390169691Skan union { char *__s; wchar_t __w; } __u; 391132720Skan __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc); 392169691Skan _M_data->_M_decimal_point = __u.__w; 39397403Sobrien 394132720Skan __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc); 395169691Skan _M_data->_M_thousands_sep = __u.__w; 396132720Skan _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 397132720Skan _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 39897403Sobrien 39997403Sobrien const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 40097403Sobrien const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); 40197403Sobrien const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); 40297403Sobrien 403132720Skan wchar_t* __wcs_ps = 0; 404132720Skan wchar_t* __wcs_ns = 0; 405132720Skan const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); 406132720Skan try 40797403Sobrien { 408132720Skan mbstate_t __state; 409132720Skan size_t __len = strlen(__cpossign); 410132720Skan if (__len) 411132720Skan { 412132720Skan ++__len; 413132720Skan memset(&__state, 0, sizeof(mbstate_t)); 414132720Skan __wcs_ps = new wchar_t[__len]; 415132720Skan mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state); 416132720Skan _M_data->_M_positive_sign = __wcs_ps; 417132720Skan } 418132720Skan else 419132720Skan _M_data->_M_positive_sign = L""; 420132720Skan _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign); 421132720Skan 422132720Skan __len = strlen(__cnegsign); 423132720Skan if (!__nposn) 424132720Skan _M_data->_M_negative_sign = L"()"; 425132720Skan else if (__len) 426132720Skan { 427132720Skan ++__len; 428132720Skan memset(&__state, 0, sizeof(mbstate_t)); 429132720Skan __wcs_ns = new wchar_t[__len]; 430132720Skan mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state); 431132720Skan _M_data->_M_negative_sign = __wcs_ns; 432132720Skan } 433132720Skan else 434132720Skan _M_data->_M_negative_sign = L""; 435132720Skan _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign); 436132720Skan 437132720Skan // _Intl == true. 438132720Skan __len = strlen(__ccurr); 439132720Skan if (__len) 440132720Skan { 441132720Skan ++__len; 442132720Skan memset(&__state, 0, sizeof(mbstate_t)); 443132720Skan wchar_t* __wcs = new wchar_t[__len]; 444132720Skan mbsrtowcs(__wcs, &__ccurr, __len, &__state); 445132720Skan _M_data->_M_curr_symbol = __wcs; 446132720Skan } 447132720Skan else 448132720Skan _M_data->_M_curr_symbol = L""; 449132720Skan _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); 45097403Sobrien } 451132720Skan catch (...) 45297403Sobrien { 453132720Skan delete _M_data; 454132720Skan _M_data = 0; 455132720Skan delete __wcs_ps; 456132720Skan delete __wcs_ns; 457132720Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 458132720Skan __uselocale(__old); 459132720Skan#else 460132720Skan setlocale(LC_ALL, __old); 461132720Skan free(__old); 462132720Skan#endif 463132720Skan __throw_exception_again; 464132720Skan } 465132720Skan 466132720Skan _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, 467132720Skan __cloc)); 46897403Sobrien char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); 46997403Sobrien char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); 47097403Sobrien char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); 471132720Skan _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 472132720Skan __pposn); 47397403Sobrien char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); 47497403Sobrien char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); 475132720Skan _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 476132720Skan __nposn); 477102782Skan 478103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 479103447Skan __uselocale(__old); 480103447Skan#else 481102782Skan setlocale(LC_ALL, __old); 482102782Skan free(__old); 483103447Skan#endif 48497403Sobrien } 48597403Sobrien } 48697403Sobrien 48797403Sobrien template<> 488132720Skan void 489132720Skan moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc, 490132720Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 491132720Skan const char*) 492117397Skan#else 493132720Skan const char* __name) 494117397Skan#endif 495132720Skan { 496132720Skan if (!_M_data) 497132720Skan _M_data = new __moneypunct_cache<wchar_t, false>; 498132720Skan 499132720Skan if (!__cloc) 50097403Sobrien { 50197403Sobrien // "C" locale 502132720Skan _M_data->_M_decimal_point = L'.'; 503132720Skan _M_data->_M_thousands_sep = L','; 504132720Skan _M_data->_M_grouping = ""; 505132720Skan _M_data->_M_grouping_size = 0; 506132720Skan _M_data->_M_curr_symbol = L""; 507132720Skan _M_data->_M_curr_symbol_size = 0; 508132720Skan _M_data->_M_positive_sign = L""; 509132720Skan _M_data->_M_positive_sign_size = 0; 510132720Skan _M_data->_M_negative_sign = L""; 511132720Skan _M_data->_M_negative_sign_size = 0; 512132720Skan _M_data->_M_frac_digits = 0; 513132720Skan _M_data->_M_pos_format = money_base::_S_default_pattern; 514132720Skan _M_data->_M_neg_format = money_base::_S_default_pattern; 515132720Skan 516132720Skan // Use ctype::widen code without the facet... 517132720Skan for (size_t __i = 0; __i < money_base::_S_end; ++__i) 518169691Skan _M_data->_M_atoms[__i] = 519169691Skan static_cast<wchar_t>(money_base::_S_atoms[__i]); 52097403Sobrien } 52197403Sobrien else 52297403Sobrien { 52397403Sobrien // Named locale. 524103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 525103447Skan __c_locale __old = __uselocale(__cloc); 526103447Skan#else 527103447Skan // Switch to named locale so that mbsrtowcs will work. 528102782Skan char* __old = strdup(setlocale(LC_ALL, NULL)); 529102782Skan setlocale(LC_ALL, __name); 530103447Skan#endif 531102782Skan 532169691Skan union { char *__s; wchar_t __w; } __u; 533132720Skan __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc); 534169691Skan _M_data->_M_decimal_point = __u.__w; 53597403Sobrien 536132720Skan __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc); 537169691Skan _M_data->_M_thousands_sep = __u.__w; 538132720Skan _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); 539132720Skan _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); 540132720Skan 54197403Sobrien const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); 54297403Sobrien const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); 54397403Sobrien const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); 54497403Sobrien 545132720Skan wchar_t* __wcs_ps = 0; 546132720Skan wchar_t* __wcs_ns = 0; 547132720Skan const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); 548132720Skan try 549132720Skan { 550132720Skan mbstate_t __state; 551132720Skan size_t __len; 552132720Skan __len = strlen(__cpossign); 553132720Skan if (__len) 554132720Skan { 555132720Skan ++__len; 556132720Skan memset(&__state, 0, sizeof(mbstate_t)); 557132720Skan __wcs_ps = new wchar_t[__len]; 558132720Skan mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state); 559132720Skan _M_data->_M_positive_sign = __wcs_ps; 560132720Skan } 561132720Skan else 562132720Skan _M_data->_M_positive_sign = L""; 563132720Skan _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign); 564132720Skan 565132720Skan __len = strlen(__cnegsign); 566132720Skan if (!__nposn) 567132720Skan _M_data->_M_negative_sign = L"()"; 568132720Skan else if (__len) 569132720Skan { 570132720Skan ++__len; 571132720Skan memset(&__state, 0, sizeof(mbstate_t)); 572132720Skan __wcs_ns = new wchar_t[__len]; 573132720Skan mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state); 574132720Skan _M_data->_M_negative_sign = __wcs_ns; 575132720Skan } 576132720Skan else 577132720Skan _M_data->_M_negative_sign = L""; 578132720Skan _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign); 57997403Sobrien 580132720Skan // _Intl == true. 581132720Skan __len = strlen(__ccurr); 582132720Skan if (__len) 583132720Skan { 584132720Skan ++__len; 585132720Skan memset(&__state, 0, sizeof(mbstate_t)); 586132720Skan wchar_t* __wcs = new wchar_t[__len]; 587132720Skan mbsrtowcs(__wcs, &__ccurr, __len, &__state); 588132720Skan _M_data->_M_curr_symbol = __wcs; 589132720Skan } 590132720Skan else 591132720Skan _M_data->_M_curr_symbol = L""; 592132720Skan _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); 59397403Sobrien } 594132720Skan catch (...) 59597403Sobrien { 596132720Skan delete _M_data; 597132720Skan _M_data = 0; 598132720Skan delete __wcs_ps; 599132720Skan delete __wcs_ns; 600132720Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 601132720Skan __uselocale(__old); 602132720Skan#else 603132720Skan setlocale(LC_ALL, __old); 604132720Skan free(__old); 605132720Skan#endif 606132720Skan __throw_exception_again; 60797403Sobrien } 60897403Sobrien 609132720Skan _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); 61097403Sobrien char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); 61197403Sobrien char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); 61297403Sobrien char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); 613132720Skan _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 614132720Skan __pposn); 61597403Sobrien char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); 61697403Sobrien char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); 617132720Skan _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 618132720Skan __nposn); 619102782Skan 620103447Skan#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) 621103447Skan __uselocale(__old); 622103447Skan#else 623102782Skan setlocale(LC_ALL, __old); 624102782Skan free(__old); 625103447Skan#endif 62697403Sobrien } 62797403Sobrien } 62897403Sobrien 62997403Sobrien template<> 63097403Sobrien moneypunct<wchar_t, true>::~moneypunct() 63197403Sobrien { 632132720Skan if (_M_data->_M_positive_sign_size) 633132720Skan delete [] _M_data->_M_positive_sign; 634132720Skan if (_M_data->_M_negative_sign_size 635132720Skan && wcscmp(_M_data->_M_negative_sign, L"()") != 0) 636132720Skan delete [] _M_data->_M_negative_sign; 637132720Skan if (_M_data->_M_curr_symbol_size) 638132720Skan delete [] _M_data->_M_curr_symbol; 639132720Skan delete _M_data; 64097403Sobrien } 64197403Sobrien 64297403Sobrien template<> 64397403Sobrien moneypunct<wchar_t, false>::~moneypunct() 64497403Sobrien { 645132720Skan if (_M_data->_M_positive_sign_size) 646132720Skan delete [] _M_data->_M_positive_sign; 647132720Skan if (_M_data->_M_negative_sign_size 648132720Skan && wcscmp(_M_data->_M_negative_sign, L"()") != 0) 649132720Skan delete [] _M_data->_M_negative_sign; 650132720Skan if (_M_data->_M_curr_symbol_size) 651132720Skan delete [] _M_data->_M_curr_symbol; 652132720Skan delete _M_data; 65397403Sobrien } 65497403Sobrien#endif 655169691Skan 656169691Skan_GLIBCXX_END_NAMESPACE 657