1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation
6 * and others. All Rights Reserved.
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
26 #include "unicode/ucurr.h"
27 #include "unicode/uloc.h"
28 #include "unicode/unum.h"
29 #include "unicode/ustring.h"
30 #include "unicode/putil.h"
31 #include "cintltst.h"
32 #include "cnmdptst.h"
33 #include "cmemory.h"
34 #include "cstring.h"
35 #include "ulist.h"
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
addNumFrDepTest(TestNode ** root)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");
55 addTest(root, &TestCurrencyKeywords, "tsformat/cnmdptst/TestCurrencyKeywords");
56 addTest(root, &TestRounding5350, "tsformat/cnmdptst/TestRounding5350");
57 addTest(root, &TestGetKeywordValuesForLocale, "tsformat/cnmdptst/TestGetKeywordValuesForLocale");
58 }
59
60 /*Test Various format patterns*/
TestPatterns(void)61 static void TestPatterns(void)
62 {
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[] = { "#.#", "#.", ".#", "#" };
72 const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
73 const char* num[] = { "0", "0.", ".0", "0" };
74
75 log_verbose("\nTesting different format patterns\n");
76 pat_length = UPRV_LENGTHOF(pat);
77 for (i=0; i < pat_length; ++i)
78 {
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)) {
83 log_err_status(status, "FAIL: Number format constructor failed for pattern %s -> %s\n", pat[i], u_errorName(status));
84 continue;
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) );
99
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)
112 {
113 log_err("FAIL: Pattern %s should format zero as %s; %s Seen instead\n", pat[i], num[i], austrdup(str) );
114
115 }
116 free(unewp);
117 free(str);
118 unum_close(fmt);
119 }
120 }
121
122 /* Test the handling of quotes*/
TestQuotes(void)123 static void TestQuotes(void)
124 {
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)){
136 log_err_status(status, "Error in number format costruction using pattern \"a'fo''o'b#\" -> %s\n", u_errorName(status));
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) {
146 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
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");
154
155 free(str);
156 unum_close(fmt);
157
158
159 u_uastrcpy(pat, "");
160 u_uastrcpy(pat, "a''b#");
161
162
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");
183
184 free(str);
185 unum_close(fmt);
186 }
187
188 /* Test exponential pattern*/
TestExponential(void)189 static void TestExponential(void)
190 {
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;
202 #if U_PLATFORM == U_PF_OS390
203 static const double val[] = { 0.01234, 123456789, 1.23e75, -3.141592653e-78 };
204 #else
205 static const double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
206 #endif
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 };
209
210 static const char* valFormat[] =
211 {
212 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
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]"
216 };
217 static const char* lvalFormat[] =
218 {
219 "0E0", "-1E0", "1E0", "1.2346E8",
220 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
221 "0E000", "-1E000", "1E000", "123.4568E006",
222 "0E0", "[1E0]", "1E0", "1.235E8"
223 };
224 static const double valParse[] =
225 {
226 #if U_PLATFORM == U_PF_OS390
227 0.01234, 123460000, 1.23E75, -3.1416E-78,
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
231 #else
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
238 #endif
239 };
240 static const int32_t lvalParse[] =
241 {
242 0, -1, 1, 123460000,
243 0, -1, 1, 123460000,
244 0, -1, 1, 123456800,
245 0, -1, 1, 123500000
246 };
247
248
249 pat_length = UPRV_LENGTHOF(pat);
250 val_length = UPRV_LENGTHOF(val);
251 lval_length = UPRV_LENGTHOF(lval);
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);
259 if (U_FAILURE(status)) {
260 log_err_status(status, "FAIL: Bad status returned by Number format construction with pattern %s -> %s\n", pat[p], u_errorName(status));
261 continue;
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)
267 {
268 /*format*/
269 lneed=0;
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 }
279
280
281
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) );
285
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);
295
296 free(str);
297 }
298 for (v=0; v<lval_length; ++v)
299 {
300 /*format*/
301 lneed=0;
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) );
315
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);
326
327 free(str);
328
329 }
330 ival += val_length;
331 ilval += lval_length;
332 unum_close(fmt);
333 free(upat);
334 }
335 }
336
337 /**
338 * Test the handling of the currency symbol in patterns.
339 */
TestCurrencySign(void)340 static void TestCurrencySign(void)
341 {
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];
350
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)){
356 log_err_status(status, "Error in number format construction with pattern \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status));
357 }
358 lneed=0;
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)) {
366 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
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");
380 if (u_strcmp(str, res) !=0) log_data_err("FAIL: Expected $1,234.56\n");
381 } else {
382 log_err_status(status, "Error formatting -> %s\n", u_errorName(status));
383 }
384 free(str);
385 free(res);
386 free(pat);
387
388 lneed=0;
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)) {
396 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
397 }
398 if(str) {
399 res=(UChar*)malloc(sizeof(UChar) * (strlen("-$1,234.56")+1) );
400 u_uastrcpy(res, "-$1,234.56");
401 if (u_strcmp(str, res) != 0) log_data_err("FAIL: Expected -$1,234.56\n");
402 free(str);
403 free(res);
404 }
405
406 unum_close(fmt);
407 free(pattern);
408 }
409
410 /**
411 * Test localized currency patterns.
412 */
TestCurrency(void)413 static void TestCurrency(void)
414 {
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"};
422 const char* result[]={"1,50\\u00a0$", "1,50\\u00a0DM", "1,50\\u00a0F"};
423 log_verbose("\nTesting the number format with different currency patterns\n");
424 for(i=0; i < 3; i++)
425 {
426 str=NULL;
427 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
428
429 if(U_FAILURE(status)){
430 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
431 myErrorName(status));
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 {
445 u_unescape(result[i], res, (int32_t)strlen(result[i])+1);
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 }
451 }
452
453 unum_close(currencyFmt);
454 free(str);
455 }
456 }
457 /**
458 * Test localized currency patterns for PREEURO variants.
459 */
TestCurrencyPreEuro(void)460 static void TestCurrencyPreEuro(void)
461 {
462 UNumberFormat *currencyFmt;
463 UChar *str=NULL, *res=NULL;
464 int32_t lneed, i;
465 UFieldPosition pos;
466 UErrorCode status = U_ZERO_ERROR;
467
468 const char* locale[]={
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",
472 "nl_NL_PREEURO",
473 };
474
475 const char* result[]={
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",
479 "NLG\\u00A01,50"
480 };
481
482 log_verbose("\nTesting the number format with different currency patterns\n");
483 for(i=0; i < 19; i++)
484 {
485 char curID[256] = {0};
486 uloc_canonicalize(locale[i], curID, 256, &status);
487 if(U_FAILURE(status)){
488 log_data_err("Could not canonicalize %s. Error: %s (Are you missing data?)\n", locale[i], u_errorName(status));
489 continue;
490 }
491 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status);
492
493 if(U_FAILURE(status)){
494 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
495 myErrorName(status));
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 }
517 }
518
519 unum_close(currencyFmt);
520 free(str);
521 free(res);
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 */
TestCurrencyObject(void)530 static void TestCurrencyObject(void)
531 {
532 UNumberFormat *currencyFmt;
533 UChar *str=NULL, *res=NULL;
534 int32_t lneed, i;
535 UFieldPosition pos;
536 UErrorCode status = U_ZERO_ERROR;
537
538 const char* locale[]={
539 "fr_FR",
540 "fr_FR",
541 };
542
543 const char* currency[]={
544 "",
545 "JPY",
546 };
547
548 const char* result[]={
549 "1\\u00A0234,56\\u00A0\\u20AC",
550 "1\\u00A0235\\u00A0JPY",
551 };
552
553 log_verbose("\nTesting the number format with different currency codes\n");
554 for(i=0; i < 2; i++)
555 {
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)){
560 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
561 myErrorName(status));
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
576 if(U_FAILURE(status)) {
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 }
585
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 }
602 }
603 }
604
605 unum_close(currencyFmt);
606 free(str);
607 free(res);
608 }
609 }
610
611 /**
612 * Test proper rounding by the format method.
613 */
TestRounding487(void)614 static void TestRounding487(void)
615 {
616 UNumberFormat *nnf;
617 UErrorCode status = U_ZERO_ERROR;
618 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
619 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
620 /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
621 nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
622
623 if(U_FAILURE(status)){
624 log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
625 } else {
626 roundingTest(nnf, 0.00159999, 4, "0.0016");
627 roundingTest(nnf, 0.00995, 4, "0.01");
628
629 roundingTest(nnf, 12.3995, 3, "12.4");
630
631 roundingTest(nnf, 12.4999, 0, "12");
632 roundingTest(nnf, - 19.5, 0, "-20");
633 }
634
635 unum_close(nnf);
636 }
637
638 /*-------------------------------------*/
639
roundingTest(UNumberFormat * nf,double x,int32_t maxFractionDigits,const char * expected)640 static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits, const char* expected)
641 {
642 UChar *out = NULL;
643 UChar *res;
644 UFieldPosition pos;
645 UErrorCode status;
646 int32_t lneed;
647 status=U_ZERO_ERROR;
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 }
670 }
671
672 /*
673 * Testing unum_getDoubleAttribute and unum_setDoubleAttribute()
674 */
TestDoubleAttribute(void)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;
684
685 log_verbose("\nTesting get and set DoubleAttributes\n");
686 def=unum_open(style, NULL,0,NULL,NULL, &status);
687
688 if (U_FAILURE(status)) {
689 log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status));
690 } else {
691 attr=UNUM_ROUNDING_INCREMENT;
692 dvalue=unum_getDoubleAttribute(def, attr);
693 for (i = 0; i<9 ; i++)
694 {
695 dvalue = mydata[i];
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 }
702 }
703
704 unum_close(def);
705 }
706
707 /**
708 * Test the functioning of the secondary grouping value.
709 */
TestSecondaryGrouping(void)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);
724 if (U_FAILURE(status)) {
725 log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status));
726 return;
727 }
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 {
734 log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,34,56,789");
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);
741 u_uastrcpy(buffer, "#,##,###");
742 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
743 {
744 log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,##,###");
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 {
758 log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,3456,789");
759 }
760 memset(resultBuffer,0, sizeof(UChar)*512);
761 unum_toPattern(f, FALSE, resultBuffer, 512, &status);
762 u_uastrcpy(buffer, "#,####,###");
763 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
764 {
765 log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,####,###");
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);
802 }
803 unum_close(f);
804 unum_close(us);
805 }
806
TestCurrencyKeywords(void)807 static void TestCurrencyKeywords(void)
808 {
809 static const char * const currencies[] = {
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",
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",
844 "ZAL", "ZAP", "ZAR", "ZMK", "ZMP", "ZRN", "ZRZ", "ZWD"
845 };
846
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];
854
855
856 for(i = 0; i < noLocales; i++) {
857 strcpy(currLoc, uloc_getAvailable(i));
858 for(j = 0; j < UPRV_LENGTHOF(currencies); j++) {
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 }
869
870 }
871 }
872
TestGetKeywordValuesForLocale(void)873 static void TestGetKeywordValuesForLocale(void) {
874 #define PREFERRED_SIZE 15
875 #define MAX_NUMBER_OF_KEYWORDS 4
876 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = {
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 },
882 { "en_TH", "THB", NULL, NULL },
883 { "de", "EUR", NULL, NULL },
884 { "de_DE", "EUR", NULL, NULL },
885 { "ar", "EGP", NULL, NULL },
886 { "ar_PS", "ILS", "JOD", NULL },
887 { "en@currency=CAD", "USD", "USN", NULL },
888 { "fr@currency=zzz", "EUR", NULL, NULL },
889 { "de_DE@currency=DEM", "EUR", NULL, NULL },
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 },
893 };
894 const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = {
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"
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++) {
921 UChar getCurrU[4];
922 int32_t getCurrLen;
923
924 status = U_ZERO_ERROR;
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);
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 }
1010 }
1011
1012 uenum_close(ALL);
1013
1014 }
1015
1016 /**
1017 * Test proper handling of rounding modes.
1018 */
TestRounding5350(void)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)){
1029 log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
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
roundingTest2(UNumberFormat * nf,double x,int32_t roundingMode,const char * expected)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);
1099 }
1100 }
1101
1102 #endif /* #if !UCONFIG_NO_FORMATTING */
1103