1// Copyright (C) 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
39void addNumFrDepTest(TestNode** root);
40static void TestCurrencyPreEuro(void);
41static void TestCurrencyObject(void);
42
43void addNumFrDepTest(TestNode** root)
44{
45  addTest(root, &TestPatterns, "tsformat/cnmdptst/TestPatterns");
46  addTest(root, &TestQuotes, "tsformat/cnmdptst/TestQuotes");
47  addTest(root, &TestExponential, "tsformat/cnmdptst/TestExponential");
48  addTest(root, &TestCurrencySign, "tsformat/cnmdptst/TestCurrencySign");
49  addTest(root, &TestCurrency,  "tsformat/cnmdptst/TestCurrency");
50  addTest(root, &TestCurrencyPreEuro,  "tsformat/cnmdptst/TestCurrencyPreEuro");
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*/
61static 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", "#" };
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 transmute 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*/
123static 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 costruction 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 costruction 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*/
189static 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            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 */
340static 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 */
413static 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_PREEURO", "fr_FR_PREEURO"};
422    const char* result[]={"1,50\\u00a0$", "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 * Test localized currency patterns for PREEURO variants.
459 */
460static void TestCurrencyPreEuro(void)
461{
462    UNumberFormat *currencyFmt;
463    UChar *str=NULL, *res=NULL;
464    int32_t lneed, i;
465    UFieldPosition pos;
466    UErrorCode status = U_ZERO_ERROR;
467
468    const char* locale[]={
469        "ca_ES_PREEURO",  "de_LU_PREEURO",  "en_IE_PREEURO",              "fi_FI_PREEURO",  "fr_LU_PREEURO",  "it_IT_PREEURO",
470        "pt_PT_PREEURO",  "de_AT_PREEURO",  "el_GR_PREEURO",              "es_ES_PREEURO",  "fr_BE_PREEURO",  "ga_IE_PREEURO",
471        "nl_BE_PREEURO",  "de_DE_PREEURO",  "en_BE_PREEURO",              "eu_ES_PREEURO",  "fr_FR_PREEURO",  "gl_ES_PREEURO",
472        "nl_NL_PREEURO",
473    };
474
475    const char* result[]={
476        "\\u20A7\\u00A02", "2\\u00A0F",            "IEP1.50",                      "1,50\\u00A0mk",   "2\\u00A0F",         "ITL\\u00A02",
477        "1$50\\u00A0\\u200B", "\\u00F6S\\u00A01,50",  "1,50\\u00A0\\u0394\\u03C1\\u03C7", "2\\u00A0\\u20A7", "1,50\\u00A0FB",     "IEP1.50",
478        "1,50\\u00A0BEF",   "1,50\\u00A0DM",        "1,50\\u00A0BEF",                    "\\u20A7\\u00A02", "1,50\\u00A0F",      "2\\u00A0\\u20A7",
479        "NLG\\u00A01,50"
480    };
481
482    log_verbose("\nTesting the number format with different currency patterns\n");
483    for(i=0; i < 19; i++)
484    {
485        char curID[256] = {0};
486        uloc_canonicalize(locale[i], curID, 256, &status);
487        if(U_FAILURE(status)){
488            log_data_err("Could not canonicalize %s. Error: %s (Are you missing data?)\n", locale[i], u_errorName(status));
489            continue;
490        }
491        currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status);
492
493        if(U_FAILURE(status)){
494            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
495                myErrorName(status));
496        } else {
497            lneed=0;
498            lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status);
499
500            if(status==U_BUFFER_OVERFLOW_ERROR){
501                status=U_ZERO_ERROR;
502                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
503                pos.field = 0;
504                unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status);
505            }
506
507            if(U_FAILURE(status)) {
508                log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
509            } else {
510                res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) );
511                u_unescape(result[i],res,(int32_t)(strlen(result[i])+1));
512
513                if (u_strcmp(str, res) != 0){
514                    log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]);
515                }
516            }
517        }
518
519        unum_close(currencyFmt);
520        free(str);
521        free(res);
522    }
523}
524
525/**
526 * Test currency "object" (we use this name to match the other C++
527 * test name and the Jave name).  Actually, test ISO currency code
528 * support in the C API.
529 */
530static void TestCurrencyObject(void)
531{
532    UNumberFormat *currencyFmt;
533    UChar *str=NULL, *res=NULL;
534    int32_t lneed, i;
535    UFieldPosition pos;
536    UErrorCode status = U_ZERO_ERROR;
537
538    const char* locale[]={
539        "fr_FR",
540        "fr_FR",
541    };
542
543    const char* currency[]={
544        "",
545        "JPY",
546    };
547
548    const char* result[]={
549        "1\\u00A0234,56\\u00A0\\u20AC",
550        "1\\u00A0235\\u00A0JPY",
551    };
552
553    log_verbose("\nTesting the number format with different currency codes\n");
554    for(i=0; i < 2; i++)
555    {
556        char cStr[20]={0};
557        UChar isoCode[16]={0};
558        currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
559        if(U_FAILURE(status)){
560            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
561                myErrorName(status));
562        } else {
563            if (*currency[i]) {
564                u_uastrcpy(isoCode, currency[i]);
565                unum_setTextAttribute(currencyFmt, UNUM_CURRENCY_CODE,
566                    isoCode, u_strlen(isoCode), &status);
567
568                if(U_FAILURE(status)) {
569                    log_err("FAIL: can't set currency code %s\n", myErrorName(status) );
570                }
571            }
572
573            unum_getTextAttribute(currencyFmt, UNUM_CURRENCY_CODE,
574                isoCode, sizeof(isoCode), &status);
575
576            if(U_FAILURE(status)) {
577                log_err("FAIL: can't get currency code %s\n", myErrorName(status) );
578            }
579
580            u_UCharsToChars(isoCode,cStr,u_strlen(isoCode));
581            log_verbose("ISO code %s\n", cStr);
582            if (*currency[i] && uprv_strcmp(cStr, currency[i])) {
583                log_err("FAIL: currency should be %s, but is %s\n", currency[i], cStr);
584            }
585
586            lneed=0;
587            lneed= unum_formatDouble(currencyFmt, 1234.56, NULL, lneed, NULL, &status);
588            if(status==U_BUFFER_OVERFLOW_ERROR){
589                status=U_ZERO_ERROR;
590                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
591                pos.field = 0;
592                unum_formatDouble(currencyFmt, 1234.56, str, lneed+1, &pos, &status);
593            }
594            if(U_FAILURE(status)) {
595                log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
596            } else {
597                res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) );
598                u_unescape(result[i],res, (int32_t)(strlen(result[i])+1));
599                if (u_strcmp(str, res) != 0){
600                    log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]);
601                }
602            }
603        }
604
605        unum_close(currencyFmt);
606        free(str);
607        free(res);
608    }
609}
610
611/**
612 * Test proper rounding by the format method.
613 */
614static void TestRounding487(void)
615{
616    UNumberFormat *nnf;
617    UErrorCode status = U_ZERO_ERROR;
618    /* this is supposed to open default date format, but later on it treats it like it is "en_US"
619     - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
620    /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
621    nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
622
623    if(U_FAILURE(status)){
624        log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
625    } else {
626        roundingTest(nnf, 0.00159999, 4, "0.0016");
627        roundingTest(nnf, 0.00995, 4, "0.01");
628
629        roundingTest(nnf, 12.3995, 3, "12.4");
630
631        roundingTest(nnf, 12.4999, 0, "12");
632        roundingTest(nnf, - 19.5, 0, "-20");
633    }
634
635    unum_close(nnf);
636}
637
638/*-------------------------------------*/
639
640static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits, const char* expected)
641{
642    UChar *out = NULL;
643    UChar *res;
644    UFieldPosition pos;
645    UErrorCode status;
646    int32_t lneed;
647    status=U_ZERO_ERROR;
648    unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, maxFractionDigits);
649    lneed=0;
650    lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status);
651    if(status==U_BUFFER_OVERFLOW_ERROR){
652        status=U_ZERO_ERROR;
653        out=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
654        pos.field=0;
655        unum_formatDouble(nf, x, out, lneed+1, &pos, &status);
656    }
657    if(U_FAILURE(status)) {
658        log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
659    }
660    /*Need to use log_verbose here. Problem with the float*/
661    /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/
662    res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) );
663    u_uastrcpy(res, expected);
664    if (u_strcmp(out, res) != 0)
665        log_err("FAIL: Expected: %s or %s\n", expected, austrdup(res) );
666    free(res);
667    if(out != NULL) {
668        free(out);
669    }
670}
671
672/*
673 * Testing unum_getDoubleAttribute and  unum_setDoubleAttribute()
674 */
675static void TestDoubleAttribute(void)
676{
677    double mydata[] = { 1.11, 22.22, 333.33, 4444.44, 55555.55, 666666.66, 7777777.77, 88888888.88, 999999999.99};
678    double dvalue;
679    int i;
680    UErrorCode status=U_ZERO_ERROR;
681    UNumberFormatAttribute attr;
682    UNumberFormatStyle style= UNUM_DEFAULT;
683    UNumberFormat *def;
684
685    log_verbose("\nTesting get and set DoubleAttributes\n");
686    def=unum_open(style, NULL,0,NULL,NULL, &status);
687
688    if (U_FAILURE(status)) {
689        log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status));
690    } else {
691        attr=UNUM_ROUNDING_INCREMENT;
692        dvalue=unum_getDoubleAttribute(def, attr);
693        for (i = 0; i<9 ; i++)
694        {
695            dvalue = mydata[i];
696            unum_setDoubleAttribute(def, attr, dvalue);
697            if(unum_getDoubleAttribute(def,attr)!=mydata[i])
698                log_err("Fail: error in setting and getting double attributes for UNUM_ROUNDING_INCREMENT\n");
699            else
700                log_verbose("Pass: setting and getting double attributes for UNUM_ROUNDING_INCREMENT works fine\n");
701        }
702    }
703
704    unum_close(def);
705}
706
707/**
708 * Test the functioning of the secondary grouping value.
709 */
710static void TestSecondaryGrouping(void) {
711    UErrorCode status = U_ZERO_ERROR;
712    UNumberFormat *f = NULL, *g= NULL;
713    UNumberFormat *us = unum_open(UNUM_DECIMAL,NULL,0, "en_US", NULL,&status);
714    UFieldPosition pos;
715    UChar resultBuffer[512];
716    int32_t l = 1876543210L;
717    UBool ok = TRUE;
718    UChar buffer[512];
719    int32_t i;
720    UBool expectGroup = FALSE, isGroup = FALSE;
721
722    u_uastrcpy(buffer, "#,##,###");
723    f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status);
724    if (U_FAILURE(status)) {
725        log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status));
726        return;
727    }
728
729    pos.field = 0;
730    unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
731    u_uastrcpy(buffer, "12,34,56,789");
732    if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
733    {
734        log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,34,56,789");
735    }
736    if (pos.beginIndex != 0 && pos.endIndex != 12) {
737        log_err("Fail: Formatting \"#,##,###\" pattern pos = (%d, %d) expected pos = (0, 12)\n", pos.beginIndex, pos.endIndex);
738    }
739    memset(resultBuffer,0, sizeof(UChar)*512);
740    unum_toPattern(f, FALSE, resultBuffer, 512, &status);
741    u_uastrcpy(buffer, "#,##,###");
742    if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
743    {
744        log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,##,###");
745    }
746    memset(resultBuffer,0, sizeof(UChar)*512);
747    u_uastrcpy(buffer, "#,###");
748    unum_applyPattern(f, FALSE, buffer, -1,NULL,NULL);
749    if (U_FAILURE(status))
750    {
751        log_err("Fail: applyPattern call failed\n");
752    }
753    unum_setAttribute(f, UNUM_SECONDARY_GROUPING_SIZE, 4);
754    unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
755    u_uastrcpy(buffer, "12,3456,789");
756    if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
757    {
758        log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,3456,789");
759    }
760    memset(resultBuffer,0, sizeof(UChar)*512);
761    unum_toPattern(f, FALSE, resultBuffer, 512, &status);
762    u_uastrcpy(buffer, "#,####,###");
763    if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
764    {
765        log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,####,###");
766    }
767    memset(resultBuffer,0, sizeof(UChar)*512);
768    g = unum_open(UNUM_DECIMAL, NULL,0,"hi_IN",NULL, &status);
769    if (U_FAILURE(status))
770    {
771        log_err("Fail: Cannot create UNumberFormat for \"hi_IN\" locale.\n");
772    }
773
774    unum_format(g, l, resultBuffer, 512, &pos, &status);
775    unum_close(g);
776    /* expect "1,87,65,43,210", but with Hindi digits */
777    /*         01234567890123                         */
778    if (u_strlen(resultBuffer) != 14) {
779        ok = FALSE;
780    } else {
781        for (i=0; i<u_strlen(resultBuffer); ++i) {
782            expectGroup = FALSE;
783            switch (i) {
784            case 1:
785            case 4:
786            case 7:
787            case 10:
788                expectGroup = TRUE;
789                break;
790            }
791            /* Later -- fix this to get the actual grouping */
792            /* character from the resource bundle.          */
793            isGroup = (UBool)(resultBuffer[i] == 0x002C);
794            if (isGroup != expectGroup) {
795                ok = FALSE;
796                break;
797            }
798        }
799    }
800    if (!ok) {
801        log_err("FAIL  Expected %s x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got %s\n", "1876543210L", resultBuffer);
802    }
803    unum_close(f);
804    unum_close(us);
805}
806
807static void TestCurrencyKeywords(void)
808{
809    static const char * const currencies[] = {
810        "ADD", "ADP", "AED", "AFA", "AFN", "AIF", "ALK", "ALL", "ALV", "ALX", "AMD",
811        "ANG", "AOA", "AOK", "AON", "AOR", "AOS", "ARA", "ARM", "ARP", "ARS", "ATS",
812        "AUD", "AUP", "AWG", "AZM", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF",
813        "BEL", "BGL", "BGM", "BGN", "BGO", "BGX", "BHD", "BIF", "BMD", "BMP", "BND",
814        "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ",
815        "BSD", "BSP", "BTN", "BTR", "BUK", "BUR", "BWP", "BYB", "BYL", "BYR", "BZD",
816        "BZH", "CAD", "CDF", "CDG", "CDL", "CFF", "CHF", "CKD", "CLC", "CLE", "CLF",
817        "CLP", "CMF", "CNP", "CNX", "CNY", "COB", "COF", "COP", "CRC", "CSC", "CSK",
818        "CUP", "CUX", "CVE", "CWG", "CYP", "CZK", "DDM", "DEM", "DES", "DJF", "DKK",
819        "DOP", "DZD", "DZF", "DZG", "ECS", "ECV", "EEK", "EGP", "ERN", "ESP", "ETB",
820        "ETD", "EUR", "FIM", "FIN", "FJD", "FJP", "FKP", "FOK", "FRF", "FRG", "GAF",
821        "GBP", "GEK", "GEL", "GHC", "GHO", "GHP", "GHR", "GIP", "GLK", "GMD", "GMP",
822        "GNF", "GNI", "GNS", "GPF", "GQE", "GQF", "GQP", "GRD", "GRN", "GTQ", "GUF",
823        "GWE", "GWM", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IBP",
824        "IDG", "IDJ", "IDN", "IDR", "IEP", "ILL", "ILP", "ILS", "IMP", "INR", "IQD",
825        "IRR", "ISK", "ITL", "JEP", "JMD", "JMP", "JOD", "JPY", "KES", "KGS", "KHO",
826        "KHR", "KID", "KMF", "KPP", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZR",
827        "KZT", "LAK", "LBP", "LIF", "LKR", "LNR", "LRD", "LSL", "LTL", "LTT", "LUF",
828        "LVL", "LVR", "LYB", "LYD", "LYP", "MAD", "MAF", "MCF", "MCG", "MDC", "MDL",
829        "MDR", "MGA", "MGF", "MHD", "MKD", "MKN", "MLF", "MMK", "MMX", "MNT", "MOP",
830        "MQF", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MWP", "MXN", "MXP",
831        "MXV", "MYR", "MZE", "MZM", "NAD", "NCF", "NGN", "NGP", "NHF", "NIC", "NIG",
832        "NIO", "NLG", "NOK", "NPR", "NZD", "NZP", "OMR", "OMS", "PAB", "PDK", "PDN",
833        "PDR", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLX", "PLZ", "PSP",
834        "PTC", "PTE", "PYG", "QAR", "REF", "ROL", "RON", "RUB", "RUR", "RWF", "SAR",
835        "SAS", "SBD", "SCR", "SDD", "SDP", "SEK", "SGD", "SHP", "SIB", "SIT", "SKK",
836        "SLL", "SML", "SOS", "SQS", "SRG", "SSP", "STD", "STE", "SUN", "SUR", "SVC",
837        "SYP", "SZL", "TCC", "TDF", "THB", "TJR", "TJS", "TMM", "TND", "TOP", "TOS",
838        "TPE", "TPP", "TRL", "TTD", "TTO", "TVD", "TWD", "TZS", "UAH", "UAK", "UGS",
839        "UGX", "USD", "USN", "USS", "UYF", "UYP", "UYU", "UZC", "UZS", "VAL", "VDD",
840        "VDN", "VDP", "VEB", "VGD", "VND", "VNN", "VNR", "VNS", "VUV", "WSP", "WST",
841        "XAD", "XAF", "XAM", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XCF", "XDR",
842        "XEF", "XEU", "XFO", "XFU", "XID", "XMF", "XNF", "XOF", "XPF", "XPS", "XSS",
843        "XTR", "YDD", "YEI", "YER", "YUD", "YUF", "YUG", "YUM", "YUN", "YUO", "YUR",
844        "ZAL", "ZAP", "ZAR", "ZMK", "ZMP", "ZRN", "ZRZ", "ZWD"
845    };
846
847    UErrorCode status = U_ZERO_ERROR;
848    int32_t i = 0, j = 0;
849    int32_t noLocales = uloc_countAvailable();
850    char locale[256];
851    char currLoc[256];
852    UChar result[4];
853    UChar currBuffer[256];
854
855
856    for(i = 0; i < noLocales; i++) {
857        strcpy(currLoc, uloc_getAvailable(i));
858        for(j = 0; j < UPRV_LENGTHOF(currencies); j++) {
859            strcpy(locale, currLoc);
860            strcat(locale, "@currency=");
861            strcat(locale, currencies[j]);
862            ucurr_forLocale(locale, result, 4, &status);
863            u_charsToUChars(currencies[j], currBuffer, 3);
864            currBuffer[3] = 0;
865            if(u_strcmp(currBuffer, result) != 0) {
866                log_err("Didn't get the right currency for %s\n", locale);
867            }
868        }
869
870    }
871}
872
873static void TestGetKeywordValuesForLocale(void) {
874#define PREFERRED_SIZE 15
875#define MAX_NUMBER_OF_KEYWORDS 4
876    const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = {
877            { "root",               "USD", "USN", NULL },
878            { "und",                "USD", "USN", NULL },
879 /*           { "und_ZZ",             "USD", NULL, NULL },  -- temporarily remove as this locale now has 15 entries */
880            { "en_US",              "USD", "USN", NULL },
881            { "en_029",             "USD", "USN", NULL },
882            { "en_TH",              "THB", NULL, NULL },
883            { "de",                 "EUR", NULL, NULL },
884            { "de_DE",              "EUR", NULL, NULL },
885            { "ar",                 "EGP", NULL, NULL },
886            { "ar_PS",              "ILS", "JOD", NULL },
887            { "en@currency=CAD",    "USD", "USN", NULL },
888            { "fr@currency=zzz",    "EUR", NULL, NULL },
889            { "de_DE@currency=DEM", "EUR", NULL, NULL },
890            { "en_US@rg=THZZZZ",    "THB", NULL, NULL },
891            { "de@rg=USZZZZ",       "USD", "USN", NULL },
892            { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL },
893    };
894    const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = {
895            2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1
896    };
897    /* ucurr_forLocale results for same locales; "" if no result expected */
898    const char *FORLOCALE[PREFERRED_SIZE] = {
899            "",    "",    "USD", "",
900            "THB", "",    "EUR", "",
901            "ILS", "CAD", "ZZZ", "DEM",
902            "THB", "USD", "CAD"
903    };
904    UErrorCode status = U_ZERO_ERROR;
905    int32_t i, j, size;
906    UEnumeration *pref, *all;
907    const char *loc = NULL;
908    UBool matchPref, matchAll;
909    const char *value = NULL;
910    int32_t valueLength = 0;
911
912    UList *ALLList = NULL;
913
914    UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status);
915    if (ALL == NULL) {
916        log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status));
917        return;
918    }
919
920    for (i = 0; i < PREFERRED_SIZE; i++) {
921        UChar getCurrU[4];
922        int32_t getCurrLen;
923
924        status = U_ZERO_ERROR;
925        pref = NULL;
926        all = NULL;
927        loc = PREFERRED[i][0];
928        pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status);
929        matchPref = FALSE;
930        matchAll = FALSE;
931
932        size = uenum_count(pref, &status);
933
934        if (size == EXPECTED_SIZE[i]) {
935            matchPref = TRUE;
936            for (j = 0; j < size; j++) {
937                if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
938                    if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) {
939                        log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]);
940
941                        matchPref = FALSE;
942                        break;
943                    }
944                } else {
945                    matchPref = FALSE;
946                    log_err("ERROR getting keyword value for locale \"%s\"\n", loc);
947                    break;
948                }
949            }
950        } else {
951            log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]);
952        }
953
954        if (!matchPref) {
955            log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc);
956            break;
957        }
958        uenum_close(pref);
959
960        all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status);
961
962        size = uenum_count(all, &status);
963
964        if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) {
965            matchAll = TRUE;
966            ALLList = ulist_getListFromEnum(ALL);
967            for (j = 0; j < size; j++) {
968                if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
969                    if (!ulist_containsString(ALLList, value, uprv_strlen(value))) {
970                        log_err("Locale %s have %s not in ALL\n", loc, value);
971                        matchAll = FALSE;
972                        break;
973                    }
974                } else {
975                    matchAll = FALSE;
976                    log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc);
977                    break;
978                }
979            }
980           if (!matchAll) {
981            log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc);
982           }
983        } else {
984            if(U_FAILURE(status)) {
985               log_err("ERROR: %s\n", u_errorName(status));
986            } else if(size!=uenum_count(ALL, &status)) {
987               log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status));
988            }
989        }
990
991        uenum_close(all);
992
993        status = U_ZERO_ERROR;
994        getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status);
995        if(U_FAILURE(status)) {
996            if (FORLOCALE[i][0] != 0) {
997                log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status));
998            }
999        } else if (getCurrLen != 3) {
1000            if (FORLOCALE[i][0] != 0 || getCurrLen != -1) {
1001                log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen);
1002            }
1003        } else {
1004            char getCurrB[4];
1005            u_UCharsToChars(getCurrU, getCurrB, 4);
1006            if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) {
1007                log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB);
1008            }
1009        }
1010    }
1011
1012    uenum_close(ALL);
1013
1014}
1015
1016/**
1017 * Test proper handling of rounding modes.
1018 */
1019static void TestRounding5350(void)
1020{
1021    UNumberFormat *nnf;
1022    UErrorCode status = U_ZERO_ERROR;
1023    /* this is supposed to open default date format, but later on it treats it like it is "en_US"
1024     - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
1025    /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
1026    nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
1027
1028    if(U_FAILURE(status)){
1029        log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
1030        return;
1031    }
1032
1033    unum_setAttribute(nnf, UNUM_MAX_FRACTION_DIGITS, 2);
1034    roundingTest2(nnf, -0.125, UNUM_ROUND_CEILING, "-0.12");
1035    roundingTest2(nnf, -0.125, UNUM_ROUND_FLOOR, "-0.13");
1036    roundingTest2(nnf, -0.125, UNUM_ROUND_DOWN, "-0.12");
1037    roundingTest2(nnf, -0.125, UNUM_ROUND_UP, "-0.13");
1038    roundingTest2(nnf, 0.125, UNUM_FOUND_HALFEVEN, "0.12");
1039    roundingTest2(nnf, 0.135, UNUM_ROUND_HALFDOWN, "0.13");
1040    roundingTest2(nnf, 0.125, UNUM_ROUND_HALFUP, "0.13");
1041    roundingTest2(nnf, 0.135, UNUM_FOUND_HALFEVEN, "0.14");
1042    /* The following are exactly represented, and shouldn't round */
1043    roundingTest2(nnf, 1.00, UNUM_ROUND_UP, "1");
1044    roundingTest2(nnf, 24.25, UNUM_ROUND_UP, "24.25");
1045    roundingTest2(nnf, 24.25, UNUM_ROUND_CEILING, "24.25");
1046    roundingTest2(nnf, -24.25, UNUM_ROUND_UP, "-24.25");
1047
1048    /* Differences pretty far out there */
1049    roundingTest2(nnf, 1.0000001, UNUM_ROUND_CEILING, "1.01");
1050    roundingTest2(nnf, 1.0000001, UNUM_ROUND_FLOOR, "1");
1051    roundingTest2(nnf, 1.0000001, UNUM_ROUND_DOWN, "1");
1052    roundingTest2(nnf, 1.0000001, UNUM_ROUND_UP, "1.01");
1053    roundingTest2(nnf, 1.0000001, UNUM_FOUND_HALFEVEN, "1");
1054    roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFDOWN, "1");
1055    roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFUP, "1");
1056
1057    roundingTest2(nnf, -1.0000001, UNUM_ROUND_CEILING, "-1");
1058    roundingTest2(nnf, -1.0000001, UNUM_ROUND_FLOOR, "-1.01");
1059    roundingTest2(nnf, -1.0000001, UNUM_ROUND_DOWN, "-1");
1060    roundingTest2(nnf, -1.0000001, UNUM_ROUND_UP, "-1.01");
1061    roundingTest2(nnf, -1.0000001, UNUM_FOUND_HALFEVEN, "-1");
1062    roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFDOWN, "-1");
1063    roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFUP, "-1");
1064
1065    unum_close(nnf);
1066}
1067
1068/*-------------------------------------*/
1069
1070static void roundingTest2(UNumberFormat* nf, double x, int32_t roundingMode, const char* expected)
1071{
1072    UChar *out = NULL;
1073    UChar *res;
1074    UFieldPosition pos;
1075    UErrorCode status;
1076    int32_t lneed;
1077    status=U_ZERO_ERROR;
1078    unum_setAttribute(nf, UNUM_ROUNDING_MODE, roundingMode);
1079    lneed=0;
1080    lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status);
1081    if(status==U_BUFFER_OVERFLOW_ERROR){
1082        status=U_ZERO_ERROR;
1083        out=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
1084        pos.field=0;
1085        unum_formatDouble(nf, x, out, lneed+1, &pos, &status);
1086    }
1087    if(U_FAILURE(status)) {
1088        log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
1089    }
1090    /*Need to use log_verbose here. Problem with the float*/
1091    /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/
1092    res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) );
1093    u_uastrcpy(res, expected);
1094    if (u_strcmp(out, res) != 0)
1095        log_err("FAIL: Expected: \"%s\"  Got: \"%s\"\n", expected, austrdup(out) );
1096    free(res);
1097    if(out != NULL) {
1098        free(out);
1099    }
1100}
1101
1102#endif /* #if !UCONFIG_NO_FORMATTING */
1103