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