]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
b75a7d8f | 3 | /******************************************************************** |
46f4442e | 4 | * COPYRIGHT: |
2ca993e8 | 5 | * Copyright (c) 1997-2016, International Business Machines Corporation |
374ca955 | 6 | * and others. All Rights Reserved. |
b75a7d8f A |
7 | ********************************************************************/ |
8 | /******************************************************************************* | |
9 | * | |
10 | * File CNMDPTST.C | |
11 | * | |
12 | * Madhu Katragadda Creation | |
13 | * Modification History: | |
14 | * | |
15 | * Date Name Description | |
16 | * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes | |
17 | ******************************************************************************* | |
18 | */ | |
19 | ||
20 | /* C DEPTH TEST FOR NUMBER FORMAT */ | |
21 | ||
22 | #include "unicode/utypes.h" | |
23 | ||
24 | #if !UCONFIG_NO_FORMATTING | |
25 | ||
374ca955 | 26 | #include "unicode/ucurr.h" |
b75a7d8f A |
27 | #include "unicode/uloc.h" |
28 | #include "unicode/unum.h" | |
29 | #include "unicode/ustring.h" | |
2ca993e8 | 30 | #include "unicode/putil.h" |
b75a7d8f A |
31 | #include "cintltst.h" |
32 | #include "cnmdptst.h" | |
33 | #include "cmemory.h" | |
34 | #include "cstring.h" | |
729e4ab9 | 35 | #include "ulist.h" |
b75a7d8f A |
36 | |
37 | #define CHECK(status,str) if (U_FAILURE(status)) { log_err("FAIL: %s\n", str); return; } | |
38 | ||
39 | void addNumFrDepTest(TestNode** root); | |
40 | static void TestCurrencyPreEuro(void); | |
41 | static void TestCurrencyObject(void); | |
42 | ||
43 | void addNumFrDepTest(TestNode** root) | |
44 | { | |
45 | addTest(root, &TestPatterns, "tsformat/cnmdptst/TestPatterns"); | |
46 | addTest(root, &TestQuotes, "tsformat/cnmdptst/TestQuotes"); | |
47 | addTest(root, &TestExponential, "tsformat/cnmdptst/TestExponential"); | |
48 | addTest(root, &TestCurrencySign, "tsformat/cnmdptst/TestCurrencySign"); | |
49 | addTest(root, &TestCurrency, "tsformat/cnmdptst/TestCurrency"); | |
50 | addTest(root, &TestCurrencyPreEuro, "tsformat/cnmdptst/TestCurrencyPreEuro"); | |
51 | addTest(root, &TestCurrencyObject, "tsformat/cnmdptst/TestCurrencyObject"); | |
52 | addTest(root, &TestRounding487, "tsformat/cnmdptst/TestRounding487"); | |
53 | addTest(root, &TestDoubleAttribute, "tsformat/cnmdptst/TestDoubleAttribute"); | |
54 | addTest(root, &TestSecondaryGrouping, "tsformat/cnmdptst/TestSecondaryGrouping"); | |
374ca955 | 55 | addTest(root, &TestCurrencyKeywords, "tsformat/cnmdptst/TestCurrencyKeywords"); |
46f4442e | 56 | addTest(root, &TestRounding5350, "tsformat/cnmdptst/TestRounding5350"); |
729e4ab9 | 57 | addTest(root, &TestGetKeywordValuesForLocale, "tsformat/cnmdptst/TestGetKeywordValuesForLocale"); |
b75a7d8f A |
58 | } |
59 | ||
60 | /*Test Various format patterns*/ | |
61 | static void TestPatterns(void) | |
62 | { | |
374ca955 A |
63 | int32_t pat_length, i, lneed; |
64 | UNumberFormat *fmt; | |
65 | UChar upat[5]; | |
66 | UChar unewpat[5]; | |
67 | UChar unum[5]; | |
68 | UChar *unewp=NULL; | |
69 | UChar *str=NULL; | |
70 | UErrorCode status = U_ZERO_ERROR; | |
71 | const char* pat[] = { "#.#", "#.", ".#", "#" }; | |
0f5d89e8 | 72 | const char* newpat[] = { "#0.#", "#0.", "#.0", "#" }; // ICU 61 behavior |
374ca955 | 73 | const char* num[] = { "0", "0.", ".0", "0" }; |
46f4442e | 74 | |
374ca955 | 75 | log_verbose("\nTesting different format patterns\n"); |
2ca993e8 | 76 | pat_length = UPRV_LENGTHOF(pat); |
374ca955 | 77 | for (i=0; i < pat_length; ++i) |
b75a7d8f | 78 | { |
374ca955 A |
79 | status = U_ZERO_ERROR; |
80 | u_uastrcpy(upat, pat[i]); | |
81 | fmt= unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status); | |
82 | if (U_FAILURE(status)) { | |
729e4ab9 | 83 | log_err_status(status, "FAIL: Number format constructor failed for pattern %s -> %s\n", pat[i], u_errorName(status)); |
46f4442e | 84 | continue; |
374ca955 A |
85 | } |
86 | lneed=0; | |
87 | lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status); | |
88 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
89 | status= U_ZERO_ERROR; | |
90 | unewp=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
91 | unum_toPattern(fmt, FALSE, unewp, lneed+1, &status); | |
92 | } | |
93 | if(U_FAILURE(status)){ | |
94 | log_err("FAIL: Number format extracting the pattern failed for %s\n", pat[i]); | |
95 | } | |
96 | u_uastrcpy(unewpat, newpat[i]); | |
97 | if(u_strcmp(unewp, unewpat) != 0) | |
98 | log_err("FAIL: Pattern %s should be transmute to %s; %s seen instead\n", pat[i], newpat[i], austrdup(unewp) ); | |
46f4442e | 99 | |
374ca955 A |
100 | lneed=0; |
101 | lneed=unum_format(fmt, 0, NULL, lneed, NULL, &status); | |
102 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
103 | status=U_ZERO_ERROR; | |
104 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
105 | unum_format(fmt, 0, str, lneed+1, NULL, &status); | |
106 | } | |
107 | if(U_FAILURE(status)) { | |
108 | log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); | |
109 | } | |
110 | u_uastrcpy(unum, num[i]); | |
111 | if (u_strcmp(str, unum) != 0) | |
b75a7d8f | 112 | { |
374ca955 | 113 | log_err("FAIL: Pattern %s should format zero as %s; %s Seen instead\n", pat[i], num[i], austrdup(str) ); |
46f4442e | 114 | |
b75a7d8f | 115 | } |
374ca955 A |
116 | free(unewp); |
117 | free(str); | |
118 | unum_close(fmt); | |
b75a7d8f A |
119 | } |
120 | } | |
121 | ||
122 | /* Test the handling of quotes*/ | |
123 | static void TestQuotes(void) | |
124 | { | |
374ca955 A |
125 | int32_t lneed; |
126 | UErrorCode status=U_ZERO_ERROR; | |
127 | UChar pat[15]; | |
128 | UChar res[15]; | |
129 | UChar *str=NULL; | |
130 | UNumberFormat *fmt; | |
131 | char tempBuf[256]; | |
132 | log_verbose("\nTestting the handling of quotes in number format\n"); | |
133 | u_uastrcpy(pat, "a'fo''o'b#"); | |
134 | fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status); | |
135 | if(U_FAILURE(status)){ | |
729e4ab9 | 136 | log_err_status(status, "Error in number format costruction using pattern \"a'fo''o'b#\" -> %s\n", u_errorName(status)); |
374ca955 A |
137 | } |
138 | lneed=0; | |
139 | lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status); | |
140 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
141 | status=U_ZERO_ERROR; | |
142 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
143 | unum_format(fmt, 123, str, lneed+1, NULL, &status); | |
144 | } | |
145 | if(U_FAILURE(status) || !str) { | |
729e4ab9 | 146 | log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); |
374ca955 A |
147 | return; |
148 | } | |
149 | log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) ); | |
150 | log_verbose("Format 123 -> %s\n", u_austrcpy(tempBuf, str) ); | |
151 | u_uastrcpy(res, "afo'ob123"); | |
152 | if(u_strcmp(str, res) != 0) | |
153 | log_err("FAIL: Expected afo'ob123"); | |
46f4442e | 154 | |
374ca955 A |
155 | free(str); |
156 | unum_close(fmt); | |
46f4442e A |
157 | |
158 | ||
374ca955 A |
159 | u_uastrcpy(pat, ""); |
160 | u_uastrcpy(pat, "a''b#"); | |
46f4442e A |
161 | |
162 | ||
374ca955 A |
163 | fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status); |
164 | if(U_FAILURE(status)){ | |
165 | log_err("Error in number format costruction using pattern \"a''b#\"\n"); | |
166 | } | |
167 | lneed=0; | |
168 | lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status); | |
169 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
170 | status=U_ZERO_ERROR; | |
171 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
172 | unum_format(fmt, 123, str, lneed+1, NULL, &status); | |
173 | } | |
174 | if(U_FAILURE(status)) { | |
175 | log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); | |
176 | } | |
177 | log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) ); | |
178 | log_verbose("Format 123 -> %s\n", u_austrcpy(tempBuf, str) ); | |
179 | u_uastrcpy(res, ""); | |
180 | u_uastrcpy(res, "a'b123"); | |
181 | if(u_strcmp(str, res) != 0) | |
182 | log_err("FAIL: Expected a'b123\n"); | |
46f4442e | 183 | |
374ca955 A |
184 | free(str); |
185 | unum_close(fmt); | |
b75a7d8f A |
186 | } |
187 | ||
188 | /* Test exponential pattern*/ | |
189 | static void TestExponential(void) | |
190 | { | |
374ca955 A |
191 | int32_t pat_length, val_length, lval_length; |
192 | int32_t ival, ilval, p, v, lneed; | |
193 | UNumberFormat *fmt; | |
194 | int32_t ppos; | |
195 | UChar *upat; | |
196 | UChar pattern[20]; | |
197 | UChar *str=NULL; | |
198 | UChar uvalfor[20], ulvalfor[20]; | |
199 | char tempMsgBug[256]; | |
200 | double a; | |
201 | UErrorCode status = U_ZERO_ERROR; | |
4388f060 | 202 | #if U_PLATFORM == U_PF_OS390 |
73c04bcf | 203 | static const double val[] = { 0.01234, 123456789, 1.23e75, -3.141592653e-78 }; |
b75a7d8f | 204 | #else |
73c04bcf | 205 | static const double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 }; |
b75a7d8f | 206 | #endif |
73c04bcf A |
207 | static const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" }; |
208 | static const int32_t lval[] = { 0, -1, 1, 123456789 }; | |
46f4442e | 209 | |
73c04bcf | 210 | static const char* valFormat[] = |
374ca955 A |
211 | { |
212 | "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271", | |
73c04bcf A |
213 | "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272", |
214 | "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273", | |
215 | "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]" | |
374ca955 | 216 | }; |
73c04bcf | 217 | static const char* lvalFormat[] = |
374ca955 A |
218 | { |
219 | "0E0", "-1E0", "1E0", "1.2346E8", | |
73c04bcf A |
220 | "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07", |
221 | "0E000", "-1E000", "1E000", "123.4568E006", | |
222 | "0E0", "[1E0]", "1E0", "1.235E8" | |
374ca955 | 223 | }; |
73c04bcf | 224 | static const double valParse[] = |
374ca955 | 225 | { |
4388f060 | 226 | #if U_PLATFORM == U_PF_OS390 |
374ca955 | 227 | 0.01234, 123460000, 1.23E75, -3.1416E-78, |
73c04bcf A |
228 | 0.01234, 123460000, 1.23E75, -3.1416E-78, |
229 | 0.01234, 123456800, 1.23E75, -3.141593E-78, | |
230 | 0.01234, 123500000, 1.23E75, -3.142E-78 | |
b75a7d8f | 231 | #else |
73c04bcf A |
232 | /* We define the whole IEEE 754 number in the 4th column because |
233 | Visual Age 7 has a bug in rounding numbers. */ | |
234 | 0.01234, 123460000, 1.23E300, -3.1415999999999999E-271, | |
235 | 0.01234, 123460000, 1.23E300, -3.1415999999999999E-271, | |
236 | 0.01234, 123456800, 1.23E300, -3.1415929999999999E-271, | |
237 | 0.01234, 123500000, 1.23E300, -3.1420000000000001E-271 | |
b75a7d8f | 238 | #endif |
374ca955 | 239 | }; |
73c04bcf | 240 | static const int32_t lvalParse[] = |
b75a7d8f | 241 | { |
374ca955 A |
242 | 0, -1, 1, 123460000, |
243 | 0, -1, 1, 123460000, | |
244 | 0, -1, 1, 123456800, | |
245 | 0, -1, 1, 123500000 | |
246 | }; | |
46f4442e A |
247 | |
248 | ||
2ca993e8 A |
249 | pat_length = UPRV_LENGTHOF(pat); |
250 | val_length = UPRV_LENGTHOF(val); | |
251 | lval_length = UPRV_LENGTHOF(lval); | |
374ca955 A |
252 | ival = 0; |
253 | ilval = 0; | |
254 | for (p=0; p < pat_length; ++p) | |
255 | { | |
256 | upat=(UChar*)malloc(sizeof(UChar) * (strlen(pat[p])+1) ); | |
257 | u_uastrcpy(upat, pat[p]); | |
258 | fmt=unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status); | |
46f4442e | 259 | if (U_FAILURE(status)) { |
729e4ab9 | 260 | log_err_status(status, "FAIL: Bad status returned by Number format construction with pattern %s -> %s\n", pat[p], u_errorName(status)); |
46f4442e | 261 | continue; |
374ca955 A |
262 | } |
263 | lneed= u_strlen(upat) + 1; | |
264 | unum_toPattern(fmt, FALSE, pattern, lneed, &status); | |
265 | log_verbose("Pattern \" %s \" -toPattern-> \" %s \" \n", upat, u_austrcpy(tempMsgBug, pattern) ); | |
266 | for (v=0; v<val_length; ++v) | |
b75a7d8f | 267 | { |
374ca955 | 268 | /*format*/ |
46f4442e | 269 | lneed=0; |
374ca955 A |
270 | lneed=unum_formatDouble(fmt, val[v], NULL, lneed, NULL, &status); |
271 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
272 | status=U_ZERO_ERROR; | |
273 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
274 | unum_formatDouble(fmt, val[v], str, lneed+1, NULL, &status); | |
275 | } | |
276 | if(U_FAILURE(status)) { | |
277 | log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); | |
278 | } | |
46f4442e A |
279 | |
280 | ||
281 | ||
374ca955 A |
282 | u_uastrcpy(uvalfor, valFormat[v+ival]); |
283 | if(u_strcmp(str, uvalfor) != 0) | |
284 | log_verbose("FAIL: Expected %s ( %s )\n", valFormat[v+ival], u_austrcpy(tempMsgBug, uvalfor) ); | |
46f4442e | 285 | |
374ca955 A |
286 | /*parsing*/ |
287 | ppos=0; | |
288 | a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status); | |
289 | if (ppos== u_strlen(str)) { | |
290 | if (a != valParse[v+ival]) | |
291 | log_err("FAIL: Expected: %e, Got: %g\n", valParse[v+ival], a); | |
292 | } | |
293 | else | |
294 | log_err(" FAIL: Partial parse ( %d chars ) -> %e\n", ppos, a); | |
46f4442e | 295 | |
374ca955 | 296 | free(str); |
b75a7d8f | 297 | } |
374ca955 | 298 | for (v=0; v<lval_length; ++v) |
b75a7d8f | 299 | { |
374ca955 | 300 | /*format*/ |
46f4442e | 301 | lneed=0; |
374ca955 A |
302 | lneed=unum_formatDouble(fmt, lval[v], NULL, lneed, NULL, &status); |
303 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
304 | status=U_ZERO_ERROR; | |
305 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
306 | unum_formatDouble(fmt, lval[v], str, lneed+1, NULL, &status); | |
307 | } | |
308 | if(U_FAILURE(status)) { | |
309 | log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); | |
310 | } | |
311 | /*printf(" Format %e -> %s\n", lval[v], austrdup(str) );*/ | |
312 | u_uastrcpy(ulvalfor, lvalFormat[v+ilval]); | |
313 | if(u_strcmp(str, ulvalfor) != 0) | |
314 | log_err("FAIL: Expected %s ( %s )\n", valFormat[v+ilval], austrdup(ulvalfor) ); | |
46f4442e | 315 | |
374ca955 A |
316 | /*parsing*/ |
317 | ppos=0; | |
318 | a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status); | |
319 | if (ppos== u_strlen(str)) { | |
320 | /*printf(" Parse -> %e\n", a);*/ | |
321 | if (a != lvalParse[v+ilval]) | |
322 | log_err("FAIL: Expected : %e\n", valParse[v+ival]); | |
323 | } | |
324 | else | |
325 | log_err(" FAIL: Partial parse ( %d chars ) -> %e\n", ppos, a); | |
46f4442e | 326 | |
374ca955 | 327 | free(str); |
46f4442e | 328 | |
b75a7d8f | 329 | } |
374ca955 A |
330 | ival += val_length; |
331 | ilval += lval_length; | |
332 | unum_close(fmt); | |
333 | free(upat); | |
b75a7d8f A |
334 | } |
335 | } | |
336 | ||
337 | /** | |
338 | * Test the handling of the currency symbol in patterns. | |
339 | */ | |
340 | static void TestCurrencySign(void) | |
341 | { | |
374ca955 A |
342 | int32_t lneed; |
343 | UNumberFormat *fmt; | |
344 | UChar *pattern=NULL; | |
345 | UChar *str=NULL; | |
346 | UChar *pat=NULL; | |
347 | UChar *res=NULL; | |
348 | UErrorCode status = U_ZERO_ERROR; | |
349 | char tempBuf[256]; | |
46f4442e | 350 | |
374ca955 A |
351 | pattern=(UChar*)malloc(sizeof(UChar) * (strlen("*#,##0.00;-*#,##0.00") + 1) ); |
352 | u_uastrcpy(pattern, "*#,##0.00;-*#,##0.00"); | |
353 | pattern[0]=pattern[11]=0xa4; /* insert latin-1 currency symbol */ | |
354 | fmt = unum_open(UNUM_IGNORE,pattern, u_strlen(pattern), "en_US",NULL, &status); | |
355 | if(U_FAILURE(status)){ | |
729e4ab9 | 356 | log_err_status(status, "Error in number format construction with pattern \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status)); |
374ca955 | 357 | } |
46f4442e | 358 | lneed=0; |
374ca955 A |
359 | lneed=unum_formatDouble(fmt, 1234.56, NULL, lneed, NULL, &status); |
360 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
361 | status=U_ZERO_ERROR; | |
362 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
363 | unum_formatDouble(fmt, 1234.56, str, lneed+1, NULL, &status); | |
364 | } | |
365 | if(U_FAILURE(status)) { | |
729e4ab9 | 366 | log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); |
374ca955 A |
367 | } |
368 | lneed=0; | |
369 | lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status); | |
370 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
371 | status=U_ZERO_ERROR; | |
372 | pat=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
373 | unum_formatDouble(fmt, FALSE, pat, lneed+1, NULL, &status); | |
374 | } | |
375 | log_verbose("Pattern \" %s \" \n", u_austrcpy(tempBuf, pat)); | |
376 | log_verbose("Format 1234.56 -> %s\n", u_austrcpy(tempBuf, str) ); | |
377 | if(U_SUCCESS(status) && str) { | |
378 | res=(UChar*)malloc(sizeof(UChar) * (strlen("$1,234.56")+1) ); | |
379 | u_uastrcpy(res, "$1,234.56"); | |
729e4ab9 | 380 | if (u_strcmp(str, res) !=0) log_data_err("FAIL: Expected $1,234.56\n"); |
374ca955 | 381 | } else { |
729e4ab9 | 382 | log_err_status(status, "Error formatting -> %s\n", u_errorName(status)); |
374ca955 | 383 | } |
b75a7d8f A |
384 | free(str); |
385 | free(res); | |
374ca955 | 386 | free(pat); |
46f4442e A |
387 | |
388 | lneed=0; | |
374ca955 A |
389 | lneed=unum_formatDouble(fmt, -1234.56, NULL, lneed, NULL, &status); |
390 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
391 | status=U_ZERO_ERROR; | |
392 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
393 | unum_formatDouble(fmt, -1234.56, str, lneed+1, NULL, &status); | |
394 | } | |
395 | if(U_FAILURE(status)) { | |
729e4ab9 | 396 | log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); |
374ca955 A |
397 | } |
398 | if(str) { | |
399 | res=(UChar*)malloc(sizeof(UChar) * (strlen("-$1,234.56")+1) ); | |
400 | u_uastrcpy(res, "-$1,234.56"); | |
729e4ab9 | 401 | if (u_strcmp(str, res) != 0) log_data_err("FAIL: Expected -$1,234.56\n"); |
374ca955 A |
402 | free(str); |
403 | free(res); | |
404 | } | |
46f4442e A |
405 | |
406 | unum_close(fmt); | |
374ca955 | 407 | free(pattern); |
b75a7d8f A |
408 | } |
409 | ||
410 | /** | |
411 | * Test localized currency patterns. | |
412 | */ | |
413 | static void TestCurrency(void) | |
414 | { | |
374ca955 A |
415 | UNumberFormat *currencyFmt; |
416 | UChar *str; | |
417 | int32_t lneed, i; | |
418 | UFieldPosition pos; | |
419 | UChar res[100]; | |
420 | UErrorCode status = U_ZERO_ERROR; | |
421 | const char* locale[]={"fr_CA", "de_DE_PREEURO", "fr_FR_PREEURO"}; | |
b331163b | 422 | const char* result[]={"1,50\\u00a0$", "1,50\\u00a0DM", "1,50\\u00a0F"}; |
374ca955 A |
423 | log_verbose("\nTesting the number format with different currency patterns\n"); |
424 | for(i=0; i < 3; i++) | |
b75a7d8f | 425 | { |
374ca955 A |
426 | str=NULL; |
427 | currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status); | |
73c04bcf | 428 | |
374ca955 | 429 | if(U_FAILURE(status)){ |
729e4ab9 | 430 | log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n", |
374ca955 | 431 | myErrorName(status)); |
73c04bcf A |
432 | } else { |
433 | lneed=0; | |
434 | lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status); | |
435 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
436 | status=U_ZERO_ERROR; | |
437 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
438 | pos.field = 0; | |
439 | unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status); | |
440 | } | |
441 | ||
442 | if(U_FAILURE(status)) { | |
443 | log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); | |
444 | } else { | |
46f4442e | 445 | u_unescape(result[i], res, (int32_t)strlen(result[i])+1); |
73c04bcf A |
446 | |
447 | if (u_strcmp(str, res) != 0){ | |
448 | log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i], aescstrdup(str, -1), locale[i]); | |
449 | } | |
450 | } | |
374ca955 | 451 | } |
73c04bcf | 452 | |
374ca955 A |
453 | unum_close(currencyFmt); |
454 | free(str); | |
b75a7d8f A |
455 | } |
456 | } | |
457 | /** | |
458 | * Test localized currency patterns for PREEURO variants. | |
459 | */ | |
460 | static void TestCurrencyPreEuro(void) | |
461 | { | |
374ca955 A |
462 | UNumberFormat *currencyFmt; |
463 | UChar *str=NULL, *res=NULL; | |
464 | int32_t lneed, i; | |
465 | UFieldPosition pos; | |
466 | UErrorCode status = U_ZERO_ERROR; | |
46f4442e | 467 | |
374ca955 | 468 | const char* locale[]={ |
46f4442e A |
469 | "ca_ES_PREEURO", "de_LU_PREEURO", "en_IE_PREEURO", "fi_FI_PREEURO", "fr_LU_PREEURO", "it_IT_PREEURO", |
470 | "pt_PT_PREEURO", "de_AT_PREEURO", "el_GR_PREEURO", "es_ES_PREEURO", "fr_BE_PREEURO", "ga_IE_PREEURO", | |
471 | "nl_BE_PREEURO", "de_DE_PREEURO", "en_BE_PREEURO", "eu_ES_PREEURO", "fr_FR_PREEURO", "gl_ES_PREEURO", | |
b75a7d8f | 472 | "nl_NL_PREEURO", |
374ca955 | 473 | }; |
46f4442e | 474 | |
0f5d89e8 | 475 | const char* result[]={ // ICU 61 behavior |
b331163b A |
476 | "\\u20A7\\u00A02", "2\\u00A0F", "IEP1.50", "1,50\\u00A0mk", "2\\u00A0F", "ITL\\u00A02", |
477 | "1$50\\u00A0\\u200B", "\\u00F6S\\u00A01,50", "1,50\\u00A0\\u0394\\u03C1\\u03C7", "2\\u00A0\\u20A7", "1,50\\u00A0FB", "IEP1.50", | |
478 | "1,50\\u00A0BEF", "1,50\\u00A0DM", "1,50\\u00A0BEF", "\\u20A7\\u00A02", "1,50\\u00A0F", "2\\u00A0\\u20A7", | |
4388f060 | 479 | "NLG\\u00A01,50" |
374ca955 | 480 | }; |
46f4442e | 481 | |
374ca955 A |
482 | log_verbose("\nTesting the number format with different currency patterns\n"); |
483 | for(i=0; i < 19; i++) | |
b75a7d8f | 484 | { |
374ca955 A |
485 | char curID[256] = {0}; |
486 | uloc_canonicalize(locale[i], curID, 256, &status); | |
487 | if(U_FAILURE(status)){ | |
729e4ab9 | 488 | log_data_err("Could not canonicalize %s. Error: %s (Are you missing data?)\n", locale[i], u_errorName(status)); |
374ca955 A |
489 | continue; |
490 | } | |
491 | currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status); | |
73c04bcf | 492 | |
374ca955 | 493 | if(U_FAILURE(status)){ |
729e4ab9 | 494 | log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n", |
374ca955 | 495 | myErrorName(status)); |
73c04bcf A |
496 | } else { |
497 | lneed=0; | |
498 | lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status); | |
499 | ||
500 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
501 | status=U_ZERO_ERROR; | |
502 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
503 | pos.field = 0; | |
504 | unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status); | |
505 | } | |
506 | ||
507 | if(U_FAILURE(status)) { | |
508 | log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); | |
509 | } else { | |
510 | res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) ); | |
511 | u_unescape(result[i],res,(int32_t)(strlen(result[i])+1)); | |
512 | ||
513 | if (u_strcmp(str, res) != 0){ | |
514 | log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]); | |
515 | } | |
516 | } | |
374ca955 | 517 | } |
46f4442e | 518 | |
374ca955 A |
519 | unum_close(currencyFmt); |
520 | free(str); | |
521 | free(res); | |
b75a7d8f A |
522 | } |
523 | } | |
524 | ||
525 | /** | |
526 | * Test currency "object" (we use this name to match the other C++ | |
527 | * test name and the Jave name). Actually, test ISO currency code | |
528 | * support in the C API. | |
529 | */ | |
530 | static void TestCurrencyObject(void) | |
531 | { | |
374ca955 A |
532 | UNumberFormat *currencyFmt; |
533 | UChar *str=NULL, *res=NULL; | |
534 | int32_t lneed, i; | |
535 | UFieldPosition pos; | |
536 | UErrorCode status = U_ZERO_ERROR; | |
46f4442e | 537 | |
374ca955 A |
538 | const char* locale[]={ |
539 | "fr_FR", | |
46f4442e | 540 | "fr_FR", |
374ca955 | 541 | }; |
46f4442e | 542 | |
374ca955 A |
543 | const char* currency[]={ |
544 | "", | |
46f4442e | 545 | "JPY", |
374ca955 | 546 | }; |
46f4442e | 547 | |
374ca955 | 548 | const char* result[]={ |
46f4442e | 549 | "1\\u00A0234,56\\u00A0\\u20AC", |
b331163b | 550 | "1\\u00A0235\\u00A0JPY", |
374ca955 | 551 | }; |
46f4442e | 552 | |
374ca955 A |
553 | log_verbose("\nTesting the number format with different currency codes\n"); |
554 | for(i=0; i < 2; i++) | |
b75a7d8f | 555 | { |
374ca955 A |
556 | char cStr[20]={0}; |
557 | UChar isoCode[16]={0}; | |
558 | currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status); | |
559 | if(U_FAILURE(status)){ | |
729e4ab9 | 560 | log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n", |
374ca955 | 561 | myErrorName(status)); |
73c04bcf A |
562 | } else { |
563 | if (*currency[i]) { | |
564 | u_uastrcpy(isoCode, currency[i]); | |
565 | unum_setTextAttribute(currencyFmt, UNUM_CURRENCY_CODE, | |
566 | isoCode, u_strlen(isoCode), &status); | |
567 | ||
568 | if(U_FAILURE(status)) { | |
569 | log_err("FAIL: can't set currency code %s\n", myErrorName(status) ); | |
570 | } | |
571 | } | |
572 | ||
573 | unum_getTextAttribute(currencyFmt, UNUM_CURRENCY_CODE, | |
574 | isoCode, sizeof(isoCode), &status); | |
575 | ||
374ca955 | 576 | if(U_FAILURE(status)) { |
73c04bcf A |
577 | log_err("FAIL: can't get currency code %s\n", myErrorName(status) ); |
578 | } | |
579 | ||
580 | u_UCharsToChars(isoCode,cStr,u_strlen(isoCode)); | |
581 | log_verbose("ISO code %s\n", cStr); | |
582 | if (*currency[i] && uprv_strcmp(cStr, currency[i])) { | |
583 | log_err("FAIL: currency should be %s, but is %s\n", currency[i], cStr); | |
584 | } | |
46f4442e | 585 | |
73c04bcf A |
586 | lneed=0; |
587 | lneed= unum_formatDouble(currencyFmt, 1234.56, NULL, lneed, NULL, &status); | |
588 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
589 | status=U_ZERO_ERROR; | |
590 | str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
591 | pos.field = 0; | |
592 | unum_formatDouble(currencyFmt, 1234.56, str, lneed+1, &pos, &status); | |
593 | } | |
594 | if(U_FAILURE(status)) { | |
595 | log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); | |
596 | } else { | |
597 | res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) ); | |
598 | u_unescape(result[i],res, (int32_t)(strlen(result[i])+1)); | |
599 | if (u_strcmp(str, res) != 0){ | |
600 | log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]); | |
601 | } | |
374ca955 | 602 | } |
374ca955 | 603 | } |
46f4442e | 604 | |
374ca955 A |
605 | unum_close(currencyFmt); |
606 | free(str); | |
607 | free(res); | |
b75a7d8f A |
608 | } |
609 | } | |
610 | ||
611 | /** | |
612 | * Test proper rounding by the format method. | |
613 | */ | |
614 | static void TestRounding487(void) | |
615 | { | |
374ca955 A |
616 | UNumberFormat *nnf; |
617 | UErrorCode status = U_ZERO_ERROR; | |
46f4442e | 618 | /* this is supposed to open default date format, but later on it treats it like it is "en_US" |
b75a7d8f | 619 | - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ |
374ca955 A |
620 | /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */ |
621 | nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status); | |
73c04bcf | 622 | |
374ca955 | 623 | if(U_FAILURE(status)){ |
729e4ab9 | 624 | log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status)); |
73c04bcf A |
625 | } else { |
626 | roundingTest(nnf, 0.00159999, 4, "0.0016"); | |
627 | roundingTest(nnf, 0.00995, 4, "0.01"); | |
46f4442e | 628 | |
73c04bcf | 629 | roundingTest(nnf, 12.3995, 3, "12.4"); |
46f4442e | 630 | |
73c04bcf A |
631 | roundingTest(nnf, 12.4999, 0, "12"); |
632 | roundingTest(nnf, - 19.5, 0, "-20"); | |
374ca955 | 633 | } |
73c04bcf | 634 | |
374ca955 | 635 | unum_close(nnf); |
b75a7d8f | 636 | } |
46f4442e | 637 | |
b75a7d8f | 638 | /*-------------------------------------*/ |
46f4442e | 639 | |
b75a7d8f A |
640 | static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits, const char* expected) |
641 | { | |
374ca955 A |
642 | UChar *out = NULL; |
643 | UChar *res; | |
644 | UFieldPosition pos; | |
645 | UErrorCode status; | |
646 | int32_t lneed; | |
b75a7d8f | 647 | status=U_ZERO_ERROR; |
374ca955 A |
648 | unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, maxFractionDigits); |
649 | lneed=0; | |
650 | lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status); | |
651 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
652 | status=U_ZERO_ERROR; | |
653 | out=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
654 | pos.field=0; | |
655 | unum_formatDouble(nf, x, out, lneed+1, &pos, &status); | |
656 | } | |
657 | if(U_FAILURE(status)) { | |
658 | log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); | |
659 | } | |
660 | /*Need to use log_verbose here. Problem with the float*/ | |
661 | /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/ | |
662 | res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) ); | |
663 | u_uastrcpy(res, expected); | |
664 | if (u_strcmp(out, res) != 0) | |
665 | log_err("FAIL: Expected: %s or %s\n", expected, austrdup(res) ); | |
666 | free(res); | |
667 | if(out != NULL) { | |
668 | free(out); | |
669 | } | |
b75a7d8f A |
670 | } |
671 | ||
672 | /* | |
46f4442e | 673 | * Testing unum_getDoubleAttribute and unum_setDoubleAttribute() |
b75a7d8f A |
674 | */ |
675 | static void TestDoubleAttribute(void) | |
676 | { | |
677 | double mydata[] = { 1.11, 22.22, 333.33, 4444.44, 55555.55, 666666.66, 7777777.77, 88888888.88, 999999999.99}; | |
678 | double dvalue; | |
679 | int i; | |
680 | UErrorCode status=U_ZERO_ERROR; | |
681 | UNumberFormatAttribute attr; | |
682 | UNumberFormatStyle style= UNUM_DEFAULT; | |
683 | UNumberFormat *def; | |
73c04bcf | 684 | |
b75a7d8f | 685 | log_verbose("\nTesting get and set DoubleAttributes\n"); |
73c04bcf A |
686 | def=unum_open(style, NULL,0,NULL,NULL, &status); |
687 | ||
688 | if (U_FAILURE(status)) { | |
729e4ab9 | 689 | log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status)); |
73c04bcf A |
690 | } else { |
691 | attr=UNUM_ROUNDING_INCREMENT; | |
692 | dvalue=unum_getDoubleAttribute(def, attr); | |
693 | for (i = 0; i<9 ; i++) | |
694 | { | |
46f4442e | 695 | dvalue = mydata[i]; |
73c04bcf A |
696 | unum_setDoubleAttribute(def, attr, dvalue); |
697 | if(unum_getDoubleAttribute(def,attr)!=mydata[i]) | |
698 | log_err("Fail: error in setting and getting double attributes for UNUM_ROUNDING_INCREMENT\n"); | |
699 | else | |
700 | log_verbose("Pass: setting and getting double attributes for UNUM_ROUNDING_INCREMENT works fine\n"); | |
701 | } | |
b75a7d8f | 702 | } |
73c04bcf | 703 | |
b75a7d8f A |
704 | unum_close(def); |
705 | } | |
706 | ||
707 | /** | |
708 | * Test the functioning of the secondary grouping value. | |
709 | */ | |
710 | static void TestSecondaryGrouping(void) { | |
711 | UErrorCode status = U_ZERO_ERROR; | |
712 | UNumberFormat *f = NULL, *g= NULL; | |
713 | UNumberFormat *us = unum_open(UNUM_DECIMAL,NULL,0, "en_US", NULL,&status); | |
714 | UFieldPosition pos; | |
715 | UChar resultBuffer[512]; | |
716 | int32_t l = 1876543210L; | |
717 | UBool ok = TRUE; | |
718 | UChar buffer[512]; | |
719 | int32_t i; | |
720 | UBool expectGroup = FALSE, isGroup = FALSE; | |
721 | ||
722 | u_uastrcpy(buffer, "#,##,###"); | |
723 | f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status); | |
729e4ab9 A |
724 | if (U_FAILURE(status)) { |
725 | log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status)); | |
726 | return; | |
727 | } | |
b75a7d8f A |
728 | |
729 | pos.field = 0; | |
730 | unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status); | |
731 | u_uastrcpy(buffer, "12,34,56,789"); | |
732 | if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) | |
733 | { | |
0f5d89e8 | 734 | log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,34,56,789"); |
b75a7d8f A |
735 | } |
736 | if (pos.beginIndex != 0 && pos.endIndex != 12) { | |
737 | log_err("Fail: Formatting \"#,##,###\" pattern pos = (%d, %d) expected pos = (0, 12)\n", pos.beginIndex, pos.endIndex); | |
738 | } | |
739 | memset(resultBuffer,0, sizeof(UChar)*512); | |
740 | unum_toPattern(f, FALSE, resultBuffer, 512, &status); | |
0f5d89e8 | 741 | u_uastrcpy(buffer, "#,##,###"); // ICU 61 behavior |
b75a7d8f A |
742 | if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) |
743 | { | |
0f5d89e8 | 744 | log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,##,###"); |
b75a7d8f A |
745 | } |
746 | memset(resultBuffer,0, sizeof(UChar)*512); | |
747 | u_uastrcpy(buffer, "#,###"); | |
748 | unum_applyPattern(f, FALSE, buffer, -1,NULL,NULL); | |
749 | if (U_FAILURE(status)) | |
750 | { | |
751 | log_err("Fail: applyPattern call failed\n"); | |
752 | } | |
753 | unum_setAttribute(f, UNUM_SECONDARY_GROUPING_SIZE, 4); | |
754 | unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status); | |
755 | u_uastrcpy(buffer, "12,3456,789"); | |
756 | if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) | |
757 | { | |
0f5d89e8 | 758 | log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,3456,789"); |
b75a7d8f A |
759 | } |
760 | memset(resultBuffer,0, sizeof(UChar)*512); | |
761 | unum_toPattern(f, FALSE, resultBuffer, 512, &status); | |
0f5d89e8 | 762 | u_uastrcpy(buffer, "#,####,###"); // ICU 61 behavior |
b75a7d8f A |
763 | if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) |
764 | { | |
0f5d89e8 | 765 | log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,####,###"); |
b75a7d8f A |
766 | } |
767 | memset(resultBuffer,0, sizeof(UChar)*512); | |
768 | g = unum_open(UNUM_DECIMAL, NULL,0,"hi_IN",NULL, &status); | |
769 | if (U_FAILURE(status)) | |
770 | { | |
771 | log_err("Fail: Cannot create UNumberFormat for \"hi_IN\" locale.\n"); | |
772 | } | |
773 | ||
774 | unum_format(g, l, resultBuffer, 512, &pos, &status); | |
775 | unum_close(g); | |
776 | /* expect "1,87,65,43,210", but with Hindi digits */ | |
777 | /* 01234567890123 */ | |
778 | if (u_strlen(resultBuffer) != 14) { | |
779 | ok = FALSE; | |
780 | } else { | |
781 | for (i=0; i<u_strlen(resultBuffer); ++i) { | |
782 | expectGroup = FALSE; | |
783 | switch (i) { | |
784 | case 1: | |
785 | case 4: | |
786 | case 7: | |
787 | case 10: | |
788 | expectGroup = TRUE; | |
789 | break; | |
790 | } | |
791 | /* Later -- fix this to get the actual grouping */ | |
792 | /* character from the resource bundle. */ | |
793 | isGroup = (UBool)(resultBuffer[i] == 0x002C); | |
794 | if (isGroup != expectGroup) { | |
795 | ok = FALSE; | |
796 | break; | |
797 | } | |
798 | } | |
799 | } | |
800 | if (!ok) { | |
801 | log_err("FAIL Expected %s x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got %s\n", "1876543210L", resultBuffer); | |
46f4442e | 802 | } |
b75a7d8f A |
803 | unum_close(f); |
804 | unum_close(us); | |
805 | } | |
806 | ||
374ca955 A |
807 | static void TestCurrencyKeywords(void) |
808 | { | |
46f4442e | 809 | static const char * const currencies[] = { |
374ca955 A |
810 | "ADD", "ADP", "AED", "AFA", "AFN", "AIF", "ALK", "ALL", "ALV", "ALX", "AMD", |
811 | "ANG", "AOA", "AOK", "AON", "AOR", "AOS", "ARA", "ARM", "ARP", "ARS", "ATS", | |
812 | "AUD", "AUP", "AWG", "AZM", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", | |
813 | "BEL", "BGL", "BGM", "BGN", "BGO", "BGX", "BHD", "BIF", "BMD", "BMP", "BND", | |
814 | "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", | |
815 | "BSD", "BSP", "BTN", "BTR", "BUK", "BUR", "BWP", "BYB", "BYL", "BYR", "BZD", | |
816 | "BZH", "CAD", "CDF", "CDG", "CDL", "CFF", "CHF", "CKD", "CLC", "CLE", "CLF", | |
817 | "CLP", "CMF", "CNP", "CNX", "CNY", "COB", "COF", "COP", "CRC", "CSC", "CSK", | |
46f4442e A |
818 | "CUP", "CUX", "CVE", "CWG", "CYP", "CZK", "DDM", "DEM", "DES", "DJF", "DKK", |
819 | "DOP", "DZD", "DZF", "DZG", "ECS", "ECV", "EEK", "EGP", "ERN", "ESP", "ETB", | |
820 | "ETD", "EUR", "FIM", "FIN", "FJD", "FJP", "FKP", "FOK", "FRF", "FRG", "GAF", | |
821 | "GBP", "GEK", "GEL", "GHC", "GHO", "GHP", "GHR", "GIP", "GLK", "GMD", "GMP", | |
822 | "GNF", "GNI", "GNS", "GPF", "GQE", "GQF", "GQP", "GRD", "GRN", "GTQ", "GUF", | |
823 | "GWE", "GWM", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IBP", | |
824 | "IDG", "IDJ", "IDN", "IDR", "IEP", "ILL", "ILP", "ILS", "IMP", "INR", "IQD", | |
825 | "IRR", "ISK", "ITL", "JEP", "JMD", "JMP", "JOD", "JPY", "KES", "KGS", "KHO", | |
826 | "KHR", "KID", "KMF", "KPP", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZR", | |
827 | "KZT", "LAK", "LBP", "LIF", "LKR", "LNR", "LRD", "LSL", "LTL", "LTT", "LUF", | |
828 | "LVL", "LVR", "LYB", "LYD", "LYP", "MAD", "MAF", "MCF", "MCG", "MDC", "MDL", | |
829 | "MDR", "MGA", "MGF", "MHD", "MKD", "MKN", "MLF", "MMK", "MMX", "MNT", "MOP", | |
830 | "MQF", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MWP", "MXN", "MXP", | |
831 | "MXV", "MYR", "MZE", "MZM", "NAD", "NCF", "NGN", "NGP", "NHF", "NIC", "NIG", | |
832 | "NIO", "NLG", "NOK", "NPR", "NZD", "NZP", "OMR", "OMS", "PAB", "PDK", "PDN", | |
833 | "PDR", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLX", "PLZ", "PSP", | |
834 | "PTC", "PTE", "PYG", "QAR", "REF", "ROL", "RON", "RUB", "RUR", "RWF", "SAR", | |
835 | "SAS", "SBD", "SCR", "SDD", "SDP", "SEK", "SGD", "SHP", "SIB", "SIT", "SKK", | |
836 | "SLL", "SML", "SOS", "SQS", "SRG", "SSP", "STD", "STE", "SUN", "SUR", "SVC", | |
837 | "SYP", "SZL", "TCC", "TDF", "THB", "TJR", "TJS", "TMM", "TND", "TOP", "TOS", | |
838 | "TPE", "TPP", "TRL", "TTD", "TTO", "TVD", "TWD", "TZS", "UAH", "UAK", "UGS", | |
839 | "UGX", "USD", "USN", "USS", "UYF", "UYP", "UYU", "UZC", "UZS", "VAL", "VDD", | |
840 | "VDN", "VDP", "VEB", "VGD", "VND", "VNN", "VNR", "VNS", "VUV", "WSP", "WST", | |
841 | "XAD", "XAF", "XAM", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XCF", "XDR", | |
842 | "XEF", "XEU", "XFO", "XFU", "XID", "XMF", "XNF", "XOF", "XPF", "XPS", "XSS", | |
843 | "XTR", "YDD", "YEI", "YER", "YUD", "YUF", "YUG", "YUM", "YUN", "YUO", "YUR", | |
374ca955 A |
844 | "ZAL", "ZAP", "ZAR", "ZMK", "ZMP", "ZRN", "ZRZ", "ZWD" |
845 | }; | |
46f4442e | 846 | |
374ca955 A |
847 | UErrorCode status = U_ZERO_ERROR; |
848 | int32_t i = 0, j = 0; | |
849 | int32_t noLocales = uloc_countAvailable(); | |
850 | char locale[256]; | |
851 | char currLoc[256]; | |
852 | UChar result[4]; | |
853 | UChar currBuffer[256]; | |
46f4442e A |
854 | |
855 | ||
374ca955 A |
856 | for(i = 0; i < noLocales; i++) { |
857 | strcpy(currLoc, uloc_getAvailable(i)); | |
2ca993e8 | 858 | for(j = 0; j < UPRV_LENGTHOF(currencies); j++) { |
374ca955 A |
859 | strcpy(locale, currLoc); |
860 | strcat(locale, "@currency="); | |
861 | strcat(locale, currencies[j]); | |
862 | ucurr_forLocale(locale, result, 4, &status); | |
863 | u_charsToUChars(currencies[j], currBuffer, 3); | |
864 | currBuffer[3] = 0; | |
865 | if(u_strcmp(currBuffer, result) != 0) { | |
866 | log_err("Didn't get the right currency for %s\n", locale); | |
867 | } | |
868 | } | |
46f4442e A |
869 | |
870 | } | |
871 | } | |
872 | ||
729e4ab9 | 873 | static void TestGetKeywordValuesForLocale(void) { |
2ca993e8 | 874 | #define PREFERRED_SIZE 15 |
4388f060 | 875 | #define MAX_NUMBER_OF_KEYWORDS 4 |
729e4ab9 | 876 | const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = { |
b331163b A |
877 | { "root", "USD", "USN", NULL }, |
878 | { "und", "USD", "USN", NULL }, | |
879 | /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */ | |
880 | { "en_US", "USD", "USN", NULL }, | |
881 | { "en_029", "USD", "USN", NULL }, | |
4388f060 A |
882 | { "en_TH", "THB", NULL, NULL }, |
883 | { "de", "EUR", NULL, NULL }, | |
884 | { "de_DE", "EUR", NULL, NULL }, | |
885 | { "ar", "EGP", NULL, NULL }, | |
51004dcb | 886 | { "ar_PS", "ILS", "JOD", NULL }, |
b331163b | 887 | { "en@currency=CAD", "USD", "USN", NULL }, |
4388f060 A |
888 | { "fr@currency=zzz", "EUR", NULL, NULL }, |
889 | { "de_DE@currency=DEM", "EUR", NULL, NULL }, | |
2ca993e8 A |
890 | { "en_US@rg=THZZZZ", "THB", NULL, NULL }, |
891 | { "de@rg=USZZZZ", "USD", "USN", NULL }, | |
892 | { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, | |
729e4ab9 A |
893 | }; |
894 | const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { | |
2ca993e8 A |
895 | 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 |
896 | }; | |
897 | /* ucurr_forLocale results for same locales; "" if no result expected */ | |
898 | const char *FORLOCALE[PREFERRED_SIZE] = { | |
899 | "", "", "USD", "", | |
900 | "THB", "", "EUR", "", | |
901 | "ILS", "CAD", "ZZZ", "DEM", | |
902 | "THB", "USD", "CAD" | |
729e4ab9 A |
903 | }; |
904 | UErrorCode status = U_ZERO_ERROR; | |
905 | int32_t i, j, size; | |
906 | UEnumeration *pref, *all; | |
907 | const char *loc = NULL; | |
908 | UBool matchPref, matchAll; | |
909 | const char *value = NULL; | |
910 | int32_t valueLength = 0; | |
911 | ||
912 | UList *ALLList = NULL; | |
913 | ||
914 | UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status); | |
915 | if (ALL == NULL) { | |
916 | log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status)); | |
917 | return; | |
918 | } | |
919 | ||
920 | for (i = 0; i < PREFERRED_SIZE; i++) { | |
2ca993e8 A |
921 | UChar getCurrU[4]; |
922 | int32_t getCurrLen; | |
923 | ||
924 | status = U_ZERO_ERROR; | |
729e4ab9 A |
925 | pref = NULL; |
926 | all = NULL; | |
927 | loc = PREFERRED[i][0]; | |
928 | pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status); | |
929 | matchPref = FALSE; | |
930 | matchAll = FALSE; | |
931 | ||
932 | size = uenum_count(pref, &status); | |
933 | ||
934 | if (size == EXPECTED_SIZE[i]) { | |
935 | matchPref = TRUE; | |
936 | for (j = 0; j < size; j++) { | |
937 | if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) { | |
938 | if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) { | |
939 | log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]); | |
940 | ||
941 | matchPref = FALSE; | |
942 | break; | |
943 | } | |
944 | } else { | |
945 | matchPref = FALSE; | |
946 | log_err("ERROR getting keyword value for locale \"%s\"\n", loc); | |
947 | break; | |
948 | } | |
949 | } | |
950 | } else { | |
951 | log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]); | |
952 | } | |
953 | ||
954 | if (!matchPref) { | |
955 | log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc); | |
956 | break; | |
957 | } | |
958 | uenum_close(pref); | |
959 | ||
960 | all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status); | |
961 | ||
962 | size = uenum_count(all, &status); | |
963 | ||
964 | if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) { | |
965 | matchAll = TRUE; | |
966 | ALLList = ulist_getListFromEnum(ALL); | |
967 | for (j = 0; j < size; j++) { | |
968 | if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) { | |
969 | if (!ulist_containsString(ALLList, value, uprv_strlen(value))) { | |
970 | log_err("Locale %s have %s not in ALL\n", loc, value); | |
971 | matchAll = FALSE; | |
972 | break; | |
973 | } | |
974 | } else { | |
975 | matchAll = FALSE; | |
976 | log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc); | |
977 | break; | |
978 | } | |
979 | } | |
980 | if (!matchAll) { | |
981 | log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc); | |
982 | } | |
983 | } else { | |
984 | if(U_FAILURE(status)) { | |
985 | log_err("ERROR: %s\n", u_errorName(status)); | |
986 | } else if(size!=uenum_count(ALL, &status)) { | |
987 | log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status)); | |
988 | } | |
989 | } | |
990 | ||
991 | uenum_close(all); | |
2ca993e8 A |
992 | |
993 | status = U_ZERO_ERROR; | |
994 | getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status); | |
995 | if(U_FAILURE(status)) { | |
996 | if (FORLOCALE[i][0] != 0) { | |
997 | log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status)); | |
998 | } | |
999 | } else if (getCurrLen != 3) { | |
1000 | if (FORLOCALE[i][0] != 0 || getCurrLen != -1) { | |
1001 | log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen); | |
1002 | } | |
1003 | } else { | |
1004 | char getCurrB[4]; | |
1005 | u_UCharsToChars(getCurrU, getCurrB, 4); | |
1006 | if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) { | |
1007 | log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB); | |
1008 | } | |
1009 | } | |
729e4ab9 A |
1010 | } |
1011 | ||
1012 | uenum_close(ALL); | |
1013 | ||
1014 | } | |
1015 | ||
46f4442e A |
1016 | /** |
1017 | * Test proper handling of rounding modes. | |
1018 | */ | |
1019 | static void TestRounding5350(void) | |
1020 | { | |
1021 | UNumberFormat *nnf; | |
1022 | UErrorCode status = U_ZERO_ERROR; | |
1023 | /* this is supposed to open default date format, but later on it treats it like it is "en_US" | |
1024 | - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ | |
1025 | /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */ | |
1026 | nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status); | |
1027 | ||
1028 | if(U_FAILURE(status)){ | |
729e4ab9 | 1029 | log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status)); |
46f4442e A |
1030 | return; |
1031 | } | |
1032 | ||
1033 | unum_setAttribute(nnf, UNUM_MAX_FRACTION_DIGITS, 2); | |
1034 | roundingTest2(nnf, -0.125, UNUM_ROUND_CEILING, "-0.12"); | |
1035 | roundingTest2(nnf, -0.125, UNUM_ROUND_FLOOR, "-0.13"); | |
1036 | roundingTest2(nnf, -0.125, UNUM_ROUND_DOWN, "-0.12"); | |
1037 | roundingTest2(nnf, -0.125, UNUM_ROUND_UP, "-0.13"); | |
1038 | roundingTest2(nnf, 0.125, UNUM_FOUND_HALFEVEN, "0.12"); | |
1039 | roundingTest2(nnf, 0.135, UNUM_ROUND_HALFDOWN, "0.13"); | |
1040 | roundingTest2(nnf, 0.125, UNUM_ROUND_HALFUP, "0.13"); | |
1041 | roundingTest2(nnf, 0.135, UNUM_FOUND_HALFEVEN, "0.14"); | |
1042 | /* The following are exactly represented, and shouldn't round */ | |
1043 | roundingTest2(nnf, 1.00, UNUM_ROUND_UP, "1"); | |
1044 | roundingTest2(nnf, 24.25, UNUM_ROUND_UP, "24.25"); | |
1045 | roundingTest2(nnf, 24.25, UNUM_ROUND_CEILING, "24.25"); | |
1046 | roundingTest2(nnf, -24.25, UNUM_ROUND_UP, "-24.25"); | |
1047 | ||
1048 | /* Differences pretty far out there */ | |
1049 | roundingTest2(nnf, 1.0000001, UNUM_ROUND_CEILING, "1.01"); | |
1050 | roundingTest2(nnf, 1.0000001, UNUM_ROUND_FLOOR, "1"); | |
1051 | roundingTest2(nnf, 1.0000001, UNUM_ROUND_DOWN, "1"); | |
1052 | roundingTest2(nnf, 1.0000001, UNUM_ROUND_UP, "1.01"); | |
1053 | roundingTest2(nnf, 1.0000001, UNUM_FOUND_HALFEVEN, "1"); | |
1054 | roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFDOWN, "1"); | |
1055 | roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFUP, "1"); | |
1056 | ||
1057 | roundingTest2(nnf, -1.0000001, UNUM_ROUND_CEILING, "-1"); | |
1058 | roundingTest2(nnf, -1.0000001, UNUM_ROUND_FLOOR, "-1.01"); | |
1059 | roundingTest2(nnf, -1.0000001, UNUM_ROUND_DOWN, "-1"); | |
1060 | roundingTest2(nnf, -1.0000001, UNUM_ROUND_UP, "-1.01"); | |
1061 | roundingTest2(nnf, -1.0000001, UNUM_FOUND_HALFEVEN, "-1"); | |
1062 | roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFDOWN, "-1"); | |
1063 | roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFUP, "-1"); | |
1064 | ||
1065 | unum_close(nnf); | |
1066 | } | |
1067 | ||
1068 | /*-------------------------------------*/ | |
1069 | ||
1070 | static void roundingTest2(UNumberFormat* nf, double x, int32_t roundingMode, const char* expected) | |
1071 | { | |
1072 | UChar *out = NULL; | |
1073 | UChar *res; | |
1074 | UFieldPosition pos; | |
1075 | UErrorCode status; | |
1076 | int32_t lneed; | |
1077 | status=U_ZERO_ERROR; | |
1078 | unum_setAttribute(nf, UNUM_ROUNDING_MODE, roundingMode); | |
1079 | lneed=0; | |
1080 | lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status); | |
1081 | if(status==U_BUFFER_OVERFLOW_ERROR){ | |
1082 | status=U_ZERO_ERROR; | |
1083 | out=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); | |
1084 | pos.field=0; | |
1085 | unum_formatDouble(nf, x, out, lneed+1, &pos, &status); | |
1086 | } | |
1087 | if(U_FAILURE(status)) { | |
1088 | log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); | |
1089 | } | |
1090 | /*Need to use log_verbose here. Problem with the float*/ | |
1091 | /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/ | |
1092 | res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) ); | |
1093 | u_uastrcpy(res, expected); | |
1094 | if (u_strcmp(out, res) != 0) | |
1095 | log_err("FAIL: Expected: \"%s\" Got: \"%s\"\n", expected, austrdup(out) ); | |
1096 | free(res); | |
1097 | if(out != NULL) { | |
1098 | free(out); | |
374ca955 A |
1099 | } |
1100 | } | |
1101 | ||
b75a7d8f | 1102 | #endif /* #if !UCONFIG_NO_FORMATTING */ |