1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2013, 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
36void addNumFrDepTest(TestNode** root);
37static void TestCurrencyPreEuro(void);
38static void TestCurrencyObject(void);
39
40void 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*/
58static 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*/
120static 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*/
186static 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 */
337static 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 */
410static 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\\u00a0DEM", "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 */
457static 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\\u00A0FIM",   "2\\u00A0F",         "ITL\\u00A02",
474        "1$50\\u00A0Esc.", "\\u00F6S\\u00A01,50",  "1,50\\u00A0\\u0394\\u03C1\\u03C7", "2\\u00A0\\u20A7", "1,50\\u00A0FB",     "IEP1.50",
475        "1,50\\u00A0BEF",   "1,50\\u00A0DEM",        "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 */
527static 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\\u00A0\\u00A5JP",
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 */
611static 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
637static 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 */
672static 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 */
707static 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
804static 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
870static 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", "USS" },
875            { "und",                "USD", "USN", "USS" },
876 /*           { "und_ZZ",             "USD", NULL, NULL },  -- temporaary remove as this locale now has 15 entries */
877            { "en_US",              "USD", "USN", "USS" },
878            { "en_029",             "USD", "USN", "USS" },
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", "USS" },
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            3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 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 */
984static 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
1035static 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