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