1 // std::moneypunct implementation details, DragonFly version -*- C++ -*- 2 3 // Copyright (C) 2015-2022 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 // 26 // ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions 27 // 28 29 // Written by Benjamin Kosnik <bkoz@redhat.com> 30 // Modified for DragonFly by John Marino <gnugcc@marino.st> 31 32 #include <locale> 33 #include <cstring> 34 35 #include "xlocale_port.h" 36 37 namespace std _GLIBCXX_VISIBILITY(default) 38 { 39 _GLIBCXX_BEGIN_NAMESPACE_VERSION 40 41 // This file might be compiled twice, but we only want to define the members 42 // of money_base once. 43 #if ! _GLIBCXX_USE_CXX11_ABI 44 45 // Construct and return valid pattern consisting of some combination of: 46 // space none symbol sign value 47 money_base::pattern 48 money_base::_S_construct_pattern(char __precedes, char __space, 49 char __posn) throw() 50 { 51 pattern __ret; 52 53 // This insanely complicated routine attempts to construct a valid 54 // pattern for use with moneypunct. A couple of invariants: 55 56 // if (__precedes) symbol -> value 57 // else value -> symbol 58 59 // if (__space) space 60 // else none 61 62 // none == never first 63 // space never first or last 64 65 // Any elegant implementations of this are welcome. 66 switch (__posn) 67 { 68 case 0: 69 case 1: 70 // 1 The sign precedes the value and symbol. 71 __ret.field[0] = sign; 72 if (__space) 73 { 74 // Pattern starts with sign. 75 if (__precedes) 76 { 77 __ret.field[1] = symbol; 78 __ret.field[3] = value; 79 } 80 else 81 { 82 __ret.field[1] = value; 83 __ret.field[3] = symbol; 84 } 85 __ret.field[2] = space; 86 } 87 else 88 { 89 // Pattern starts with sign and ends with none. 90 if (__precedes) 91 { 92 __ret.field[1] = symbol; 93 __ret.field[2] = value; 94 } 95 else 96 { 97 __ret.field[1] = value; 98 __ret.field[2] = symbol; 99 } 100 __ret.field[3] = none; 101 } 102 break; 103 case 2: 104 // 2 The sign follows the value and symbol. 105 if (__space) 106 { 107 // Pattern either ends with sign. 108 if (__precedes) 109 { 110 __ret.field[0] = symbol; 111 __ret.field[2] = value; 112 } 113 else 114 { 115 __ret.field[0] = value; 116 __ret.field[2] = symbol; 117 } 118 __ret.field[1] = space; 119 __ret.field[3] = sign; 120 } 121 else 122 { 123 // Pattern ends with sign then none. 124 if (__precedes) 125 { 126 __ret.field[0] = symbol; 127 __ret.field[1] = value; 128 } 129 else 130 { 131 __ret.field[0] = value; 132 __ret.field[1] = symbol; 133 } 134 __ret.field[2] = sign; 135 __ret.field[3] = none; 136 } 137 break; 138 case 3: 139 // 3 The sign immediately precedes the symbol. 140 if (__precedes) 141 { 142 __ret.field[0] = sign; 143 __ret.field[1] = symbol; 144 if (__space) 145 { 146 __ret.field[2] = space; 147 __ret.field[3] = value; 148 } 149 else 150 { 151 __ret.field[2] = value; 152 __ret.field[3] = none; 153 } 154 } 155 else 156 { 157 __ret.field[0] = value; 158 if (__space) 159 { 160 __ret.field[1] = space; 161 __ret.field[2] = sign; 162 __ret.field[3] = symbol; 163 } 164 else 165 { 166 __ret.field[1] = sign; 167 __ret.field[2] = symbol; 168 __ret.field[3] = none; 169 } 170 } 171 break; 172 case 4: 173 // 4 The sign immediately follows the symbol. 174 if (__precedes) 175 { 176 __ret.field[0] = symbol; 177 __ret.field[1] = sign; 178 if (__space) 179 { 180 __ret.field[2] = space; 181 __ret.field[3] = value; 182 } 183 else 184 { 185 __ret.field[2] = value; 186 __ret.field[3] = none; 187 } 188 } 189 else 190 { 191 __ret.field[0] = value; 192 if (__space) 193 { 194 __ret.field[1] = space; 195 __ret.field[2] = symbol; 196 __ret.field[3] = sign; 197 } 198 else 199 { 200 __ret.field[1] = symbol; 201 __ret.field[2] = sign; 202 __ret.field[3] = none; 203 } 204 } 205 break; 206 default: 207 __ret = pattern(); 208 } 209 return __ret; 210 } 211 #endif 212 213 template<> 214 void 215 moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc, 216 const char*) 217 { 218 if (!_M_data) 219 _M_data = new __moneypunct_cache<char, true>; 220 221 if (!__cloc) 222 { 223 // "C" locale 224 _M_data->_M_decimal_point = '.'; 225 _M_data->_M_thousands_sep = ','; 226 _M_data->_M_grouping = ""; 227 _M_data->_M_grouping_size = 0; 228 _M_data->_M_use_grouping = false; 229 _M_data->_M_curr_symbol = ""; 230 _M_data->_M_curr_symbol_size = 0; 231 _M_data->_M_positive_sign = ""; 232 _M_data->_M_positive_sign_size = 0; 233 _M_data->_M_negative_sign = ""; 234 _M_data->_M_negative_sign_size = 0; 235 _M_data->_M_frac_digits = 0; 236 _M_data->_M_pos_format = money_base::_S_default_pattern; 237 _M_data->_M_neg_format = money_base::_S_default_pattern; 238 239 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 240 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; 241 } 242 else 243 { 244 // Named locale. 245 lconv* lc = localeconv_l((locale_t) __cloc); 246 247 // Check for NULL, which implies no fractional digits. 248 if (lc->mon_decimal_point == NULL || 249 lc->mon_decimal_point[0] == '\0') 250 { 251 // Like in "C" locale. 252 _M_data->_M_frac_digits = 0; 253 _M_data->_M_decimal_point = '.'; 254 } 255 else 256 { 257 _M_data->_M_decimal_point = lc->mon_decimal_point[0]; 258 _M_data->_M_frac_digits = lc->int_frac_digits; 259 } 260 261 const char* __cgroup = lc->mon_grouping; 262 const char* __cpossign = lc->positive_sign; 263 const char* __cnegsign = lc->negative_sign; 264 // _Intl == true 265 const char* __ccurr = lc->int_curr_symbol; 266 267 char* __group = 0; 268 char* __ps = 0; 269 char* __ns = 0; 270 const char __nposn = lc->int_n_sign_posn; 271 __try 272 { 273 size_t __len; 274 275 // Check for NULL, which implies no grouping. 276 if (lc->mon_thousands_sep == NULL || 277 lc->mon_thousands_sep[0] == '\0') 278 { 279 // Like in "C" locale. 280 _M_data->_M_grouping = ""; 281 _M_data->_M_grouping_size = 0; 282 _M_data->_M_use_grouping = false; 283 _M_data->_M_thousands_sep = ','; 284 } 285 else 286 { 287 _M_data->_M_thousands_sep = lc->mon_thousands_sep[0]; 288 289 __len = strlen(__cgroup); 290 if (__len) 291 { 292 __group = new char[__len + 1]; 293 memcpy(__group, __cgroup, __len + 1); 294 _M_data->_M_grouping = __group; 295 } 296 else 297 { 298 _M_data->_M_grouping = ""; 299 _M_data->_M_use_grouping = false; 300 } 301 _M_data->_M_grouping_size = __len; 302 } 303 304 __len = strlen(__cpossign); 305 if (__len) 306 { 307 __ps = new char[__len + 1]; 308 memcpy(__ps, __cpossign, __len + 1); 309 _M_data->_M_positive_sign = __ps; 310 } 311 else 312 _M_data->_M_positive_sign = ""; 313 _M_data->_M_positive_sign_size = __len; 314 315 if (!__nposn) 316 { 317 _M_data->_M_negative_sign = "()"; 318 _M_data->_M_negative_sign_size = 2; 319 } 320 else 321 { 322 __len = strlen(__cnegsign); 323 if (__len) 324 { 325 __ns = new char[__len + 1]; 326 memcpy(__ns, __cnegsign, __len + 1); 327 _M_data->_M_negative_sign = __ns; 328 } 329 else 330 _M_data->_M_negative_sign = ""; 331 _M_data->_M_negative_sign_size = __len; 332 } 333 334 __len = strlen(__ccurr); 335 if (__len) 336 { 337 char* __curr = new char[__len + 1]; 338 memcpy(__curr, __ccurr, __len + 1); 339 _M_data->_M_curr_symbol = __curr; 340 } 341 else 342 _M_data->_M_curr_symbol = ""; 343 _M_data->_M_curr_symbol_size = __len; 344 } 345 __catch(...) 346 { 347 delete _M_data; 348 _M_data = 0; 349 delete [] __group; 350 delete [] __ps; 351 delete [] __ns; 352 __throw_exception_again; 353 } 354 355 char __pprecedes = lc->int_p_cs_precedes; 356 char __pspace = lc->int_p_sep_by_space; 357 char __pposn = lc->int_p_sign_posn; 358 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 359 __pposn); 360 char __nprecedes = lc->int_n_cs_precedes; 361 char __nspace = lc->int_n_sep_by_space; 362 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 363 __nposn); 364 } 365 } 366 367 template<> 368 void 369 moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc, 370 const char*) 371 { 372 if (!_M_data) 373 _M_data = new __moneypunct_cache<char, false>; 374 375 if (!__cloc) 376 { 377 // "C" locale 378 _M_data->_M_decimal_point = '.'; 379 _M_data->_M_thousands_sep = ','; 380 _M_data->_M_grouping = ""; 381 _M_data->_M_grouping_size = 0; 382 _M_data->_M_use_grouping = false; 383 _M_data->_M_curr_symbol = ""; 384 _M_data->_M_curr_symbol_size = 0; 385 _M_data->_M_positive_sign = ""; 386 _M_data->_M_positive_sign_size = 0; 387 _M_data->_M_negative_sign = ""; 388 _M_data->_M_negative_sign_size = 0; 389 _M_data->_M_frac_digits = 0; 390 _M_data->_M_pos_format = money_base::_S_default_pattern; 391 _M_data->_M_neg_format = money_base::_S_default_pattern; 392 393 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 394 _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; 395 } 396 else 397 { 398 // Named locale. 399 lconv* lc = localeconv_l((locale_t) __cloc); 400 401 // Check for NULL, which implies no fractional digits. 402 if (lc->mon_decimal_point == NULL || 403 lc->mon_decimal_point[0] == '\0') 404 { 405 // Like in "C" locale. 406 _M_data->_M_frac_digits = 0; 407 _M_data->_M_decimal_point = '.'; 408 } 409 else 410 { 411 _M_data->_M_decimal_point = lc->mon_decimal_point[0]; 412 _M_data->_M_frac_digits = lc->frac_digits; 413 } 414 415 const char* __cgroup = lc->mon_grouping; 416 const char* __cpossign = lc->positive_sign; 417 const char* __cnegsign = lc->negative_sign; 418 // _Intl == false 419 const char* __ccurr = lc->currency_symbol; 420 421 char* __group = 0; 422 char* __ps = 0; 423 char* __ns = 0; 424 const char __nposn = lc->n_sign_posn; 425 __try 426 { 427 size_t __len; 428 429 // Check for NULL, which implies no grouping. 430 if (lc->mon_thousands_sep == NULL || 431 lc->mon_thousands_sep[0] == '\0') 432 { 433 // Like in "C" locale. 434 _M_data->_M_grouping = ""; 435 _M_data->_M_grouping_size = 0; 436 _M_data->_M_use_grouping = false; 437 _M_data->_M_thousands_sep = ','; 438 } 439 else 440 { 441 _M_data->_M_thousands_sep = lc->mon_thousands_sep[0]; 442 443 __len = strlen(__cgroup); 444 if (__len) 445 { 446 __group = new char[__len + 1]; 447 memcpy(__group, __cgroup, __len + 1); 448 _M_data->_M_grouping = __group; 449 } 450 else 451 { 452 _M_data->_M_grouping = ""; 453 _M_data->_M_use_grouping = false; 454 } 455 _M_data->_M_grouping_size = __len; 456 } 457 458 __len = strlen(__cpossign); 459 if (__len) 460 { 461 __ps = new char[__len + 1]; 462 memcpy(__ps, __cpossign, __len + 1); 463 _M_data->_M_positive_sign = __ps; 464 } 465 else 466 _M_data->_M_positive_sign = ""; 467 _M_data->_M_positive_sign_size = __len; 468 469 if (!__nposn) 470 { 471 _M_data->_M_negative_sign = "()"; 472 _M_data->_M_negative_sign_size = 2; 473 } 474 else 475 { 476 __len = strlen(__cnegsign); 477 if (__len) 478 { 479 __ns = new char[__len + 1]; 480 memcpy(__ns, __cnegsign, __len + 1); 481 _M_data->_M_negative_sign = __ns; 482 } 483 else 484 _M_data->_M_negative_sign = ""; 485 _M_data->_M_negative_sign_size = __len; 486 } 487 488 __len = strlen(__ccurr); 489 if (__len) 490 { 491 char* __curr = new char[__len + 1]; 492 memcpy(__curr, __ccurr, __len + 1); 493 _M_data->_M_curr_symbol = __curr; 494 } 495 else 496 _M_data->_M_curr_symbol = ""; 497 _M_data->_M_curr_symbol_size = __len; 498 } 499 __catch(...) 500 { 501 delete _M_data; 502 _M_data = 0; 503 delete [] __group; 504 delete [] __ps; 505 delete [] __ns; 506 __throw_exception_again; 507 } 508 509 char __pprecedes = lc->p_cs_precedes; 510 char __pspace = lc->p_sep_by_space; 511 char __pposn = lc->p_sign_posn; 512 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 513 __pposn); 514 char __nprecedes = lc->n_cs_precedes; 515 char __nspace = lc->n_sep_by_space; 516 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 517 __nposn); 518 } 519 } 520 521 template<> 522 moneypunct<char, true>::~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 template<> 537 moneypunct<char, false>::~moneypunct() 538 { 539 if (_M_data->_M_grouping_size) 540 delete [] _M_data->_M_grouping; 541 if (_M_data->_M_positive_sign_size) 542 delete [] _M_data->_M_positive_sign; 543 if (_M_data->_M_negative_sign_size 544 && strcmp(_M_data->_M_negative_sign, "()") != 0) 545 delete [] _M_data->_M_negative_sign; 546 if (_M_data->_M_curr_symbol_size) 547 delete [] _M_data->_M_curr_symbol; 548 delete _M_data; 549 } 550 551 #ifdef _GLIBCXX_USE_WCHAR_T 552 template<> 553 void 554 moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc, 555 const char*) 556 { 557 if (!_M_data) 558 _M_data = new __moneypunct_cache<wchar_t, true>; 559 560 if (!__cloc) 561 { 562 // "C" locale 563 _M_data->_M_decimal_point = L'.'; 564 _M_data->_M_thousands_sep = L','; 565 _M_data->_M_grouping = ""; 566 _M_data->_M_grouping_size = 0; 567 _M_data->_M_use_grouping = false; 568 _M_data->_M_curr_symbol = L""; 569 _M_data->_M_curr_symbol_size = 0; 570 _M_data->_M_positive_sign = L""; 571 _M_data->_M_positive_sign_size = 0; 572 _M_data->_M_negative_sign = L""; 573 _M_data->_M_negative_sign_size = 0; 574 _M_data->_M_frac_digits = 0; 575 _M_data->_M_pos_format = money_base::_S_default_pattern; 576 _M_data->_M_neg_format = money_base::_S_default_pattern; 577 578 // Use ctype::widen code without the facet... 579 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 580 _M_data->_M_atoms[__i] = 581 static_cast<wchar_t>(money_base::_S_atoms[__i]); 582 } 583 else 584 { 585 // Named locale. 586 lconv* lc = localeconv_l((locale_t) __cloc); 587 588 // Check for NULL, which implies no fractional digits. 589 if (lc->mon_decimal_point == NULL || 590 lc->mon_decimal_point[0] == '\0') 591 { 592 // Like in "C" locale. 593 _M_data->_M_frac_digits = 0; 594 _M_data->_M_decimal_point = L'.'; 595 } 596 else 597 { 598 _M_data->_M_frac_digits = lc->int_frac_digits; 599 _M_data->_M_decimal_point = (wchar_t)lc->mon_decimal_point[0]; 600 } 601 602 const char* __cgroup = lc->mon_grouping; 603 const char* __cpossign = lc->positive_sign; 604 const char* __cnegsign = lc->negative_sign; 605 const char* __ccurr = lc->int_curr_symbol; 606 607 char* __group = 0; 608 wchar_t* __wcs_ps = 0; 609 wchar_t* __wcs_ns = 0; 610 const char __nposn = lc->int_n_sign_posn; 611 __try 612 { 613 size_t __len; 614 615 // Check for NULL, which implies no grouping. 616 if (lc->mon_thousands_sep == NULL || 617 lc->mon_thousands_sep[0] == '\0') 618 { 619 // Like in "C" locale. 620 _M_data->_M_grouping = ""; 621 _M_data->_M_grouping_size = 0; 622 _M_data->_M_use_grouping = false; 623 _M_data->_M_thousands_sep = L','; 624 } 625 else 626 { 627 _M_data->_M_thousands_sep = 628 (wchar_t)lc->mon_thousands_sep[0]; 629 __len = strlen(__cgroup); 630 if (__len) 631 { 632 __group = new char[__len + 1]; 633 memcpy(__group, __cgroup, __len + 1); 634 _M_data->_M_grouping = __group; 635 } 636 else 637 { 638 _M_data->_M_grouping = ""; 639 _M_data->_M_use_grouping = false; 640 } 641 _M_data->_M_grouping_size = __len; 642 } 643 644 mbstate_t __state; 645 __len = strlen(__cpossign); 646 if (__len) 647 { 648 memset(&__state, 0, sizeof(mbstate_t)); 649 __wcs_ps = new wchar_t[__len + 1]; 650 mbsrtowcs_l(__wcs_ps, &__cpossign, __len + 1, &__state, 651 (locale_t)__cloc); 652 _M_data->_M_positive_sign = __wcs_ps; 653 } 654 else 655 _M_data->_M_positive_sign = L""; 656 _M_data->_M_positive_sign_size = 657 wcslen(_M_data->_M_positive_sign); 658 659 __len = strlen(__cnegsign); 660 if (!__nposn) 661 _M_data->_M_negative_sign = L"()"; 662 else if (__len) 663 { 664 memset(&__state, 0, sizeof(mbstate_t)); 665 __wcs_ns = new wchar_t[__len + 1]; 666 mbsrtowcs_l(__wcs_ps, &__cpossign, __len + 1, &__state, 667 (locale_t)__cloc); 668 _M_data->_M_negative_sign = __wcs_ns; 669 } 670 else 671 _M_data->_M_negative_sign = L""; 672 _M_data->_M_negative_sign_size = 673 wcslen(_M_data->_M_negative_sign); 674 675 // _Intl == true. 676 __len = strlen(__ccurr); 677 if (__len) 678 { 679 memset(&__state, 0, sizeof(mbstate_t)); 680 wchar_t* __wcs = new wchar_t[__len + 1]; 681 mbsrtowcs_l(__wcs, &__ccurr, __len + 1, &__state, 682 (locale_t)__cloc); 683 _M_data->_M_curr_symbol = __wcs; 684 } 685 else 686 _M_data->_M_curr_symbol = L""; 687 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); 688 } 689 __catch(...) 690 { 691 delete _M_data; 692 _M_data = 0; 693 delete [] __group; 694 delete [] __wcs_ps; 695 delete [] __wcs_ns; 696 __throw_exception_again; 697 } 698 699 char __pprecedes = lc->int_p_cs_precedes; 700 char __pspace = lc->int_p_sep_by_space; 701 char __pposn = lc->int_p_sign_posn; 702 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 703 __pposn); 704 char __nprecedes = lc->int_n_cs_precedes; 705 char __nspace = lc->int_n_sep_by_space; 706 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 707 __nposn); 708 } 709 } 710 711 template<> 712 void 713 moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc, 714 const char*) 715 { 716 if (!_M_data) 717 _M_data = new __moneypunct_cache<wchar_t, false>; 718 719 if (!__cloc) 720 { 721 // "C" locale 722 _M_data->_M_decimal_point = L'.'; 723 _M_data->_M_thousands_sep = L','; 724 _M_data->_M_grouping = ""; 725 _M_data->_M_grouping_size = 0; 726 _M_data->_M_use_grouping = false; 727 _M_data->_M_curr_symbol = L""; 728 _M_data->_M_curr_symbol_size = 0; 729 _M_data->_M_positive_sign = L""; 730 _M_data->_M_positive_sign_size = 0; 731 _M_data->_M_negative_sign = L""; 732 _M_data->_M_negative_sign_size = 0; 733 _M_data->_M_frac_digits = 0; 734 _M_data->_M_pos_format = money_base::_S_default_pattern; 735 _M_data->_M_neg_format = money_base::_S_default_pattern; 736 737 // Use ctype::widen code without the facet... 738 for (size_t __i = 0; __i < money_base::_S_end; ++__i) 739 _M_data->_M_atoms[__i] = 740 static_cast<wchar_t>(money_base::_S_atoms[__i]); 741 } 742 else 743 { 744 // Named locale. 745 lconv* lc = localeconv_l((locale_t) __cloc); 746 747 // Check for NULL, which implies no fractional digits. 748 if (lc->mon_decimal_point == NULL || 749 lc->mon_decimal_point[0] == '\0') 750 { 751 // Like in "C" locale. 752 _M_data->_M_frac_digits = 0; 753 _M_data->_M_decimal_point = L'.'; 754 } 755 else 756 { 757 _M_data->_M_frac_digits = lc->frac_digits; 758 _M_data->_M_decimal_point = (wchar_t)lc->mon_decimal_point[0]; 759 } 760 761 const char* __cgroup = lc->mon_grouping; 762 const char* __cpossign = lc->positive_sign; 763 const char* __cnegsign = lc->negative_sign; 764 const char* __ccurr = lc->currency_symbol; 765 766 char* __group = 0; 767 wchar_t* __wcs_ps = 0; 768 wchar_t* __wcs_ns = 0; 769 const char __nposn = lc->n_sign_posn; 770 __try 771 { 772 size_t __len; 773 774 // Check for NULL, which implies no grouping. 775 if (lc->mon_thousands_sep == NULL || 776 lc->mon_thousands_sep[0] == '\0') 777 { 778 // Like in "C" locale. 779 _M_data->_M_grouping = ""; 780 _M_data->_M_grouping_size = 0; 781 _M_data->_M_use_grouping = false; 782 _M_data->_M_thousands_sep = L','; 783 } 784 else 785 { 786 _M_data->_M_thousands_sep = 787 (wchar_t)lc->mon_thousands_sep[0]; 788 __len = strlen(__cgroup); 789 if (__len) 790 { 791 __group = new char[__len + 1]; 792 memcpy(__group, __cgroup, __len + 1); 793 _M_data->_M_grouping = __group; 794 } 795 else 796 { 797 _M_data->_M_grouping = ""; 798 _M_data->_M_use_grouping = false; 799 } 800 _M_data->_M_grouping_size = __len; 801 } 802 803 mbstate_t __state; 804 __len = strlen(__cpossign); 805 if (__len) 806 { 807 memset(&__state, 0, sizeof(mbstate_t)); 808 __wcs_ps = new wchar_t[__len + 1]; 809 mbsrtowcs_l(__wcs_ps, &__cpossign, __len + 1, &__state, 810 (locale_t)__cloc); 811 _M_data->_M_positive_sign = __wcs_ps; 812 } 813 else 814 _M_data->_M_positive_sign = L""; 815 _M_data->_M_positive_sign_size = 816 wcslen(_M_data->_M_positive_sign); 817 818 __len = strlen(__cnegsign); 819 if (!__nposn) 820 _M_data->_M_negative_sign = L"()"; 821 else if (__len) 822 { 823 memset(&__state, 0, sizeof(mbstate_t)); 824 __wcs_ns = new wchar_t[__len + 1]; 825 mbsrtowcs_l(__wcs_ns, &__cnegsign, __len + 1, &__state, 826 (locale_t)__cloc); 827 _M_data->_M_negative_sign = __wcs_ns; 828 } 829 else 830 _M_data->_M_negative_sign = L""; 831 _M_data->_M_negative_sign_size = 832 wcslen(_M_data->_M_negative_sign); 833 834 // _Intl == true. 835 __len = strlen(__ccurr); 836 if (__len) 837 { 838 memset(&__state, 0, sizeof(mbstate_t)); 839 wchar_t* __wcs = new wchar_t[__len + 1]; 840 mbsrtowcs_l(__wcs, &__ccurr, __len + 1, &__state, 841 (locale_t)__cloc); 842 _M_data->_M_curr_symbol = __wcs; 843 } 844 else 845 _M_data->_M_curr_symbol = L""; 846 _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); 847 } 848 __catch(...) 849 { 850 delete _M_data; 851 _M_data = 0; 852 delete [] __group; 853 delete [] __wcs_ps; 854 delete [] __wcs_ns; 855 __throw_exception_again; 856 } 857 858 char __pprecedes = lc->p_cs_precedes; 859 char __pspace = lc->p_sep_by_space; 860 char __pposn = lc->p_sign_posn; 861 _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, 862 __pposn); 863 char __nprecedes = lc->n_cs_precedes; 864 char __nspace = lc->n_sep_by_space; 865 _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, 866 __nposn); 867 } 868 } 869 870 template<> 871 moneypunct<wchar_t, true>::~moneypunct() 872 { 873 if (_M_data->_M_grouping_size) 874 delete [] _M_data->_M_grouping; 875 if (_M_data->_M_positive_sign_size) 876 delete [] _M_data->_M_positive_sign; 877 if (_M_data->_M_negative_sign_size 878 && wcscmp(_M_data->_M_negative_sign, L"()") != 0) 879 delete [] _M_data->_M_negative_sign; 880 if (_M_data->_M_curr_symbol_size) 881 delete [] _M_data->_M_curr_symbol; 882 delete _M_data; 883 } 884 885 template<> 886 moneypunct<wchar_t, false>::~moneypunct() 887 { 888 if (_M_data->_M_grouping_size) 889 delete [] _M_data->_M_grouping; 890 if (_M_data->_M_positive_sign_size) 891 delete [] _M_data->_M_positive_sign; 892 if (_M_data->_M_negative_sign_size 893 && wcscmp(_M_data->_M_negative_sign, L"()") != 0) 894 delete [] _M_data->_M_negative_sign; 895 if (_M_data->_M_curr_symbol_size) 896 delete [] _M_data->_M_curr_symbol; 897 delete _M_data; 898 } 899 #endif 900 901 _GLIBCXX_END_NAMESPACE_VERSION 902 } // namespace 903