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