1 // © 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 <stdbool.h>
27
28 #include "unicode/ucurr.h"
29 #include "unicode/uloc.h"
30 #include "unicode/unum.h"
31 #include "unicode/ustring.h"
32 #include "unicode/putil.h"
33 #include "cintltst.h"
34 #include "cnmdptst.h"
35 #include "cmemory.h"
36 #include "cstring.h"
37 #include "ulist.h"
38
39 #define CHECK(status,str) if (U_FAILURE(status)) { log_err("FAIL: %s\n", str); return; }
40
41 void addNumFrDepTest(TestNode** root);
42 static void TestCurrencyObject(void);
43
addNumFrDepTest(TestNode ** root)44 void addNumFrDepTest(TestNode** root)
45 {
46 addTest(root, &TestPatterns, "tsformat/cnmdptst/TestPatterns");
47 addTest(root, &TestQuotes, "tsformat/cnmdptst/TestQuotes");
48 addTest(root, &TestExponential, "tsformat/cnmdptst/TestExponential");
49 addTest(root, &TestCurrencySign, "tsformat/cnmdptst/TestCurrencySign");
50 addTest(root, &TestCurrency, "tsformat/cnmdptst/TestCurrency");
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", "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 transmuted 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 construction 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 construction 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 free(upat);
262 upat = NULL;
263 continue;
264 }
265 lneed= u_strlen(upat) + 1;
266 unum_toPattern(fmt, false, pattern, lneed, &status);
267 log_verbose("Pattern \" %s \" -toPattern-> \" %s \" \n", upat, u_austrcpy(tempMsgBug, pattern) );
268 for (v=0; v<val_length; ++v)
269 {
270 /*format*/
271 lneed=0;
272 lneed=unum_formatDouble(fmt, val[v], NULL, lneed, NULL, &status);
273 if(status==U_BUFFER_OVERFLOW_ERROR){
274 status=U_ZERO_ERROR;
275 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
276 unum_formatDouble(fmt, val[v], str, lneed+1, NULL, &status);
277 }
278 if(U_FAILURE(status)) {
279 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
280 }
281
282
283
284 u_uastrcpy(uvalfor, valFormat[v+ival]);
285 if(u_strcmp(str, uvalfor) != 0)
286 log_verbose("FAIL: Expected %s ( %s )\n", valFormat[v+ival], u_austrcpy(tempMsgBug, uvalfor) );
287
288 /*parsing*/
289 ppos=0;
290 a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status);
291 if (ppos== u_strlen(str)) {
292 if (a != valParse[v+ival])
293 log_err("FAIL: Expected: %e, Got: %g\n", valParse[v+ival], a);
294 }
295 else
296 log_err(" FAIL: Partial parse ( %d chars ) -> %e\n", ppos, a);
297
298 free(str);
299 }
300 for (v=0; v<lval_length; ++v)
301 {
302 /*format*/
303 lneed=0;
304 lneed=unum_formatDouble(fmt, lval[v], NULL, lneed, NULL, &status);
305 if(status==U_BUFFER_OVERFLOW_ERROR){
306 status=U_ZERO_ERROR;
307 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
308 unum_formatDouble(fmt, lval[v], str, lneed+1, NULL, &status);
309 }
310 if(U_FAILURE(status)) {
311 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
312 }
313 /*printf(" Format %e -> %s\n", lval[v], austrdup(str) );*/
314 u_uastrcpy(ulvalfor, lvalFormat[v+ilval]);
315 if(u_strcmp(str, ulvalfor) != 0)
316 log_err("FAIL: Expected %s ( %s )\n", valFormat[v+ilval], austrdup(ulvalfor) );
317
318 /*parsing*/
319 ppos=0;
320 a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status);
321 if (ppos== u_strlen(str)) {
322 /*printf(" Parse -> %e\n", a);*/
323 if (a != lvalParse[v+ilval])
324 log_err("FAIL: Expected : %e\n", valParse[v+ival]);
325 }
326 else
327 log_err(" FAIL: Partial parse ( %d chars ) -> %e\n", ppos, a);
328
329 free(str);
330
331 }
332 ival += val_length;
333 ilval += lval_length;
334 unum_close(fmt);
335 free(upat);
336 }
337 }
338
339 /**
340 * Test the handling of the currency symbol in patterns.
341 */
TestCurrencySign(void)342 static void TestCurrencySign(void)
343 {
344 int32_t lneed;
345 UNumberFormat *fmt;
346 UChar *pattern=NULL;
347 UChar *str=NULL;
348 UChar *pat=NULL;
349 UChar *res=NULL;
350 UErrorCode status = U_ZERO_ERROR;
351 char tempBuf[256];
352
353 pattern=(UChar*)malloc(sizeof(UChar) * (strlen("*#,##0.00;-*#,##0.00") + 1) );
354 u_uastrcpy(pattern, "*#,##0.00;-*#,##0.00");
355 pattern[0]=pattern[11]=0xa4; /* insert latin-1 currency symbol */
356 fmt = unum_open(UNUM_IGNORE,pattern, u_strlen(pattern), "en_US",NULL, &status);
357 if(U_FAILURE(status)){
358 log_err_status(status, "Error in number format construction with pattern \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status));
359 }
360 lneed=0;
361 lneed=unum_formatDouble(fmt, 1234.56, NULL, lneed, NULL, &status);
362 if(status==U_BUFFER_OVERFLOW_ERROR){
363 status=U_ZERO_ERROR;
364 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
365 unum_formatDouble(fmt, 1234.56, str, lneed+1, NULL, &status);
366 }
367 if(U_FAILURE(status)) {
368 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
369 }
370 lneed=0;
371 lneed=unum_toPattern(fmt, false, NULL, lneed, &status);
372 if(status==U_BUFFER_OVERFLOW_ERROR){
373 status=U_ZERO_ERROR;
374 pat=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
375 unum_formatDouble(fmt, false, pat, lneed+1, NULL, &status);
376 }
377 log_verbose("Pattern \" %s \" \n", u_austrcpy(tempBuf, pat));
378 log_verbose("Format 1234.56 -> %s\n", u_austrcpy(tempBuf, str) );
379 if(U_SUCCESS(status) && str) {
380 res=(UChar*)malloc(sizeof(UChar) * (strlen("$1,234.56")+1) );
381 u_uastrcpy(res, "$1,234.56");
382 if (u_strcmp(str, res) !=0) log_data_err("FAIL: Expected $1,234.56\n");
383 } else {
384 log_err_status(status, "Error formatting -> %s\n", u_errorName(status));
385 }
386 free(str);
387 free(res);
388 free(pat);
389
390 lneed=0;
391 lneed=unum_formatDouble(fmt, -1234.56, NULL, lneed, NULL, &status);
392 if(status==U_BUFFER_OVERFLOW_ERROR){
393 status=U_ZERO_ERROR;
394 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
395 unum_formatDouble(fmt, -1234.56, str, lneed+1, NULL, &status);
396 }
397 if(U_FAILURE(status)) {
398 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
399 }
400 if(str) {
401 res=(UChar*)malloc(sizeof(UChar) * (strlen("-$1,234.56")+1) );
402 u_uastrcpy(res, "-$1,234.56");
403 if (u_strcmp(str, res) != 0) log_data_err("FAIL: Expected -$1,234.56\n");
404 free(str);
405 free(res);
406 }
407
408 unum_close(fmt);
409 free(pattern);
410 }
411
412 /**
413 * Test localized currency patterns.
414 */
TestCurrency(void)415 static void TestCurrency(void)
416 {
417 UNumberFormat *currencyFmt;
418 UChar *str;
419 int32_t lneed, i;
420 UFieldPosition pos;
421 UChar res[100];
422 UErrorCode status = U_ZERO_ERROR;
423 const char* locale[]={"fr_CA", "de_DE@currency=DEM", "fr_FR@currency=FRF"};
424 const char* result[]={"1,50\\u00a0$", "1,50\\u00a0DM", "1,50\\u00a0F"};
425 log_verbose("\nTesting the number format with different currency patterns\n");
426 for(i=0; i < 3; i++)
427 {
428 str=NULL;
429 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
430
431 if(U_FAILURE(status)){
432 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
433 myErrorName(status));
434 } else {
435 lneed=0;
436 lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status);
437 if(status==U_BUFFER_OVERFLOW_ERROR){
438 status=U_ZERO_ERROR;
439 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
440 pos.field = 0;
441 unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status);
442 }
443
444 if(U_FAILURE(status)) {
445 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
446 } else {
447 u_unescape(result[i], res, (int32_t)strlen(result[i])+1);
448
449 if (u_strcmp(str, res) != 0){
450 log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i], aescstrdup(str, -1), locale[i]);
451 }
452 }
453 }
454
455 unum_close(currencyFmt);
456 free(str);
457 }
458 }
459
460 /**
461 * Test currency "object" (we use this name to match the other C++
462 * test name and the Jave name). Actually, test ISO currency code
463 * support in the C API.
464 */
TestCurrencyObject(void)465 static void TestCurrencyObject(void)
466 {
467 UNumberFormat *currencyFmt;
468 UChar *str=NULL, *res=NULL;
469 int32_t lneed, i;
470 UFieldPosition pos;
471 UErrorCode status = U_ZERO_ERROR;
472
473 const char* locale[]={
474 "fr_FR",
475 "fr_FR",
476 };
477
478 const char* currency[]={
479 "",
480 "JPY",
481 };
482
483 const char* result[]={
484 "1\\u202F234,56\\u00A0\\u20AC",
485 "1\\u202F235\\u00A0JPY",
486 };
487
488 log_verbose("\nTesting the number format with different currency codes\n");
489 for(i=0; i < 2; i++)
490 {
491 char cStr[20]={0};
492 UChar isoCode[16]={0};
493 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
494 if(U_FAILURE(status)){
495 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
496 myErrorName(status));
497 } else {
498 if (*currency[i]) {
499 u_uastrcpy(isoCode, currency[i]);
500 unum_setTextAttribute(currencyFmt, UNUM_CURRENCY_CODE,
501 isoCode, u_strlen(isoCode), &status);
502
503 if(U_FAILURE(status)) {
504 log_err("FAIL: can't set currency code %s\n", myErrorName(status) );
505 }
506 }
507
508 unum_getTextAttribute(currencyFmt, UNUM_CURRENCY_CODE,
509 isoCode, sizeof(isoCode), &status);
510
511 if(U_FAILURE(status)) {
512 log_err("FAIL: can't get currency code %s\n", myErrorName(status) );
513 }
514
515 u_UCharsToChars(isoCode,cStr,u_strlen(isoCode));
516 log_verbose("ISO code %s\n", cStr);
517 if (*currency[i] && uprv_strcmp(cStr, currency[i])) {
518 log_err("FAIL: currency should be %s, but is %s\n", currency[i], cStr);
519 }
520
521 lneed=0;
522 lneed= unum_formatDouble(currencyFmt, 1234.56, NULL, lneed, NULL, &status);
523 if(status==U_BUFFER_OVERFLOW_ERROR){
524 status=U_ZERO_ERROR;
525 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
526 pos.field = 0;
527 unum_formatDouble(currencyFmt, 1234.56, str, lneed+1, &pos, &status);
528 }
529 if(U_FAILURE(status)) {
530 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
531 } else {
532 res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) );
533 u_unescape(result[i],res, (int32_t)(strlen(result[i])+1));
534 if (u_strcmp(str, res) != 0){
535 log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]);
536 }
537 }
538 }
539
540 unum_close(currencyFmt);
541 free(str);
542 free(res);
543 }
544 }
545
546 /**
547 * Test proper rounding by the format method.
548 */
TestRounding487(void)549 static void TestRounding487(void)
550 {
551 UNumberFormat *nnf;
552 UErrorCode status = U_ZERO_ERROR;
553 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
554 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
555 /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
556 nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
557
558 if(U_FAILURE(status)){
559 log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
560 } else {
561 roundingTest(nnf, 0.00159999, 4, "0.0016");
562 roundingTest(nnf, 0.00995, 4, "0.01");
563
564 roundingTest(nnf, 12.3995, 3, "12.4");
565
566 roundingTest(nnf, 12.4999, 0, "12");
567 roundingTest(nnf, - 19.5, 0, "-20");
568 }
569
570 unum_close(nnf);
571 }
572
573 /*-------------------------------------*/
574
roundingTest(UNumberFormat * nf,double x,int32_t maxFractionDigits,const char * expected)575 static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits, const char* expected)
576 {
577 UChar *out = NULL;
578 UChar *res;
579 UFieldPosition pos;
580 UErrorCode status;
581 int32_t lneed;
582 status=U_ZERO_ERROR;
583 unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, maxFractionDigits);
584 lneed=0;
585 lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status);
586 if(status==U_BUFFER_OVERFLOW_ERROR){
587 status=U_ZERO_ERROR;
588 out=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
589 pos.field=0;
590 unum_formatDouble(nf, x, out, lneed+1, &pos, &status);
591 }
592 if(U_FAILURE(status)) {
593 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
594 }
595 /*Need to use log_verbose here. Problem with the float*/
596 /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/
597 res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) );
598 u_uastrcpy(res, expected);
599 if (u_strcmp(out, res) != 0)
600 log_err("FAIL: Expected: %s or %s\n", expected, austrdup(res) );
601 free(res);
602 if(out != NULL) {
603 free(out);
604 }
605 }
606
607 /*
608 * Testing unum_getDoubleAttribute and unum_setDoubleAttribute()
609 */
TestDoubleAttribute(void)610 static void TestDoubleAttribute(void)
611 {
612 double mydata[] = { 1.11, 22.22, 333.33, 4444.44, 55555.55, 666666.66, 7777777.77, 88888888.88, 999999999.99};
613 double dvalue;
614 int i;
615 UErrorCode status=U_ZERO_ERROR;
616 UNumberFormatAttribute attr;
617 UNumberFormatStyle style= UNUM_DEFAULT;
618 UNumberFormat *def;
619
620 log_verbose("\nTesting get and set DoubleAttributes\n");
621 def=unum_open(style, NULL,0,NULL,NULL, &status);
622
623 if (U_FAILURE(status)) {
624 log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status));
625 } else {
626 attr=UNUM_ROUNDING_INCREMENT;
627 dvalue=unum_getDoubleAttribute(def, attr);
628 for (i = 0; i<9 ; i++)
629 {
630 dvalue = mydata[i];
631 unum_setDoubleAttribute(def, attr, dvalue);
632 if(unum_getDoubleAttribute(def,attr)!=mydata[i])
633 log_err("Fail: error in setting and getting double attributes for UNUM_ROUNDING_INCREMENT\n");
634 else
635 log_verbose("Pass: setting and getting double attributes for UNUM_ROUNDING_INCREMENT works fine\n");
636 }
637 }
638
639 unum_close(def);
640 }
641
642 /**
643 * Test the functioning of the secondary grouping value.
644 */
TestSecondaryGrouping(void)645 static void TestSecondaryGrouping(void) {
646 UErrorCode status = U_ZERO_ERROR;
647 UNumberFormat *f = NULL, *g= NULL;
648 UNumberFormat *us = unum_open(UNUM_DECIMAL,NULL,0, "en_US", NULL,&status);
649 UFieldPosition pos;
650 UChar resultBuffer[512];
651 int32_t l = 1876543210L;
652 UBool ok = true;
653 UChar buffer[512];
654 int32_t i;
655 UBool expectGroup = false, isGroup = false;
656
657 u_uastrcpy(buffer, "#,##,###");
658 f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status);
659 if (U_FAILURE(status)) {
660 log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status));
661 return;
662 }
663
664 pos.field = 0;
665 unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
666 u_uastrcpy(buffer, "12,34,56,789");
667 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
668 {
669 log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,34,56,789");
670 }
671 if (pos.beginIndex != 0 && pos.endIndex != 12) {
672 log_err("Fail: Formatting \"#,##,###\" pattern pos = (%d, %d) expected pos = (0, 12)\n", pos.beginIndex, pos.endIndex);
673 }
674 memset(resultBuffer,0, sizeof(UChar)*512);
675 unum_toPattern(f, false, resultBuffer, 512, &status);
676 u_uastrcpy(buffer, "#,##,##0");
677 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
678 {
679 log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,##,##0");
680 }
681 memset(resultBuffer,0, sizeof(UChar)*512);
682 u_uastrcpy(buffer, "#,###");
683 unum_applyPattern(f, false, buffer, -1,NULL,NULL);
684 if (U_FAILURE(status))
685 {
686 log_err("Fail: applyPattern call failed\n");
687 }
688 unum_setAttribute(f, UNUM_SECONDARY_GROUPING_SIZE, 4);
689 unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
690 u_uastrcpy(buffer, "12,3456,789");
691 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
692 {
693 log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,3456,789");
694 }
695 memset(resultBuffer,0, sizeof(UChar)*512);
696 unum_toPattern(f, false, resultBuffer, 512, &status);
697 u_uastrcpy(buffer, "#,####,##0");
698 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
699 {
700 log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,####,##0");
701 }
702 memset(resultBuffer,0, sizeof(UChar)*512);
703 g = unum_open(UNUM_DECIMAL, NULL,0,"hi_IN",NULL, &status);
704 if (U_FAILURE(status))
705 {
706 log_err("Fail: Cannot create UNumberFormat for \"hi_IN\" locale.\n");
707 }
708
709 unum_format(g, l, resultBuffer, 512, &pos, &status);
710 unum_close(g);
711 /* expect "1,87,65,43,210", but with Hindi digits */
712 /* 01234567890123 */
713 if (u_strlen(resultBuffer) != 14) {
714 ok = false;
715 } else {
716 for (i=0; i<u_strlen(resultBuffer); ++i) {
717 expectGroup = false;
718 switch (i) {
719 case 1:
720 case 4:
721 case 7:
722 case 10:
723 expectGroup = true;
724 break;
725 }
726 /* Later -- fix this to get the actual grouping */
727 /* character from the resource bundle. */
728 isGroup = (UBool)(resultBuffer[i] == 0x002C);
729 if (isGroup != expectGroup) {
730 ok = false;
731 break;
732 }
733 }
734 }
735 if (!ok) {
736 log_err("FAIL Expected %s x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got %s\n", "1876543210L", resultBuffer);
737 }
738 unum_close(f);
739 unum_close(us);
740 }
741
TestCurrencyKeywords(void)742 static void TestCurrencyKeywords(void)
743 {
744 static const char * const currencies[] = {
745 "ADD", "ADP", "AED", "AFA", "AFN", "AIF", "ALK", "ALL", "ALV", "ALX", "AMD",
746 "ANG", "AOA", "AOK", "AON", "AOR", "AOS", "ARA", "ARM", "ARP", "ARS", "ATS",
747 "AUD", "AUP", "AWG", "AZM", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF",
748 "BEL", "BGL", "BGM", "BGN", "BGO", "BGX", "BHD", "BIF", "BMD", "BMP", "BND",
749 "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ",
750 "BSD", "BSP", "BTN", "BTR", "BUK", "BUR", "BWP", "BYB", "BYL", "BYR", "BZD",
751 "BZH", "CAD", "CDF", "CDG", "CDL", "CFF", "CHF", "CKD", "CLC", "CLE", "CLF",
752 "CLP", "CMF", "CNP", "CNX", "CNY", "COB", "COF", "COP", "CRC", "CSC", "CSK",
753 "CUP", "CUX", "CVE", "CWG", "CYP", "CZK", "DDM", "DEM", "DES", "DJF", "DKK",
754 "DOP", "DZD", "DZF", "DZG", "ECS", "ECV", "EEK", "EGP", "ERN", "ESP", "ETB",
755 "ETD", "EUR", "FIM", "FIN", "FJD", "FJP", "FKP", "FOK", "FRF", "FRG", "GAF",
756 "GBP", "GEK", "GEL", "GHC", "GHO", "GHP", "GHR", "GIP", "GLK", "GMD", "GMP",
757 "GNF", "GNI", "GNS", "GPF", "GQE", "GQF", "GQP", "GRD", "GRN", "GTQ", "GUF",
758 "GWE", "GWM", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IBP",
759 "IDG", "IDJ", "IDN", "IDR", "IEP", "ILL", "ILP", "ILS", "IMP", "INR", "IQD",
760 "IRR", "ISK", "ITL", "JEP", "JMD", "JMP", "JOD", "JPY", "KES", "KGS", "KHO",
761 "KHR", "KID", "KMF", "KPP", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZR",
762 "KZT", "LAK", "LBP", "LIF", "LKR", "LNR", "LRD", "LSL", "LTL", "LTT", "LUF",
763 "LVL", "LVR", "LYB", "LYD", "LYP", "MAD", "MAF", "MCF", "MCG", "MDC", "MDL",
764 "MDR", "MGA", "MGF", "MHD", "MKD", "MKN", "MLF", "MMK", "MMX", "MNT", "MOP",
765 "MQF", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MWP", "MXN", "MXP",
766 "MXV", "MYR", "MZE", "MZM", "NAD", "NCF", "NGN", "NGP", "NHF", "NIC", "NIG",
767 "NIO", "NLG", "NOK", "NPR", "NZD", "NZP", "OMR", "OMS", "PAB", "PDK", "PDN",
768 "PDR", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLX", "PLZ", "PSP",
769 "PTC", "PTE", "PYG", "QAR", "REF", "ROL", "RON", "RUB", "RUR", "RWF", "SAR",
770 "SAS", "SBD", "SCR", "SDD", "SDP", "SEK", "SGD", "SHP", "SIB", "SIT", "SKK",
771 "SLL", "SML", "SOS", "SQS", "SRG", "SSP", "STD", "STE", "SUN", "SUR", "SVC",
772 "SYP", "SZL", "TCC", "TDF", "THB", "TJR", "TJS", "TMM", "TND", "TOP", "TOS",
773 "TPE", "TPP", "TRL", "TTD", "TTO", "TVD", "TWD", "TZS", "UAH", "UAK", "UGS",
774 "UGX", "USD", "USN", "USS", "UYF", "UYP", "UYU", "UZC", "UZS", "VAL", "VDD",
775 "VDN", "VDP", "VEB", "VGD", "VND", "VNN", "VNR", "VNS", "VUV", "WSP", "WST",
776 "XAD", "XAF", "XAM", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XCF", "XDR",
777 "XEF", "XEU", "XFO", "XFU", "XID", "XMF", "XNF", "XOF", "XPF", "XPS", "XSS",
778 "XTR", "YDD", "YEI", "YER", "YUD", "YUF", "YUG", "YUM", "YUN", "YUO", "YUR",
779 "ZAL", "ZAP", "ZAR", "ZMK", "ZMP", "ZRN", "ZRZ", "ZWD"
780 };
781
782 UErrorCode status = U_ZERO_ERROR;
783 int32_t i = 0, j = 0;
784 int32_t noLocales = uloc_countAvailable();
785 char locale[256];
786 char currLoc[256];
787 UChar result[4];
788 UChar currBuffer[256];
789
790
791 for(i = 0; i < noLocales; i++) {
792 strcpy(currLoc, uloc_getAvailable(i));
793 for(j = 0; j < UPRV_LENGTHOF(currencies); j++) {
794 strcpy(locale, currLoc);
795 strcat(locale, "@currency=");
796 strcat(locale, currencies[j]);
797 ucurr_forLocale(locale, result, 4, &status);
798 u_charsToUChars(currencies[j], currBuffer, 3);
799 currBuffer[3] = 0;
800 if(u_strcmp(currBuffer, result) != 0) {
801 log_err("Didn't get the right currency for %s\n", locale);
802 }
803 }
804
805 }
806 }
807
TestGetKeywordValuesForLocale(void)808 static void TestGetKeywordValuesForLocale(void) {
809 #define PREFERRED_SIZE 15
810 #define MAX_NUMBER_OF_KEYWORDS 4
811 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = {
812 { "root", "USD", "USN", NULL },
813 { "und", "USD", "USN", NULL },
814 /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */
815 { "en_US", "USD", "USN", NULL },
816 { "en_029", "USD", "USN", NULL },
817 { "en_TH", "THB", NULL, NULL },
818 { "de", "EUR", NULL, NULL },
819 { "de_DE", "EUR", NULL, NULL },
820 { "ar", "EGP", NULL, NULL },
821 { "ar_PS", "ILS", "JOD", NULL },
822 { "en@currency=CAD", "USD", "USN", NULL },
823 { "fr@currency=zzz", "EUR", NULL, NULL },
824 { "de_DE@currency=DEM", "EUR", NULL, NULL },
825 { "en_US@rg=THZZZZ", "THB", NULL, NULL },
826 { "de@rg=USZZZZ", "USD", "USN", NULL },
827 { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL },
828 };
829 const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = {
830 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1
831 };
832 /* ucurr_forLocale results for same locales; "" if no result expected */
833 const char *FORLOCALE[PREFERRED_SIZE] = {
834 "", "", "USD", "",
835 "THB", "", "EUR", "",
836 "ILS", "CAD", "ZZZ", "DEM",
837 "THB", "USD", "CAD"
838 };
839 UErrorCode status = U_ZERO_ERROR;
840 int32_t i, j, size;
841 UEnumeration *pref, *all;
842 const char *loc = NULL;
843 UBool matchPref, matchAll;
844 const char *value = NULL;
845 int32_t valueLength = 0;
846
847 UList *ALLList = NULL;
848
849 UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), false, &status);
850 if (ALL == NULL) {
851 log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status));
852 return;
853 }
854
855 for (i = 0; i < PREFERRED_SIZE; i++) {
856 UChar getCurrU[4];
857 int32_t getCurrLen;
858
859 status = U_ZERO_ERROR;
860 pref = NULL;
861 all = NULL;
862 loc = PREFERRED[i][0];
863 pref = ucurr_getKeywordValuesForLocale("currency", loc, true, &status);
864 matchPref = false;
865 matchAll = false;
866
867 size = uenum_count(pref, &status);
868
869 if (size == EXPECTED_SIZE[i]) {
870 matchPref = true;
871 for (j = 0; j < size; j++) {
872 if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
873 if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) {
874 log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]);
875
876 matchPref = false;
877 break;
878 }
879 } else {
880 matchPref = false;
881 log_err("ERROR getting keyword value for locale \"%s\"\n", loc);
882 break;
883 }
884 }
885 } else {
886 log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]);
887 }
888
889 if (!matchPref) {
890 log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc);
891 break;
892 }
893 uenum_close(pref);
894
895 all = ucurr_getKeywordValuesForLocale("currency", loc, false, &status);
896
897 size = uenum_count(all, &status);
898
899 if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) {
900 matchAll = true;
901 ALLList = ulist_getListFromEnum(ALL);
902 for (j = 0; j < size; j++) {
903 if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
904 if (!ulist_containsString(ALLList, value, (int32_t)uprv_strlen(value))) {
905 log_err("Locale %s have %s not in ALL\n", loc, value);
906 matchAll = false;
907 break;
908 }
909 } else {
910 matchAll = false;
911 log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc);
912 break;
913 }
914 }
915 if (!matchAll) {
916 log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc);
917 }
918 } else {
919 if(U_FAILURE(status)) {
920 log_err("ERROR: %s\n", u_errorName(status));
921 } else if(size!=uenum_count(ALL, &status)) {
922 log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status));
923 }
924 }
925
926 uenum_close(all);
927
928 status = U_ZERO_ERROR;
929 getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status);
930 if(U_FAILURE(status)) {
931 if (FORLOCALE[i][0] != 0) {
932 log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status));
933 }
934 } else if (getCurrLen != 3) {
935 if (FORLOCALE[i][0] != 0 || getCurrLen != -1) {
936 log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen);
937 }
938 } else {
939 char getCurrB[4];
940 u_UCharsToChars(getCurrU, getCurrB, 4);
941 if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) {
942 log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB);
943 }
944 }
945 }
946
947 uenum_close(ALL);
948
949 }
950
951 /**
952 * Test proper handling of rounding modes.
953 */
TestRounding5350(void)954 static void TestRounding5350(void)
955 {
956 UNumberFormat *nnf;
957 UErrorCode status = U_ZERO_ERROR;
958 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
959 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
960 /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
961 nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
962
963 if(U_FAILURE(status)){
964 log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
965 return;
966 }
967
968 unum_setAttribute(nnf, UNUM_MAX_FRACTION_DIGITS, 2);
969 roundingTest2(nnf, -0.125, UNUM_ROUND_CEILING, "-0.12");
970 roundingTest2(nnf, -0.125, UNUM_ROUND_FLOOR, "-0.13");
971 roundingTest2(nnf, -0.125, UNUM_ROUND_DOWN, "-0.12");
972 roundingTest2(nnf, -0.125, UNUM_ROUND_UP, "-0.13");
973 roundingTest2(nnf, 0.125, UNUM_ROUND_HALFEVEN, "0.12");
974 roundingTest2(nnf, 0.135, UNUM_ROUND_HALF_ODD, "0.13");
975 roundingTest2(nnf, 0.135, UNUM_ROUND_HALF_CEILING, "0.14");
976 roundingTest2(nnf, -0.135, UNUM_ROUND_HALF_CEILING, "-0.13");
977 roundingTest2(nnf, 0.135, UNUM_ROUND_HALF_FLOOR, "0.13");
978 roundingTest2(nnf, -0.135, UNUM_ROUND_HALF_FLOOR, "-0.14");
979 roundingTest2(nnf, 0.135, UNUM_ROUND_HALFDOWN, "0.13");
980 roundingTest2(nnf, 0.125, UNUM_ROUND_HALFUP, "0.13");
981 roundingTest2(nnf, 0.135, UNUM_FOUND_HALFEVEN, "0.14");
982 /* The following are exactly represented, and shouldn't round */
983 roundingTest2(nnf, 1.00, UNUM_ROUND_UP, "1");
984 roundingTest2(nnf, 24.25, UNUM_ROUND_UP, "24.25");
985 roundingTest2(nnf, 24.25, UNUM_ROUND_CEILING, "24.25");
986 roundingTest2(nnf, -24.25, UNUM_ROUND_UP, "-24.25");
987
988 /* Differences pretty far out there */
989 roundingTest2(nnf, 1.0000001, UNUM_ROUND_CEILING, "1.01");
990 roundingTest2(nnf, 1.0000001, UNUM_ROUND_FLOOR, "1");
991 roundingTest2(nnf, 1.0000001, UNUM_ROUND_DOWN, "1");
992 roundingTest2(nnf, 1.0000001, UNUM_ROUND_UP, "1.01");
993 roundingTest2(nnf, 1.0000001, UNUM_FOUND_HALFEVEN, "1");
994 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALF_ODD, "1");
995 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALF_CEILING, "1");
996 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALF_FLOOR, "1");
997 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFDOWN, "1");
998 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFUP, "1");
999
1000 roundingTest2(nnf, -1.0000001, UNUM_ROUND_CEILING, "-1");
1001 roundingTest2(nnf, -1.0000001, UNUM_ROUND_FLOOR, "-1.01");
1002 roundingTest2(nnf, -1.0000001, UNUM_ROUND_DOWN, "-1");
1003 roundingTest2(nnf, -1.0000001, UNUM_ROUND_UP, "-1.01");
1004 roundingTest2(nnf, -1.0000001, UNUM_FOUND_HALFEVEN, "-1");
1005 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALF_ODD, "-1");
1006 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALF_CEILING, "-1");
1007 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALF_FLOOR, "-1");
1008 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFDOWN, "-1");
1009 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFUP, "-1");
1010
1011 unum_close(nnf);
1012 }
1013
1014 /*-------------------------------------*/
1015
roundingTest2(UNumberFormat * nf,double x,int32_t roundingMode,const char * expected)1016 static void roundingTest2(UNumberFormat* nf, double x, int32_t roundingMode, const char* expected)
1017 {
1018 UChar *out = NULL;
1019 UChar *res;
1020 UFieldPosition pos;
1021 UErrorCode status;
1022 int32_t lneed;
1023 status=U_ZERO_ERROR;
1024 unum_setAttribute(nf, UNUM_ROUNDING_MODE, roundingMode);
1025 lneed=0;
1026 lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status);
1027 if(status==U_BUFFER_OVERFLOW_ERROR){
1028 status=U_ZERO_ERROR;
1029 out=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
1030 pos.field=0;
1031 unum_formatDouble(nf, x, out, lneed+1, &pos, &status);
1032 }
1033 if(U_FAILURE(status)) {
1034 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
1035 }
1036 /*Need to use log_verbose here. Problem with the float*/
1037 /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/
1038 res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) );
1039 u_uastrcpy(res, expected);
1040 if (u_strcmp(out, res) != 0)
1041 log_err("FAIL: Expected: \"%s\" Got: \"%s\"\n", expected, austrdup(out) );
1042 free(res);
1043 if(out != NULL) {
1044 free(out);
1045 }
1046 }
1047
1048 #endif /* #if !UCONFIG_NO_FORMATTING */
1049