]>
Commit | Line | Data |
---|---|---|
69971cd8 BK |
1 | // 2001-09-09 Benjamin Kosnik <bkoz@redhat.com> |
2 | ||
aefb3380 | 3 | // Copyright (C) 2001, 2002 Free Software Foundation |
69971cd8 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 | |
8 | // Free Software Foundation; either version 2, 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 | // 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, | |
19 | // USA. | |
20 | ||
21 | // 22.2.6.2.1 money_put members | |
22 | ||
23 | #include <locale> | |
24 | #include <sstream> | |
25 | #include <testsuite_hooks.h> | |
26 | ||
27 | // XXX This test is not working for non-glibc locale models. | |
28 | // { dg-do run { xfail *-*-* } } | |
29 | ||
30 | #ifdef _GLIBCPP_USE_WCHAR_T | |
31 | // test string version | |
32 | void test01() | |
33 | { | |
34 | using namespace std; | |
35 | typedef money_base::part part; | |
36 | typedef money_base::pattern pattern; | |
37 | typedef ostreambuf_iterator<wchar_t> iterator_type; | |
38 | ||
39 | bool test = true; | |
69971cd8 BK |
40 | |
41 | // basic construction | |
42 | locale loc_c = locale::classic(); | |
69971cd8 | 43 | locale loc_hk("en_HK"); |
69971cd8 | 44 | locale loc_fr("fr_FR@euro"); |
165e0367 | 45 | locale loc_de("de_DE@euro"); |
69971cd8 | 46 | VERIFY( loc_c != loc_de ); |
69971cd8 BK |
47 | VERIFY( loc_hk != loc_fr ); |
48 | VERIFY( loc_hk != loc_de ); | |
49 | VERIFY( loc_de != loc_fr ); | |
50 | ||
51 | // cache the moneypunct facets | |
52 | typedef moneypunct<wchar_t, true> __money_true; | |
53 | typedef moneypunct<wchar_t, false> __money_false; | |
54 | const __money_true& monpunct_c_t = use_facet<__money_true>(loc_c); | |
55 | const __money_true& monpunct_de_t = use_facet<__money_true>(loc_de); | |
56 | const __money_false& monpunct_c_f = use_facet<__money_false>(loc_c); | |
57 | const __money_false& monpunct_de_f = use_facet<__money_false>(loc_de); | |
58 | const __money_true& monpunct_hk_t = use_facet<__money_true>(loc_hk); | |
59 | const __money_false& monpunct_hk_f = use_facet<__money_false>(loc_hk); | |
60 | ||
61 | // sanity check the data is correct. | |
62 | const wstring empty; | |
63 | ||
64 | // total EPA budget FY 2002 | |
65 | const wstring digits1(L"720000000000"); | |
66 | ||
73307975 | 67 | // est. cost, national missile "defense", expressed as a loss in USD 2001 |
69971cd8 BK |
68 | const wstring digits2(L"-10000000000000"); |
69 | ||
70 | // not valid input | |
71 | const wstring digits3(L"-A"); | |
72 | ||
73 | // input less than frac_digits | |
74 | const wstring digits4(L"-1"); | |
75 | ||
69971cd8 BK |
76 | wostringstream oss; |
77 | oss.imbue(loc_de); | |
78 | // cache the money_put facet | |
79 | const money_put<wchar_t>& mon_put = use_facet<money_put<wchar_t> >(oss.getloc()); | |
80 | ||
81 | ||
577f4061 | 82 | iterator_type os_it01 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); |
69971cd8 BK |
83 | wstring result1 = oss.str(); |
84 | VERIFY( result1 == L"7.200.000.000,00 "); | |
85 | ||
86 | oss.str(empty); | |
577f4061 | 87 | iterator_type os_it02 = mon_put.put(oss.rdbuf(), false, oss, ' ', digits1); |
69971cd8 BK |
88 | wstring result2 = oss.str(); |
89 | VERIFY( result2 == L"7.200.000.000,00 "); | |
90 | ||
91 | // intl and non-intl versions should be the same. | |
92 | VERIFY( result1 == result2 ); | |
93 | ||
94 | // now try with showbase, to get currency symbol in format | |
95 | oss.setf(ios_base::showbase); | |
96 | ||
97 | oss.str(empty); | |
577f4061 | 98 | iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); |
69971cd8 | 99 | wstring result3 = oss.str(); |
165e0367 | 100 | VERIFY( result3 == L"7.200.000.000,00 EUR "); |
69971cd8 BK |
101 | |
102 | oss.str(empty); | |
577f4061 | 103 | iterator_type os_it04 = mon_put.put(oss.rdbuf(), false, oss, ' ', digits1); |
69971cd8 | 104 | wstring result4 = oss.str(); |
165e0367 | 105 | VERIFY( result4 == L"7.200.000.000,00 \x20ac"); |
69971cd8 BK |
106 | |
107 | // intl and non-intl versions should be different. | |
108 | VERIFY( result3 != result4 ); | |
109 | VERIFY( result3 != result1 ); | |
110 | VERIFY( result4 != result2 ); | |
111 | ||
112 | // test sign of more than one digit, say hong kong. | |
113 | oss.imbue(loc_hk); | |
114 | oss.str(empty); | |
577f4061 | 115 | iterator_type os_it05 = mon_put.put(oss.rdbuf(), false, oss, ' ', digits1); |
69971cd8 BK |
116 | wstring result5 = oss.str(); |
117 | VERIFY( result5 == L"HK$7,200,000,000.00"); | |
118 | ||
119 | oss.str(empty); | |
577f4061 | 120 | iterator_type os_it06 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits2); |
69971cd8 BK |
121 | wstring result6 = oss.str(); |
122 | VERIFY( result6 == L"(HKD 100,000,000,000.00)"); | |
123 | ||
124 | // test one-digit formats without zero padding | |
125 | oss.imbue(loc_c); | |
126 | oss.str(empty); | |
577f4061 | 127 | iterator_type os_it07 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits4); |
69971cd8 BK |
128 | wstring result7 = oss.str(); |
129 | VERIFY( result7 == L"1"); | |
130 | ||
131 | // test one-digit formats with zero padding, zero frac widths | |
132 | oss.imbue(loc_hk); | |
133 | oss.str(empty); | |
577f4061 | 134 | iterator_type os_it08 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits4); |
69971cd8 BK |
135 | wstring result8 = oss.str(); |
136 | VERIFY( result8 == L"(HKD .01)"); | |
137 | ||
138 | oss.unsetf(ios_base::showbase); | |
139 | ||
140 | // test bunk input | |
141 | oss.str(empty); | |
577f4061 | 142 | iterator_type os_it09 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits3); |
69971cd8 BK |
143 | wstring result9 = oss.str(); |
144 | VERIFY( result9 == L""); | |
145 | ||
146 | // test io.width() > length | |
147 | // test various fill strategies | |
148 | oss.imbue(loc_de); | |
149 | ||
150 | oss.str(empty); | |
151 | oss.width(20); | |
152 | iterator_type os_it10 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4); | |
153 | wstring result10 = oss.str(); | |
577f4061 | 154 | VERIFY( result10 == L"***************-,01*"); |
69971cd8 BK |
155 | |
156 | oss.str(empty); | |
157 | oss.width(20); | |
158 | oss.setf(ios_base::internal); | |
159 | iterator_type os_it11 = mon_put.put(oss.rdbuf(), true, oss, '*', digits4); | |
160 | wstring result11 = oss.str(); | |
161 | VERIFY( result11 == L"-,01****************"); | |
162 | } | |
163 | ||
164 | // test double/wstring versions | |
165 | void test02() | |
166 | { | |
167 | using namespace std; | |
168 | typedef money_base::part part; | |
169 | typedef money_base::pattern pattern; | |
170 | typedef ostreambuf_iterator<wchar_t> iterator_type; | |
171 | ||
172 | bool test = true; | |
69971cd8 BK |
173 | |
174 | // basic construction | |
175 | locale loc_c = locale::classic(); | |
69971cd8 | 176 | locale loc_hk("en_HK"); |
69971cd8 | 177 | locale loc_fr("fr_FR@euro"); |
165e0367 | 178 | locale loc_de("de_DE@euro"); |
69971cd8 | 179 | VERIFY( loc_c != loc_de ); |
69971cd8 BK |
180 | VERIFY( loc_hk != loc_fr ); |
181 | VERIFY( loc_hk != loc_de ); | |
182 | VERIFY( loc_de != loc_fr ); | |
183 | ||
184 | // cache the moneypunct facets | |
185 | typedef moneypunct<wchar_t, true> __money_true; | |
186 | typedef moneypunct<wchar_t, false> __money_false; | |
187 | const __money_true& monpunct_c_t = use_facet<__money_true>(loc_c); | |
188 | const __money_true& monpunct_de_t = use_facet<__money_true>(loc_de); | |
189 | const __money_false& monpunct_c_f = use_facet<__money_false>(loc_c); | |
190 | const __money_false& monpunct_de_f = use_facet<__money_false>(loc_de); | |
191 | const __money_true& monpunct_hk_t = use_facet<__money_true>(loc_hk); | |
192 | const __money_false& monpunct_hk_f = use_facet<__money_false>(loc_hk); | |
193 | ||
194 | // sanity check the data is correct. | |
195 | const wstring empty; | |
196 | ||
197 | // total EPA budget FY 2002 | |
23992195 | 198 | const long double digits1 = 720000000000.0; |
69971cd8 | 199 | |
73307975 | 200 | // est. cost, national missile "defense", expressed as a loss in USD 2001 |
23992195 | 201 | const long double digits2 = -10000000000000.0; |
69971cd8 BK |
202 | |
203 | // input less than frac_digits | |
23992195 | 204 | const long double digits4 = -1.0; |
69971cd8 BK |
205 | |
206 | ||
207 | wostringstream oss; | |
208 | oss.imbue(loc_de); | |
209 | // cache the money_put facet | |
210 | const money_put<wchar_t>& mon_put = use_facet<money_put<wchar_t> >(oss.getloc()); | |
211 | ||
212 | ||
577f4061 | 213 | iterator_type os_it01 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); |
69971cd8 BK |
214 | wstring result1 = oss.str(); |
215 | VERIFY( result1 == L"7.200.000.000,00 "); | |
216 | ||
217 | oss.str(empty); | |
577f4061 | 218 | iterator_type os_it02 = mon_put.put(oss.rdbuf(), false, oss, ' ', digits1); |
69971cd8 BK |
219 | wstring result2 = oss.str(); |
220 | VERIFY( result2 == L"7.200.000.000,00 "); | |
221 | ||
222 | // intl and non-intl versions should be the same. | |
223 | VERIFY( result1 == result2 ); | |
224 | ||
225 | // now try with showbase, to get currency symbol in format | |
226 | oss.setf(ios_base::showbase); | |
227 | ||
228 | oss.str(empty); | |
3039874b | 229 | iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1); |
69971cd8 | 230 | wstring result3 = oss.str(); |
165e0367 | 231 | VERIFY( result3 == L"7.200.000.000,00 EUR "); |
69971cd8 BK |
232 | |
233 | oss.str(empty); | |
577f4061 | 234 | iterator_type os_it04 = mon_put.put(oss.rdbuf(), false, oss, ' ', digits1); |
69971cd8 | 235 | wstring result4 = oss.str(); |
165e0367 | 236 | VERIFY( result4 == L"7.200.000.000,00 \x20ac"); |
69971cd8 BK |
237 | |
238 | // intl and non-intl versions should be different. | |
239 | VERIFY( result3 != result4 ); | |
240 | VERIFY( result3 != result1 ); | |
241 | VERIFY( result4 != result2 ); | |
242 | } | |
ae72572b BK |
243 | |
244 | void test03() | |
245 | { | |
246 | using namespace std; | |
247 | bool test = true; | |
248 | ||
249 | // Check money_put works with other iterators besides streambuf | |
250 | // output iterators. (As long as output_iterator requirements are met.) | |
251 | typedef wstring::iterator iter_type; | |
252 | typedef money_put<wchar_t, iter_type> mon_put_type; | |
253 | const ios_base::iostate goodbit = ios_base::goodbit; | |
254 | const ios_base::iostate eofbit = ios_base::eofbit; | |
255 | ios_base::iostate err = goodbit; | |
256 | const locale loc_c = locale::classic(); | |
257 | // woman, art, thief (stole the blues) | |
258 | const wstring str(L"1943 Janis Joplin"); | |
23992195 | 259 | const long double ld = 1943.0; |
ae72572b BK |
260 | const wstring x(str.size(), 'x'); // have to have allocated string! |
261 | wstring res; | |
262 | ||
263 | wostringstream oss; | |
264 | oss.imbue(locale(loc_c, new mon_put_type)); | |
265 | ||
266 | // Iterator advanced, state, output. | |
267 | const mon_put_type& mp = use_facet<mon_put_type>(oss.getloc()); | |
268 | ||
269 | // 01 string | |
270 | res = x; | |
271 | iter_type ret1 = mp.put(res.begin(), false, oss, ' ', str); | |
272 | wstring sanity1(res.begin(), ret1); | |
273 | VERIFY( err == goodbit ); | |
274 | VERIFY( res == L"1943xxxxxxxxxxxxx" ); | |
275 | VERIFY( sanity1 == L"1943" ); | |
276 | ||
277 | // 02 long double | |
278 | res = x; | |
279 | iter_type ret2 = mp.put(res.begin(), false, oss, ' ', ld); | |
280 | wstring sanity2(res.begin(), ret2); | |
281 | VERIFY( err == goodbit ); | |
282 | VERIFY( res == L"1943xxxxxxxxxxxxx" ); | |
283 | VERIFY( sanity2 == L"1943" ); | |
284 | } | |
4b9aaf63 BK |
285 | |
286 | // libstdc++/5280 | |
287 | void test04() | |
288 | { | |
b6a95741 | 289 | #ifdef _GLIBCPP_HAVE_SETENV |
4b9aaf63 | 290 | // Set the global locale to non-"C". |
165e0367 | 291 | std::locale loc_de("de_DE@euro"); |
4b9aaf63 BK |
292 | std::locale::global(loc_de); |
293 | ||
165e0367 | 294 | // Set LANG environment variable to de_DE@euro. |
4b9aaf63 | 295 | const char* oldLANG = getenv("LANG"); |
165e0367 | 296 | if (!setenv("LANG", "de_DE@euro", 1)) |
4b9aaf63 BK |
297 | { |
298 | test01(); | |
299 | test02(); | |
300 | test03(); | |
4a78d864 | 301 | setenv("LANG", oldLANG ? oldLANG : "", 1); |
4b9aaf63 | 302 | } |
b6a95741 | 303 | #endif |
4b9aaf63 | 304 | } |
577f4061 PC |
305 | |
306 | struct My_money_io : public std::moneypunct<wchar_t,false> | |
307 | { | |
308 | char_type do_decimal_point() const { return L'.'; } | |
309 | char_type do_thousands_sep() const { return L','; } | |
310 | std::string do_grouping() const { return "\003"; } | |
311 | ||
312 | std::wstring do_negative_sign() const { return L"()"; } | |
313 | ||
314 | int do_frac_digits() const { return 2; } | |
315 | ||
316 | pattern do_neg_format() const | |
317 | { | |
04fc1394 | 318 | pattern pat = { { symbol, space, sign, value } }; |
577f4061 PC |
319 | return pat; |
320 | } | |
321 | }; | |
322 | ||
323 | // libstdc++/5708 | |
324 | void test05() | |
325 | { | |
326 | using namespace std; | |
327 | typedef ostreambuf_iterator<wchar_t> OutIt; | |
328 | ||
329 | locale loc(locale::classic(), new My_money_io); | |
330 | ||
331 | bool intl = false; | |
332 | ||
333 | wstring val(L"-123456"); | |
334 | const money_put<wchar_t,OutIt>& mp = | |
335 | use_facet<money_put<wchar_t, OutIt> >(loc); | |
336 | ||
337 | wostringstream fmt; | |
338 | fmt.imbue(loc); | |
339 | OutIt out(fmt); | |
340 | mp.put(out,intl,fmt,L'*',val); | |
341 | VERIFY( fmt.str() == L"*(1,234.56)" ); | |
342 | } | |
3039874b PC |
343 | |
344 | struct My_money_io_2 : public std::moneypunct<wchar_t,false> | |
345 | { | |
346 | char_type do_thousands_sep() const { return L','; } | |
347 | std::string do_grouping() const { return "\001"; } | |
348 | }; | |
349 | ||
350 | // Make sure we can output a very big amount of money (with grouping too). | |
351 | void test06() | |
352 | { | |
353 | using namespace std; | |
354 | typedef ostreambuf_iterator<wchar_t> OutIt; | |
355 | ||
356 | locale loc(locale::classic(), new My_money_io_2); | |
357 | ||
358 | bool intl = false; | |
359 | ||
23992195 | 360 | long double val = 1.0e50L; |
3039874b PC |
361 | const money_put<wchar_t,OutIt>& mp = |
362 | use_facet<money_put<wchar_t, OutIt> >(loc); | |
363 | ||
364 | wostringstream fmt; | |
365 | fmt.imbue(loc); | |
366 | OutIt out(fmt); | |
367 | mp.put(out,intl,fmt,'*',val); | |
368 | VERIFY( fmt ); | |
369 | } | |
b5623829 PC |
370 | |
371 | // http://gcc.gnu.org/ml/libstdc++/2002-05/msg00038.html | |
372 | void test07() | |
373 | { | |
374 | bool test = true; | |
375 | ||
8081da07 | 376 | const char* tentLANG = std::setlocale(LC_ALL, "ja_JP.eucjp"); |
27b4d95a PC |
377 | if (tentLANG != NULL) |
378 | { | |
379 | std::string preLANG = tentLANG; | |
380 | test01(); | |
381 | test02(); | |
382 | test03(); | |
383 | test05(); | |
384 | test06(); | |
8081da07 | 385 | std::string postLANG = std::setlocale(LC_ALL, NULL); |
27b4d95a PC |
386 | VERIFY( preLANG == postLANG ); |
387 | } | |
b5623829 | 388 | } |
69971cd8 BK |
389 | #endif |
390 | ||
391 | int main() | |
392 | { | |
393 | #ifdef _GLIBCPP_USE_WCHAR_T | |
394 | test01(); | |
395 | test02(); | |
ae72572b | 396 | test03(); |
4b9aaf63 | 397 | test04(); |
577f4061 | 398 | test05(); |
3039874b | 399 | test06(); |
b5623829 | 400 | test07(); |
69971cd8 BK |
401 | #endif |
402 | return 0; | |
403 | } |