• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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