1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // NetBSD does not support LC_MONETARY at the moment
10 // XFAIL: netbsd
11 
12 // Failure related to GLIBC's use of U00A0 as mon_thousands_sep
13 // and U002E as mon_decimal_point.
14 // TODO: U00A0 should be investigated.
15 // Possibly related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16006
16 // XFAIL: linux
17 
18 // REQUIRES: locale.ru_RU.UTF-8
19 
20 // <locale>
21 
22 // class money_put<charT, OutputIterator>
23 
24 // iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
25 //               long double units) const;
26 
27 #include <locale>
28 #include <ios>
29 #include <streambuf>
30 #include <cassert>
31 #include "test_macros.h"
32 #include "test_iterators.h"
33 
34 #include "platform_support.h" // locale name macros
35 
36 // TODO:
37 // Some of the assertions in this test are failing on Apple platforms.
38 // Until we figure out the problem and fix it, disable these tests on
39 // Apple platforms. Note that we're not using XFAIL or UNSUPPORTED markup
40 // here, because this test would otherwise be disabled on all platforms
41 // we test. To avoid this test becoming entirely stale, we just disable
42 // the parts that fail.
43 //
44 // See https://llvm.org/PR45739 for the bug tracking this.
45 #if defined(__APPLE__)
46 #   define APPLE_FIXME
47 #endif
48 
49 typedef std::money_put<char, output_iterator<char*> > Fn;
50 
51 class my_facet
52     : public Fn
53 {
54 public:
my_facet(std::size_t refs=0)55     explicit my_facet(std::size_t refs = 0)
56         : Fn(refs) {}
57 };
58 
59 typedef std::money_put<wchar_t, output_iterator<wchar_t*> > Fw;
60 
61 class my_facetw
62     : public Fw
63 {
64 public:
my_facetw(std::size_t refs=0)65     explicit my_facetw(std::size_t refs = 0)
66         : Fw(refs) {}
67 };
68 
main(int,char **)69 int main(int, char**)
70 {
71     std::ios ios(0);
72     std::string loc_name(LOCALE_ru_RU_UTF_8);
73     ios.imbue(std::locale(ios.getloc(),
74                           new std::moneypunct_byname<char, false>(loc_name)));
75     ios.imbue(std::locale(ios.getloc(),
76                           new std::moneypunct_byname<char, true>(loc_name)));
77     ios.imbue(std::locale(ios.getloc(),
78                           new std::moneypunct_byname<wchar_t, false>(loc_name)));
79     ios.imbue(std::locale(ios.getloc(),
80                           new std::moneypunct_byname<wchar_t, true>(loc_name)));
81 {
82     const my_facet f(1);
83     // char, national
84 #if !defined(APPLE_FIXME)
85     {   // zero
86         long double v = 0;
87         char str[100];
88         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
89                                             false, ios, '*', v);
90         std::string ex(str, iter.base());
91         assert(ex == "0,00 ");
92     }
93     {   // negative one
94         long double v = -1;
95         char str[100];
96         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
97                                             false, ios, '*', v);
98         std::string ex(str, iter.base());
99         assert(ex == "-0,01 ");
100     }
101     {   // positive
102         long double v = 123456789;
103         char str[100];
104         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
105                                             false, ios, '*', v);
106         std::string ex(str, iter.base());
107         assert(ex == "1 234 567,89 ");
108     }
109     {   // negative
110         long double v = -123456789;
111         char str[100];
112         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
113                                             false, ios, '*', v);
114         std::string ex(str, iter.base());
115         assert(ex == "-1 234 567,89 ");
116     }
117 #endif
118     {   // zero, showbase
119         long double v = 0;
120         showbase(ios);
121         char str[100];
122         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
123                                             false, ios, '*', v);
124         std::string ex(str, iter.base());
125         assert(ex == "0,00 \xD1\x80\xD1\x83\xD0\xB1"".");
126     }
127     {   // negative one, showbase
128         long double v = -1;
129         showbase(ios);
130         char str[100];
131         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
132                                             false, ios, '*', v);
133         std::string ex(str, iter.base());
134         assert(ex == "-0,01 \xD1\x80\xD1\x83\xD0\xB1"".");
135     }
136     {   // positive, showbase
137         long double v = 123456789;
138         showbase(ios);
139         char str[100];
140         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
141                                             false, ios, '*', v);
142         std::string ex(str, iter.base());
143         assert(ex == "1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
144     }
145     {   // negative, showbase
146         long double v = -123456789;
147         showbase(ios);
148         char str[100];
149         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
150                                             false, ios, '*', v);
151         std::string ex(str, iter.base());
152         assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
153     }
154     {   // negative, showbase, left
155         long double v = -123456789;
156         showbase(ios);
157         ios.width(20);
158         left(ios);
159         char str[100];
160         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
161                                             false, ios, ' ', v);
162         std::string ex(str, iter.base());
163         assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
164         assert(ios.width() == 0);
165     }
166     {   // negative, showbase, internal
167         long double v = -123456789;
168         showbase(ios);
169         ios.width(20);
170         internal(ios);
171         char str[100];
172         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
173                                             false, ios, ' ', v);
174         std::string ex(str, iter.base());
175         assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
176         assert(ios.width() == 0);
177     }
178     {   // negative, showbase, right
179         long double v = -123456789;
180         showbase(ios);
181         ios.width(20);
182         right(ios);
183         char str[100];
184         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
185                                             false, ios, ' ', v);
186         std::string ex(str, iter.base());
187         assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
188         assert(ios.width() == 0);
189     }
190 
191     // char, international
192     noshowbase(ios);
193     ios.unsetf(std::ios_base::adjustfield);
194 #if !defined(APPLE_FIXME)
195     {   // zero
196         long double v = 0;
197         char str[100];
198         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
199                                             true, ios, '*', v);
200         std::string ex(str, iter.base());
201         assert(ex == "0,00 ");
202     }
203     {   // negative one
204         long double v = -1;
205         char str[100];
206         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
207                                             true, ios, '*', v);
208         std::string ex(str, iter.base());
209         assert(ex == "-0,01 ");
210     }
211     {   // positive
212         long double v = 123456789;
213         char str[100];
214         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
215                                             true, ios, '*', v);
216         std::string ex(str, iter.base());
217         assert(ex == "1 234 567,89 ");
218     }
219     {   // negative
220         long double v = -123456789;
221         char str[100];
222         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
223                                             true, ios, '*', v);
224         std::string ex(str, iter.base());
225         assert(ex == "-1 234 567,89 ");
226     }
227     {   // zero, showbase
228         long double v = 0;
229         showbase(ios);
230         char str[100];
231         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
232                                             true, ios, '*', v);
233         std::string ex(str, iter.base());
234         assert(ex == "0,00 RUB ");
235     }
236     {   // negative one, showbase
237         long double v = -1;
238         showbase(ios);
239         char str[100];
240         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
241                                             true, ios, '*', v);
242         std::string ex(str, iter.base());
243         assert(ex == "-0,01 RUB ");
244     }
245     {   // positive, showbase
246         long double v = 123456789;
247         showbase(ios);
248         char str[100];
249         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
250                                             true, ios, '*', v);
251         std::string ex(str, iter.base());
252         assert(ex == "1 234 567,89 RUB ");
253     }
254     {   // negative, showbase
255         long double v = -123456789;
256         showbase(ios);
257         char str[100];
258         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
259                                             true, ios, '*', v);
260         std::string ex(str, iter.base());
261         assert(ex == "-1 234 567,89 RUB ");
262     }
263 #endif
264     {   // negative, showbase, left
265         long double v = -123456789;
266         showbase(ios);
267         ios.width(20);
268         left(ios);
269         char str[100];
270         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
271                                             true, ios, ' ', v);
272         std::string ex(str, iter.base());
273         assert(ex == "-1 234 567,89 RUB   ");
274         assert(ios.width() == 0);
275     }
276 #if !defined(APPLE_FIXME)
277     {   // negative, showbase, internal
278         long double v = -123456789;
279         showbase(ios);
280         ios.width(20);
281         internal(ios);
282         char str[100];
283         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
284                                             true, ios, ' ', v);
285         std::string ex(str, iter.base());
286         assert(ex == "-1 234 567,89   RUB ");
287         assert(ios.width() == 0);
288     }
289     {   // negative, showbase, right
290         long double v = -123456789;
291         showbase(ios);
292         ios.width(20);
293         right(ios);
294         char str[100];
295         output_iterator<char*> iter = f.put(output_iterator<char*>(str),
296                                             true, ios, ' ', v);
297         std::string ex(str, iter.base());
298         assert(ex == "  -1 234 567,89 RUB ");
299         assert(ios.width() == 0);
300     }
301 #endif
302 }
303 {
304     const my_facetw f(1);
305     // wchar_t, national
306     noshowbase(ios);
307     ios.unsetf(std::ios_base::adjustfield);
308 #if !defined(APPLE_FIXME)
309     {   // zero
310         long double v = 0;
311         wchar_t str[100];
312         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
313                                             false, ios, '*', v);
314         std::wstring ex(str, iter.base());
315         assert(ex == L"0,00 ");
316     }
317     {   // negative one
318         long double v = -1;
319         wchar_t str[100];
320         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
321                                             false, ios, '*', v);
322         std::wstring ex(str, iter.base());
323         assert(ex == L"-0,01 ");
324     }
325     {   // positive
326         long double v = 123456789;
327         wchar_t str[100];
328         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
329                                             false, ios, '*', v);
330         std::wstring ex(str, iter.base());
331         assert(ex == L"1 234 567,89 ");
332     }
333     {   // negative
334         long double v = -123456789;
335         wchar_t str[100];
336         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
337                                             false, ios, '*', v);
338         std::wstring ex(str, iter.base());
339         assert(ex == L"-1 234 567,89 ");
340     }
341 #endif
342     {   // zero, showbase
343         long double v = 0;
344         showbase(ios);
345         wchar_t str[100];
346         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
347                                             false, ios, '*', v);
348         std::wstring ex(str, iter.base());
349         assert(ex == L"0,00 \x440\x443\x431"".");
350     }
351     {   // negative one, showbase
352         long double v = -1;
353         showbase(ios);
354         wchar_t str[100];
355         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
356                                             false, ios, '*', v);
357         std::wstring ex(str, iter.base());
358         assert(ex == L"-0,01 \x440\x443\x431"".");
359     }
360     {   // positive, showbase
361         long double v = 123456789;
362         showbase(ios);
363         wchar_t str[100];
364         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
365                                             false, ios, '*', v);
366         std::wstring ex(str, iter.base());
367         assert(ex == L"1 234 567,89 \x440\x443\x431"".");
368     }
369     {   // negative, showbase
370         long double v = -123456789;
371         showbase(ios);
372         wchar_t str[100];
373         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
374                                             false, ios, '*', v);
375         std::wstring ex(str, iter.base());
376         assert(ex == L"-1 234 567,89 \x440\x443\x431"".");
377     }
378     {   // negative, showbase, left
379         long double v = -123456789;
380         showbase(ios);
381         ios.width(20);
382         left(ios);
383         wchar_t str[100];
384         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
385                                             false, ios, ' ', v);
386         std::wstring ex(str, iter.base());
387         assert(ex == L"-1 234 567,89 \x440\x443\x431"".  ");
388         assert(ios.width() == 0);
389     }
390     {   // negative, showbase, internal
391         long double v = -123456789;
392         showbase(ios);
393         ios.width(20);
394         internal(ios);
395         wchar_t str[100];
396         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
397                                             false, ios, ' ', v);
398         std::wstring ex(str, iter.base());
399         assert(ex == L"-1 234 567,89   \x440\x443\x431"".");
400         assert(ios.width() == 0);
401     }
402     {   // negative, showbase, right
403         long double v = -123456789;
404         showbase(ios);
405         ios.width(20);
406         right(ios);
407         wchar_t str[100];
408         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
409                                             false, ios, ' ', v);
410         std::wstring ex(str, iter.base());
411         assert(ex == L"  -1 234 567,89 \x440\x443\x431"".");
412         assert(ios.width() == 0);
413     }
414 
415     // wchar_t, international
416     noshowbase(ios);
417     ios.unsetf(std::ios_base::adjustfield);
418 #if !defined(APPLE_FIXME)
419     {   // zero
420         long double v = 0;
421         wchar_t str[100];
422         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
423                                             true, ios, '*', v);
424         std::wstring ex(str, iter.base());
425         assert(ex == L"0,00 ");
426     }
427     {   // negative one
428         long double v = -1;
429         wchar_t str[100];
430         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
431                                             true, ios, '*', v);
432         std::wstring ex(str, iter.base());
433         assert(ex == L"-0,01 ");
434     }
435     {   // positive
436         long double v = 123456789;
437         wchar_t str[100];
438         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
439                                             true, ios, '*', v);
440         std::wstring ex(str, iter.base());
441         assert(ex == L"1 234 567,89 ");
442     }
443     {   // negative
444         long double v = -123456789;
445         wchar_t str[100];
446         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
447                                             true, ios, '*', v);
448         std::wstring ex(str, iter.base());
449         assert(ex == L"-1 234 567,89 ");
450     }
451     {   // zero, showbase
452         long double v = 0;
453         showbase(ios);
454         wchar_t str[100];
455         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
456                                             true, ios, '*', v);
457         std::wstring ex(str, iter.base());
458         assert(ex == L"0,00 RUB ");
459     }
460     {   // negative one, showbase
461         long double v = -1;
462         showbase(ios);
463         wchar_t str[100];
464         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
465                                             true, ios, '*', v);
466         std::wstring ex(str, iter.base());
467         assert(ex == L"-0,01 RUB ");
468     }
469     {   // positive, showbase
470         long double v = 123456789;
471         showbase(ios);
472         wchar_t str[100];
473         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
474                                             true, ios, '*', v);
475         std::wstring ex(str, iter.base());
476         assert(ex == L"1 234 567,89 RUB ");
477     }
478     {   // negative, showbase
479         long double v = -123456789;
480         showbase(ios);
481         wchar_t str[100];
482         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
483                                             true, ios, '*', v);
484         std::wstring ex(str, iter.base());
485         assert(ex == L"-1 234 567,89 RUB ");
486     }
487 #endif
488     {   // negative, showbase, left
489         long double v = -123456789;
490         showbase(ios);
491         ios.width(20);
492         left(ios);
493         wchar_t str[100];
494         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
495                                             true, ios, ' ', v);
496         std::wstring ex(str, iter.base());
497         assert(ex == L"-1 234 567,89 RUB   ");
498         assert(ios.width() == 0);
499     }
500 #if !defined(APPLE_FIXME)
501     {   // negative, showbase, internal
502         long double v = -123456789;
503         showbase(ios);
504         ios.width(20);
505         internal(ios);
506         wchar_t str[100];
507         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
508                                             true, ios, ' ', v);
509         std::wstring ex(str, iter.base());
510         assert(ex == L"-1 234 567,89   RUB ");
511         assert(ios.width() == 0);
512     }
513     {   // negative, showbase, right
514         long double v = -123456789;
515         showbase(ios);
516         ios.width(20);
517         right(ios);
518         wchar_t str[100];
519         output_iterator<wchar_t*> iter = f.put(output_iterator<wchar_t*>(str),
520                                             true, ios, ' ', v);
521         std::wstring ex(str, iter.base());
522         assert(ex == L"  -1 234 567,89 RUB ");
523         assert(ios.width() == 0);
524     }
525 #endif
526 }
527 
528   return 0;
529 }
530