1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2013, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/* Modification History:
7*   Date        Name        Description
8*   07/15/99    helena      Ported to HPUX 10/11 CC.
9*/
10
11#include "unicode/utypes.h"
12
13#if !UCONFIG_NO_FORMATTING
14
15#include "numfmtst.h"
16#include "unicode/dcfmtsym.h"
17#include "unicode/decimfmt.h"
18#include "unicode/localpointer.h"
19#include "unicode/ucurr.h"
20#include "unicode/ustring.h"
21#include "unicode/measfmt.h"
22#include "unicode/curramt.h"
23#include "digitlst.h"
24#include "textfile.h"
25#include "tokiter.h"
26#include "charstr.h"
27#include "putilimp.h"
28#include "winnmtst.h"
29#include <float.h>
30#include <string.h>
31#include <stdlib.h>
32#include "cstring.h"
33#include "unicode/numsys.h"
34#include "fmtableimp.h"
35
36//#define NUMFMTST_CACHE_DEBUG 1
37#include "stdio.h" /* for sprintf */
38// #include "iostream"   // for cout
39
40//#define NUMFMTST_DEBUG 1
41
42#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof(array[0]))
43
44static const UChar EUR[] = {69,85,82,0}; // "EUR"
45static const UChar ISO_CURRENCY_USD[] = {0x55, 0x53, 0x44, 0}; // "USD"
46
47// *****************************************************************************
48// class NumberFormatTest
49// *****************************************************************************
50
51#define CHECK(status,str) if (U_FAILURE(status)) { errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
52#define CHECK_DATA(status,str) if (U_FAILURE(status)) { dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
53
54void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
55{
56  TESTCASE_AUTO_BEGIN;
57  TESTCASE_AUTO(TestCurrencySign);
58  TESTCASE_AUTO(TestCurrency);
59  TESTCASE_AUTO(TestParse);
60  TESTCASE_AUTO(TestRounding487);
61  TESTCASE_AUTO(TestQuotes);
62  TESTCASE_AUTO(TestExponential);
63  TESTCASE_AUTO(TestPatterns);
64
65  // Upgrade to alphaWorks - liu 5/99
66  TESTCASE_AUTO(TestExponent);
67  TESTCASE_AUTO(TestScientific);
68  TESTCASE_AUTO(TestPad);
69  TESTCASE_AUTO(TestPatterns2);
70  TESTCASE_AUTO(TestSecondaryGrouping);
71  TESTCASE_AUTO(TestSurrogateSupport);
72  TESTCASE_AUTO(TestAPI);
73
74  TESTCASE_AUTO(TestCurrencyObject);
75  TESTCASE_AUTO(TestCurrencyPatterns);
76  //TESTCASE_AUTO(TestDigitList);
77  TESTCASE_AUTO(TestWhiteSpaceParsing);
78  TESTCASE_AUTO(TestComplexCurrency);  // This test removed because CLDR no longer uses choice formats in currency symbols.
79  TESTCASE_AUTO(TestRegCurrency);
80  TESTCASE_AUTO(TestSymbolsWithBadLocale);
81  TESTCASE_AUTO(TestAdoptDecimalFormatSymbols);
82
83  TESTCASE_AUTO(TestScientific2);
84  TESTCASE_AUTO(TestScientificGrouping);
85  TESTCASE_AUTO(TestInt64);
86
87  TESTCASE_AUTO(TestPerMill);
88  TESTCASE_AUTO(TestIllegalPatterns);
89  TESTCASE_AUTO(TestCases);
90
91  TESTCASE_AUTO(TestCurrencyNames);
92  TESTCASE_AUTO(TestCurrencyAmount);
93  TESTCASE_AUTO(TestCurrencyUnit);
94  TESTCASE_AUTO(TestCoverage);
95  TESTCASE_AUTO(TestJB3832);
96  TESTCASE_AUTO(TestHost);
97  TESTCASE_AUTO(TestHostClone);
98  TESTCASE_AUTO(TestCurrencyFormat);
99  TESTCASE_AUTO(TestRounding);
100  TESTCASE_AUTO(TestNonpositiveMultiplier);
101  TESTCASE_AUTO(TestNumberingSystems);
102  TESTCASE_AUTO(TestSpaceParsing);
103  TESTCASE_AUTO(TestMultiCurrencySign);
104  TESTCASE_AUTO(TestCurrencyFormatForMixParsing);
105  TESTCASE_AUTO(TestDecimalFormatCurrencyParse);
106  TESTCASE_AUTO(TestCurrencyIsoPluralFormat);
107  TESTCASE_AUTO(TestCurrencyParsing);
108  TESTCASE_AUTO(TestParseCurrencyInUCurr);
109  TESTCASE_AUTO(TestFormatAttributes);
110  TESTCASE_AUTO(TestFieldPositionIterator);
111  TESTCASE_AUTO(TestDecimal);
112  TESTCASE_AUTO(TestCurrencyFractionDigits);
113  TESTCASE_AUTO(TestExponentParse);
114  TESTCASE_AUTO(TestExplicitParents);
115  TESTCASE_AUTO(TestLenientParse);
116  TESTCASE_AUTO(TestAvailableNumberingSystems);
117  TESTCASE_AUTO(TestRoundingPattern);
118  TESTCASE_AUTO(Test9087);
119  TESTCASE_AUTO(TestFormatFastpaths);
120  TESTCASE_AUTO(TestFormattableSize);
121  TESTCASE_AUTO_END;
122}
123
124// -------------------------------------
125
126// Test API (increase code coverage)
127void
128NumberFormatTest::TestAPI(void)
129{
130  logln("Test API");
131  UErrorCode status = U_ZERO_ERROR;
132  NumberFormat *test = NumberFormat::createInstance("root", status);
133  if(U_FAILURE(status)) {
134    dataerrln("unable to create format object - %s", u_errorName(status));
135  }
136  if(test != NULL) {
137    test->setMinimumIntegerDigits(10);
138    test->setMaximumIntegerDigits(2);
139
140    test->setMinimumFractionDigits(10);
141    test->setMaximumFractionDigits(2);
142
143    UnicodeString result;
144    FieldPosition pos;
145    Formattable bla("Paja Patak"); // Donald Duck for non Serbian speakers
146    test->format(bla, result, pos, status);
147    if(U_SUCCESS(status)) {
148      errln("Yuck... Formatted a duck... As a number!");
149    } else {
150      status = U_ZERO_ERROR;
151    }
152
153    result.remove();
154    int64_t ll = 12;
155    test->format(ll, result);
156    if (result != "12.00"){
157        errln("format int64_t error");
158    }
159
160    ParsePosition ppos;
161    LocalPointer<CurrencyAmount> currAmt(test->parseCurrency("",ppos));
162    // old test for (U_FAILURE(status)) was bogus here, method does not set status!
163    if (ppos.getIndex()) {
164        errln("Parsed empty string as currency");
165    }
166
167    delete test;
168  }
169}
170
171class StubNumberForamt :public NumberFormat{
172public:
173    StubNumberForamt(){};
174    virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const {
175        return appendTo;
176    }
177    virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const {
178        return appendTo.append((UChar)0x0033);
179    }
180    virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const {
181        return NumberFormat::format(number, appendTo, pos);
182    }
183    virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const {
184        return appendTo;
185    }
186    virtual void parse(const UnicodeString& ,
187                    Formattable& ,
188                    ParsePosition& ) const {}
189    virtual void parse( const UnicodeString& ,
190                        Formattable& ,
191                        UErrorCode& ) const {}
192    virtual UClassID getDynamicClassID(void) const {
193        static char classID = 0;
194        return (UClassID)&classID;
195    }
196    virtual Format* clone() const {return NULL;}
197};
198
199void
200NumberFormatTest::TestCoverage(void){
201    StubNumberForamt stub;
202    UnicodeString agent("agent");
203    FieldPosition pos;
204    int64_t num = 4;
205    if (stub.format(num, agent, pos) != UnicodeString("agent3")){
206        errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
207    };
208}
209
210// Test various patterns
211void
212NumberFormatTest::TestPatterns(void)
213{
214    UErrorCode status = U_ZERO_ERROR;
215    DecimalFormatSymbols sym(Locale::getUS(), status);
216    if (U_FAILURE(status)) { errcheckln(status, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status)); return; }
217
218    const char* pat[]    = { "#.#", "#.", ".#", "#" };
219    int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0]));
220    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
221    const char* num[]    = { "0",   "0.", ".0", "0" };
222    for (int32_t i=0; i<pat_length; ++i)
223    {
224        status = U_ZERO_ERROR;
225        DecimalFormat fmt(pat[i], sym, status);
226        if (U_FAILURE(status)) { errln((UnicodeString)"FAIL: DecimalFormat constructor failed for " + pat[i]); continue; }
227        UnicodeString newp; fmt.toPattern(newp);
228        if (!(newp == newpat[i]))
229            errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +
230                  "; " + newp + " seen instead");
231
232        UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s);
233        if (!(s == num[i]))
234        {
235            errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +
236                  "; " + s + " seen instead");
237            logln((UnicodeString)"Min integer digits = " + fmt.getMinimumIntegerDigits());
238        }
239    }
240}
241
242/*
243icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
244icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
245icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
246*/
247/*
248void
249NumberFormatTest::TestDigitList(void)
250{
251  // API coverage for DigitList
252  DigitList list1;
253  list1.append('1');
254  list1.fDecimalAt = 1;
255  DigitList list2;
256  list2.set((int32_t)1);
257  if (list1 != list2) {
258    errln("digitlist append, operator!= or set failed ");
259  }
260  if (!(list1 == list2)) {
261    errln("digitlist append, operator== or set failed ");
262  }
263}
264*/
265
266// -------------------------------------
267
268// Test exponential pattern
269void
270NumberFormatTest::TestExponential(void)
271{
272    UErrorCode status = U_ZERO_ERROR;
273    DecimalFormatSymbols sym(Locale::getUS(), status);
274    if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; }
275    const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]"  };
276    int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0]));
277
278// The following #if statements allow this test to be built and run on
279// platforms that do not have standard IEEE numerics.  For example,
280// S/390 doubles have an exponent range of -78 to +75.  For the
281// following #if statements to work, float.h must define
282// DBL_MAX_10_EXP to be a compile-time constant.
283
284// This section may be expanded as needed.
285
286#if DBL_MAX_10_EXP > 300
287    double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
288    int32_t val_length = (int32_t)(sizeof(val) / sizeof(val[0]));
289    const char* valFormat[] =
290    {
291        // 0.####E0
292        "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
293        // 00.000E00
294        "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
295        // ##0.######E000
296        "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
297        // 0.###E0;[0.###E0]
298        "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
299    };
300    double valParse[] =
301    {
302        0.01234, 123460000, 1.23E300, -3.1416E-271,
303        0.01234, 123460000, 1.23E300, -3.1416E-271,
304        0.01234, 123456800, 1.23E300, -3.141593E-271,
305        0.01234, 123500000, 1.23E300, -3.142E-271,
306    };
307#elif DBL_MAX_10_EXP > 70
308    double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 };
309    int32_t val_length = sizeof(val) / sizeof(val[0]);
310    char* valFormat[] =
311    {
312        // 0.####E0
313        "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
314        // 00.000E00
315        "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
316        // ##0.######E000
317        "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
318        // 0.###E0;[0.###E0]
319        "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
320    };
321    double valParse[] =
322    {
323        0.01234, 123460000, 1.23E70, -3.1416E-71,
324        0.01234, 123460000, 1.23E70, -3.1416E-71,
325        0.01234, 123456800, 1.23E70, -3.141593E-71,
326        0.01234, 123500000, 1.23E70, -3.142E-71,
327    };
328#else
329    // Don't test double conversion
330    double* val = 0;
331    int32_t val_length = 0;
332    char** valFormat = 0;
333    double* valParse = 0;
334    logln("Warning: Skipping double conversion tests");
335#endif
336
337    int32_t lval[] = { 0, -1, 1, 123456789 };
338    int32_t lval_length = (int32_t)(sizeof(lval) / sizeof(lval[0]));
339    const char* lvalFormat[] =
340    {
341        // 0.####E0
342        "0E0", "-1E0", "1E0", "1.2346E8",
343        // 00.000E00
344        "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
345        // ##0.######E000
346        "0E000", "-1E000", "1E000", "123.4568E006",
347        // 0.###E0;[0.###E0]
348        "0E0", "[1E0]", "1E0", "1.235E8"
349    };
350    int32_t lvalParse[] =
351    {
352        0, -1, 1, 123460000,
353        0, -1, 1, 123460000,
354        0, -1, 1, 123456800,
355        0, -1, 1, 123500000,
356    };
357    int32_t ival = 0, ilval = 0;
358    for (int32_t p=0; p<pat_length; ++p)
359    {
360        DecimalFormat fmt(pat[p], sym, status);
361        if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
362        UnicodeString pattern;
363        logln((UnicodeString)"Pattern \"" + pat[p] + "\" -toPattern-> \"" +
364          fmt.toPattern(pattern) + "\"");
365        int32_t v;
366        for (v=0; v<val_length; ++v)
367        {
368            UnicodeString s; (*(NumberFormat*)&fmt).format(val[v], s);
369            logln((UnicodeString)" " + val[v] + " -format-> " + s);
370            if (s != valFormat[v+ival])
371                errln((UnicodeString)"FAIL: Expected " + valFormat[v+ival]);
372
373            ParsePosition pos(0);
374            Formattable af;
375            fmt.parse(s, af, pos);
376            double a;
377            UBool useEpsilon = FALSE;
378            if (af.getType() == Formattable::kLong)
379                a = af.getLong();
380            else if (af.getType() == Formattable::kDouble) {
381                a = af.getDouble();
382#if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
383                // S/390 will show a failure like this:
384                //| -3.141592652999999e-271 -format-> -3.1416E-271
385                //|                          -parse-> -3.1416e-271
386                //| FAIL: Expected -3.141599999999999e-271
387                // To compensate, we use an epsilon-based equality
388                // test on S/390 only.  We don't want to do this in
389                // general because it's less exacting.
390                useEpsilon = TRUE;
391#endif
392            }
393            else {
394                errln((UnicodeString)"FAIL: Non-numeric Formattable returned");
395                continue;
396            }
397            if (pos.getIndex() == s.length())
398            {
399                logln((UnicodeString)"  -parse-> " + a);
400                // Use epsilon comparison as necessary
401                if ((useEpsilon &&
402                    (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
403                    (!useEpsilon && a != valParse[v+ival]))
404                {
405                    errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]);
406                }
407            }
408            else {
409                errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
410                errln((UnicodeString)"  should be (" + s.length() + " chars) -> " + valParse[v+ival]);
411            }
412        }
413        for (v=0; v<lval_length; ++v)
414        {
415            UnicodeString s;
416            (*(NumberFormat*)&fmt).format(lval[v], s);
417            logln((UnicodeString)" " + lval[v] + "L -format-> " + s);
418            if (s != lvalFormat[v+ilval])
419                errln((UnicodeString)"ERROR: Expected " + lvalFormat[v+ilval] + " Got: " + s);
420
421            ParsePosition pos(0);
422            Formattable af;
423            fmt.parse(s, af, pos);
424            if (af.getType() == Formattable::kLong ||
425                af.getType() == Formattable::kInt64) {
426                UErrorCode status = U_ZERO_ERROR;
427                int32_t a = af.getLong(status);
428                if (pos.getIndex() == s.length())
429                {
430                    logln((UnicodeString)"  -parse-> " + a);
431                    if (a != lvalParse[v+ilval])
432                        errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]);
433                }
434                else
435                    errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
436            }
437            else
438                errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s
439                    + " Double: " + af.getDouble()
440                    + ", Long: " + af.getLong());
441        }
442        ival += val_length;
443        ilval += lval_length;
444    }
445}
446
447void
448NumberFormatTest::TestScientific2() {
449    // jb 2552
450    UErrorCode status = U_ZERO_ERROR;
451    DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
452    if (U_SUCCESS(status)) {
453        double num = 12.34;
454        expect(*fmt, num, "$12.34");
455        fmt->setScientificNotation(TRUE);
456        expect(*fmt, num, "$1.23E1");
457        fmt->setScientificNotation(FALSE);
458        expect(*fmt, num, "$12.34");
459    }
460    delete fmt;
461}
462
463void
464NumberFormatTest::TestScientificGrouping() {
465    // jb 2552
466    UErrorCode status = U_ZERO_ERROR;
467    DecimalFormat fmt("##0.00E0",status);
468    if (U_SUCCESS(status)) {
469        expect(fmt, .01234, "12.3E-3");
470        expect(fmt, .1234, "123E-3");
471        expect(fmt, 1.234, "1.23E0");
472        expect(fmt, 12.34, "12.3E0");
473        expect(fmt, 123.4, "123E0");
474        expect(fmt, 1234., "1.23E3");
475    }
476}
477
478/*static void setFromString(DigitList& dl, const char* str) {
479    char c;
480    UBool decimalSet = FALSE;
481    dl.clear();
482    while ((c = *str++)) {
483        if (c == '-') {
484            dl.fIsPositive = FALSE;
485        } else if (c == '+') {
486            dl.fIsPositive = TRUE;
487        } else if (c == '.') {
488            dl.fDecimalAt = dl.fCount;
489            decimalSet = TRUE;
490        } else {
491            dl.append(c);
492        }
493    }
494    if (!decimalSet) {
495        dl.fDecimalAt = dl.fCount;
496    }
497}*/
498
499void
500NumberFormatTest::TestInt64() {
501    UErrorCode status = U_ZERO_ERROR;
502    DecimalFormat fmt("#.#E0",status);
503    fmt.setMaximumFractionDigits(20);
504    if (U_SUCCESS(status)) {
505        expect(fmt, (Formattable)(int64_t)0, "0E0");
506        expect(fmt, (Formattable)(int64_t)-1, "-1E0");
507        expect(fmt, (Formattable)(int64_t)1, "1E0");
508        expect(fmt, (Formattable)(int64_t)2147483647, "2.147483647E9");
509        expect(fmt, (Formattable)((int64_t)-2147483647-1), "-2.147483648E9");
510        expect(fmt, (Formattable)(int64_t)U_INT64_MAX, "9.223372036854775807E18");
511        expect(fmt, (Formattable)(int64_t)U_INT64_MIN, "-9.223372036854775808E18");
512    }
513
514    // also test digitlist
515/*    int64_t int64max = U_INT64_MAX;
516    int64_t int64min = U_INT64_MIN;
517    const char* int64maxstr = "9223372036854775807";
518    const char* int64minstr = "-9223372036854775808";
519    UnicodeString fail("fail: ");
520
521    // test max int64 value
522    DigitList dl;
523    setFromString(dl, int64maxstr);
524    {
525        if (!dl.fitsIntoInt64(FALSE)) {
526            errln(fail + int64maxstr + " didn't fit");
527        }
528        int64_t int64Value = dl.getInt64();
529        if (int64Value != int64max) {
530            errln(fail + int64maxstr);
531        }
532        dl.set(int64Value);
533        int64Value = dl.getInt64();
534        if (int64Value != int64max) {
535            errln(fail + int64maxstr);
536        }
537    }
538    // test negative of max int64 value (1 shy of min int64 value)
539    dl.fIsPositive = FALSE;
540    {
541        if (!dl.fitsIntoInt64(FALSE)) {
542            errln(fail + "-" + int64maxstr + " didn't fit");
543        }
544        int64_t int64Value = dl.getInt64();
545        if (int64Value != -int64max) {
546            errln(fail + "-" + int64maxstr);
547        }
548        dl.set(int64Value);
549        int64Value = dl.getInt64();
550        if (int64Value != -int64max) {
551            errln(fail + "-" + int64maxstr);
552        }
553    }
554    // test min int64 value
555    setFromString(dl, int64minstr);
556    {
557        if (!dl.fitsIntoInt64(FALSE)) {
558            errln(fail + "-" + int64minstr + " didn't fit");
559        }
560        int64_t int64Value = dl.getInt64();
561        if (int64Value != int64min) {
562            errln(fail + int64minstr);
563        }
564        dl.set(int64Value);
565        int64Value = dl.getInt64();
566        if (int64Value != int64min) {
567            errln(fail + int64minstr);
568        }
569    }
570    // test negative of min int 64 value (1 more than max int64 value)
571    dl.fIsPositive = TRUE; // won't fit
572    {
573        if (dl.fitsIntoInt64(FALSE)) {
574            errln(fail + "-(" + int64minstr + ") didn't fit");
575        }
576    }*/
577}
578
579// -------------------------------------
580
581// Test the handling of quotes
582void
583NumberFormatTest::TestQuotes(void)
584{
585    UErrorCode status = U_ZERO_ERROR;
586    UnicodeString *pat;
587    DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status);
588    if (U_FAILURE(status)) {
589        errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
590        delete sym;
591        return;
592    }
593    pat = new UnicodeString("a'fo''o'b#");
594    DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status);
595    UnicodeString s;
596    ((NumberFormat*)fmt)->format((int32_t)123, s);
597    logln((UnicodeString)"Pattern \"" + *pat + "\"");
598    logln((UnicodeString)" Format 123 -> " + escape(s));
599    if (!(s=="afo'ob123"))
600        errln((UnicodeString)"FAIL: Expected afo'ob123");
601
602    s.truncate(0);
603    delete fmt;
604    delete pat;
605
606    pat = new UnicodeString("a''b#");
607    fmt = new DecimalFormat(*pat, *sym, status);
608    ((NumberFormat*)fmt)->format((int32_t)123, s);
609    logln((UnicodeString)"Pattern \"" + *pat + "\"");
610    logln((UnicodeString)" Format 123 -> " + escape(s));
611    if (!(s=="a'b123"))
612        errln((UnicodeString)"FAIL: Expected a'b123");
613    delete fmt;
614    delete pat;
615    delete sym;
616}
617
618/**
619 * Test the handling of the currency symbol in patterns.
620 */
621void
622NumberFormatTest::TestCurrencySign(void)
623{
624    UErrorCode status = U_ZERO_ERROR;
625    DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status);
626    UnicodeString pat;
627    UChar currency = 0x00A4;
628    if (U_FAILURE(status)) {
629        errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
630        delete sym;
631        return;
632    }
633    // "\xA4#,##0.00;-\xA4#,##0.00"
634    pat.append(currency).append("#,##0.00;-").
635        append(currency).append("#,##0.00");
636    DecimalFormat *fmt = new DecimalFormat(pat, *sym, status);
637    UnicodeString s; ((NumberFormat*)fmt)->format(1234.56, s);
638    pat.truncate(0);
639    logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
640    logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
641    if (s != "$1,234.56") dataerrln((UnicodeString)"FAIL: Expected $1,234.56");
642    s.truncate(0);
643    ((NumberFormat*)fmt)->format(- 1234.56, s);
644    logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
645    if (s != "-$1,234.56") dataerrln((UnicodeString)"FAIL: Expected -$1,234.56");
646    delete fmt;
647    pat.truncate(0);
648    // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
649    pat.append(currency).append(currency).
650        append(" #,##0.00;").
651        append(currency).append(currency).
652        append(" -#,##0.00");
653    fmt = new DecimalFormat(pat, *sym, status);
654    s.truncate(0);
655    ((NumberFormat*)fmt)->format(1234.56, s);
656    logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
657    logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
658    if (s != "USD 1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD 1,234.56");
659    s.truncate(0);
660    ((NumberFormat*)fmt)->format(-1234.56, s);
661    logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
662    if (s != "USD -1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD -1,234.56");
663    delete fmt;
664    delete sym;
665    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + u_errorName(status));
666}
667
668// -------------------------------------
669
670static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
671
672UnicodeString&
673NumberFormatTest::escape(UnicodeString& s)
674{
675    UnicodeString buf;
676    for (int32_t i=0; i<s.length(); ++i)
677    {
678        UChar c = s[(int32_t)i];
679        if (c <= (UChar)0x7F) buf += c;
680        else {
681            buf += (UChar)0x5c; buf += (UChar)0x55;
682            buf += toHexString((c & 0xF000) >> 12);
683            buf += toHexString((c & 0x0F00) >> 8);
684            buf += toHexString((c & 0x00F0) >> 4);
685            buf += toHexString(c & 0x000F);
686        }
687    }
688    return (s = buf);
689}
690
691
692// -------------------------------------
693static const char* testCases[][2]= {
694     /* locale ID */  /* expected */
695    {"ca_ES_PREEURO", "\\u20A7\\u00A01.150" },
696    {"de_LU_PREEURO", "1,150\\u00A0F" },
697    {"el_GR_PREEURO", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" },
698    {"en_BE_PREEURO", "1.150,50\\u00A0BEF" },
699    {"es_ES_PREEURO", "1.150\\u00A0\\u20A7" },
700    {"eu_ES_PREEURO", "\\u20A7\\u00A01.150" },
701    {"gl_ES_PREEURO", "1.150\\u00A0\\u20A7" },
702    {"it_IT_PREEURO", "ITL\\u00A01.150" },
703    {"pt_PT_PREEURO", "1,150$50\\u00A0Esc."},
704    {"en_US@currency=JPY", "\\u00A51,150"},
705    {"en_US@currency=jpy", "\\u00A51,150"},
706    {"en-US-u-cu-jpy", "\\u00A51,150"}
707};
708/**
709 * Test localized currency patterns.
710 */
711void
712NumberFormatTest::TestCurrency(void)
713{
714    UErrorCode status = U_ZERO_ERROR;
715    NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
716    if (U_FAILURE(status)) {
717        dataerrln("Error calling NumberFormat::createCurrencyInstance()");
718        return;
719    }
720
721    UnicodeString s; currencyFmt->format(1.50, s);
722    logln((UnicodeString)"Un pauvre ici a..........." + s);
723    if (!(s==CharsToUnicodeString("1,50\\u00A0$")))
724        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$");
725    delete currencyFmt;
726    s.truncate(0);
727    char loc[256]={0};
728    int len = uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
729    currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status);
730    currencyFmt->format(1.50, s);
731    logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
732    if (!(s==CharsToUnicodeString("1,50\\u00A0DEM")))
733        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DEM");
734    delete currencyFmt;
735    s.truncate(0);
736    len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
737    currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
738    currencyFmt->format(1.50, s);
739    logln((UnicodeString)"Un pauvre en France a....." + s);
740    if (!(s==CharsToUnicodeString("1,50\\u00A0F")))
741        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>F");
742    delete currencyFmt;
743    if (U_FAILURE(status))
744        errln((UnicodeString)"FAIL: Status " + (int32_t)status);
745
746    for(int i=0; i < (int)(sizeof(testCases)/sizeof(testCases[i])); i++){
747        status = U_ZERO_ERROR;
748        const char *localeID = testCases[i][0];
749        UnicodeString expected(testCases[i][1], -1, US_INV);
750        expected = expected.unescape();
751        s.truncate(0);
752        char loc[256]={0};
753        uloc_canonicalize(localeID, loc, 256, &status);
754        currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
755        if(U_FAILURE(status)){
756            errln("Could not create currency formatter for locale %s",localeID);
757            continue;
758        }
759        currencyFmt->format(1150.50, s);
760        if(s!=expected){
761            errln(UnicodeString("FAIL: Expected: ")+expected
762                    + UnicodeString(" Got: ") + s
763                    + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
764        }
765        if (U_FAILURE(status)){
766            errln((UnicodeString)"FAIL: Status " + (int32_t)status);
767        }
768        delete currencyFmt;
769    }
770}
771
772// -------------------------------------
773
774/**
775 * Test the Currency object handling, new as of ICU 2.2.
776 */
777void NumberFormatTest::TestCurrencyObject() {
778    UErrorCode ec = U_ZERO_ERROR;
779    NumberFormat* fmt =
780        NumberFormat::createCurrencyInstance(Locale::getUS(), ec);
781
782    if (U_FAILURE(ec)) {
783        dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec));
784        delete fmt;
785        return;
786    }
787
788    Locale null("", "", "");
789
790    expectCurrency(*fmt, null, 1234.56, "$1,234.56");
791
792    expectCurrency(*fmt, Locale::getFrance(),
793                   1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
794
795    expectCurrency(*fmt, Locale::getJapan(),
796                   1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
797
798    expectCurrency(*fmt, Locale("fr", "CH", ""),
799                   1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
800
801    expectCurrency(*fmt, Locale::getUS(),
802                   1234.56, "$1,234.56");
803
804    delete fmt;
805    fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec);
806
807    if (U_FAILURE(ec)) {
808        errln("FAIL: getCurrencyInstance(FRANCE)");
809        delete fmt;
810        return;
811    }
812
813    expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
814
815    expectCurrency(*fmt, Locale::getJapan(),
816                   1234.56, CharsToUnicodeString("1 235 \\u00A5JP")); // Yen
817
818    expectCurrency(*fmt, Locale("fr", "CH", ""),
819                   1234.56, "1 234,56 CHF"); // no more 0.05 rounding here, see cldrbug 5548
820
821    expectCurrency(*fmt, Locale::getUS(),
822                   1234.56, "1 234,56 $US");
823
824    expectCurrency(*fmt, Locale::getFrance(),
825                   1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
826
827    delete fmt;
828}
829
830// -------------------------------------
831
832/**
833 * Do rudimentary testing of parsing.
834 */
835void
836NumberFormatTest::TestParse(void)
837{
838    UErrorCode status = U_ZERO_ERROR;
839    UnicodeString arg("0");
840    DecimalFormat* format = new DecimalFormat("00", status);
841    //try {
842        Formattable n; format->parse(arg, n, status);
843        logln((UnicodeString)"parse(" + arg + ") = " + n.getLong());
844        if (n.getType() != Formattable::kLong ||
845            n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0");
846    delete format;
847    if (U_FAILURE(status)) errcheckln(status, (UnicodeString)"FAIL: Status " + u_errorName(status));
848    //}
849    //catch(Exception e) {
850    //    errln((UnicodeString)"Exception caught: " + e);
851    //}
852}
853
854// -------------------------------------
855
856static const char *lenientAffixTestCases[] = {
857        "(1)",
858        "( 1)",
859        "(1 )",
860        "( 1 )"
861};
862
863static const char *lenientMinusTestCases[] = {
864    "-5",
865    "\\u22125",
866    "\\u20105"
867};
868
869static const char *lenientCurrencyTestCases[] = {
870        "$1,000",
871        "$ 1,000",
872        "$1000",
873        "$ 1000",
874        "$1 000.00",
875        "$ 1 000.00",
876        "$ 1\\u00A0000.00",
877        "1000.00"
878};
879
880static const char *lenientNegativeCurrencyTestCases[] = {
881        "($1,000)",
882        "($ 1,000)",
883        "($1000)",
884        "($ 1000)",
885        "($1 000.00)",
886        "($ 1 000.00)",
887        "( $ 1,000.00 )",
888        "($ 1\\u00A0000.00)",
889        "(1000.00)"
890};
891
892static const char *lenientPercentTestCases[] = {
893        "25%",
894        " 25%",
895        " 25 %",
896    	"25 %",
897		"25\\u00A0%",
898		"25"
899};
900
901static const char *lenientNegativePercentTestCases[] = {
902		"-25%",
903		" -25%",
904		" - 25%",
905		"- 25 %",
906		" - 25 %",
907		"-25 %",
908		"-25\\u00A0%",
909		"-25",
910		"- 25"
911};
912
913static const char *strictFailureTestCases[] = {
914		" 1000",
915		"10,00",
916		"1,000,.0"
917};
918
919#define ARRAY_SIZE(array) ((int32_t) (sizeof (array) / sizeof(array[0])))
920
921/**
922 * Test lenient parsing.
923 */
924void
925NumberFormatTest::TestLenientParse(void)
926{
927    UErrorCode status = U_ZERO_ERROR;
928    DecimalFormat *format = new DecimalFormat("(#,##0)", status);
929    Formattable n;
930
931    if (format == NULL || U_FAILURE(status)) {
932        dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status));
933    } else {
934        format->setLenient(TRUE);
935        for (int32_t t = 0; t < ARRAY_SIZE (lenientAffixTestCases); t += 1) {
936        	UnicodeString testCase = ctou(lenientAffixTestCases[t]);
937
938            format->parse(testCase, n, status);
939            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
940
941            if (U_FAILURE(status) || n.getType() != Formattable::kLong ||
942            	n.getLong() != 1) {
943            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t] + (UnicodeString) "\"");
944            	status = U_ZERO_ERROR;
945            }
946       }
947       delete format;
948    }
949
950    Locale en_US("en_US");
951    Locale sv_SE("sv_SE");
952
953    NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status);
954
955    if (mFormat == NULL || U_FAILURE(status)) {
956        dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status));
957    } else {
958        mFormat->setLenient(TRUE);
959        for (int32_t t = 0; t < ARRAY_SIZE(lenientMinusTestCases); t += 1) {
960            UnicodeString testCase = ctou(lenientMinusTestCases[t]);
961
962            mFormat->parse(testCase, n, status);
963            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
964
965            if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
966                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
967                status = U_ZERO_ERROR;
968            }
969        }
970        delete mFormat;
971    }
972
973    mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status);
974
975    if (mFormat == NULL || U_FAILURE(status)) {
976        dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status));
977    } else {
978        mFormat->setLenient(TRUE);
979        for (int32_t t = 0; t < ARRAY_SIZE(lenientMinusTestCases); t += 1) {
980            UnicodeString testCase = ctou(lenientMinusTestCases[t]);
981
982            mFormat->parse(testCase, n, status);
983            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
984
985            if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
986                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
987                status = U_ZERO_ERROR;
988            }
989        }
990        delete mFormat;
991    }
992
993    NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status);
994
995    if (cFormat == NULL || U_FAILURE(status)) {
996        dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status));
997    } else {
998        cFormat->setLenient(TRUE);
999        for (int32_t t = 0; t < ARRAY_SIZE (lenientCurrencyTestCases); t += 1) {
1000        	UnicodeString testCase = ctou(lenientCurrencyTestCases[t]);
1001
1002            cFormat->parse(testCase, n, status);
1003            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1004
1005            if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1006            	n.getLong() != 1000) {
1007            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t] + (UnicodeString) "\"");
1008            	status = U_ZERO_ERROR;
1009            }
1010        }
1011
1012        for (int32_t t = 0; t < ARRAY_SIZE (lenientNegativeCurrencyTestCases); t += 1) {
1013        	UnicodeString testCase = ctou(lenientNegativeCurrencyTestCases[t]);
1014
1015            cFormat->parse(testCase, n, status);
1016            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1017
1018            if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1019            	n.getLong() != -1000) {
1020            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t] + (UnicodeString) "\"");
1021            	status = U_ZERO_ERROR;
1022            }
1023        }
1024
1025        delete cFormat;
1026    }
1027
1028    NumberFormat *pFormat = NumberFormat::createPercentInstance(en_US, status);
1029
1030    if (pFormat == NULL || U_FAILURE(status)) {
1031        dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status));
1032    } else {
1033        pFormat->setLenient(TRUE);
1034        for (int32_t t = 0; t < ARRAY_SIZE (lenientPercentTestCases); t += 1) {
1035        	UnicodeString testCase = ctou(lenientPercentTestCases[t]);
1036
1037        	pFormat->parse(testCase, n, status);
1038            logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
1039
1040            if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1041            	n.getDouble() != 0.25) {
1042            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t] + (UnicodeString) "\"");
1043            	status = U_ZERO_ERROR;
1044            }
1045        }
1046
1047        for (int32_t t = 0; t < ARRAY_SIZE (lenientNegativePercentTestCases); t += 1) {
1048        	UnicodeString testCase = ctou(lenientNegativePercentTestCases[t]);
1049
1050        	pFormat->parse(testCase, n, status);
1051            logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
1052
1053            if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1054            	n.getDouble() != -0.25) {
1055            	errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t] + (UnicodeString) "\"");
1056            	status = U_ZERO_ERROR;
1057            }
1058        }
1059
1060        delete pFormat;
1061    }
1062
1063   // Test cases that should fail with a strict parse and pass with a
1064   // lenient parse.
1065   NumberFormat *nFormat = NumberFormat::createInstance(en_US, status);
1066
1067   if (nFormat == NULL || U_FAILURE(status)) {
1068       dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status));
1069   } else {
1070       // first, make sure that they fail with a strict parse
1071       for (int32_t t = 0; t < ARRAY_SIZE(strictFailureTestCases); t += 1) {
1072	       UnicodeString testCase = ctou(strictFailureTestCases[t]);
1073
1074	       nFormat->parse(testCase, n, status);
1075	       logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1076
1077	       if (! U_FAILURE(status)) {
1078		       errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
1079	       }
1080
1081	       status = U_ZERO_ERROR;
1082       }
1083
1084       // then, make sure that they pass with a lenient parse
1085       nFormat->setLenient(TRUE);
1086       for (int32_t t = 0; t < ARRAY_SIZE(strictFailureTestCases); t += 1) {
1087	       UnicodeString testCase = ctou(strictFailureTestCases[t]);
1088
1089	       nFormat->parse(testCase, n, status);
1090	       logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1091
1092	       if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1093	            	n.getLong() != 1000) {
1094		       errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
1095		       status = U_ZERO_ERROR;
1096	       }
1097       }
1098
1099       delete nFormat;
1100   }
1101}
1102
1103// -------------------------------------
1104
1105/**
1106 * Test proper rounding by the format method.
1107 */
1108void
1109NumberFormatTest::TestRounding487(void)
1110{
1111    UErrorCode status = U_ZERO_ERROR;
1112    NumberFormat *nf = NumberFormat::createInstance(status);
1113    if (U_FAILURE(status)) {
1114        dataerrln("Error calling NumberFormat::createInstance()");
1115        return;
1116    }
1117
1118    roundingTest(*nf, 0.00159999, 4, "0.0016");
1119    roundingTest(*nf, 0.00995, 4, "0.01");
1120
1121    roundingTest(*nf, 12.3995, 3, "12.4");
1122
1123    roundingTest(*nf, 12.4999, 0, "12");
1124    roundingTest(*nf, - 19.5, 0, "-20");
1125    delete nf;
1126    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
1127}
1128
1129/**
1130 * Test the functioning of the secondary grouping value.
1131 */
1132void NumberFormatTest::TestSecondaryGrouping(void) {
1133    UErrorCode status = U_ZERO_ERROR;
1134    DecimalFormatSymbols US(Locale::getUS(), status);
1135    CHECK(status, "DecimalFormatSymbols ct");
1136
1137    DecimalFormat f("#,##,###", US, status);
1138    CHECK(status, "DecimalFormat ct");
1139
1140    expect2(f, (int32_t)123456789L, "12,34,56,789");
1141    expectPat(f, "#,##,###");
1142    f.applyPattern("#,###", status);
1143    CHECK(status, "applyPattern");
1144
1145    f.setSecondaryGroupingSize(4);
1146    expect2(f, (int32_t)123456789L, "12,3456,789");
1147    expectPat(f, "#,####,###");
1148    NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
1149    CHECK_DATA(status, "createInstance(hi_IN)");
1150
1151    UnicodeString out;
1152    int32_t l = (int32_t)1876543210L;
1153    g->format(l, out);
1154    delete g;
1155    // expect "1,87,65,43,210", but with Hindi digits
1156    //         01234567890123
1157    UBool ok = TRUE;
1158    if (out.length() != 14) {
1159        ok = FALSE;
1160    } else {
1161        for (int32_t i=0; i<out.length(); ++i) {
1162            UBool expectGroup = FALSE;
1163            switch (i) {
1164            case 1:
1165            case 4:
1166            case 7:
1167            case 10:
1168                expectGroup = TRUE;
1169                break;
1170            }
1171            // Later -- fix this to get the actual grouping
1172            // character from the resource bundle.
1173            UBool isGroup = (out.charAt(i) == 0x002C);
1174            if (isGroup != expectGroup) {
1175                ok = FALSE;
1176                break;
1177            }
1178        }
1179    }
1180    if (!ok) {
1181        errln((UnicodeString)"FAIL  Expected " + l +
1182              " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
1183              escape(out) + "\"");
1184    } else {
1185        logln((UnicodeString)"Ok    " + l +
1186              " x hi_IN -> \"" +
1187              escape(out) + "\"");
1188    }
1189}
1190
1191void NumberFormatTest::TestWhiteSpaceParsing(void) {
1192    UErrorCode ec = U_ZERO_ERROR;
1193    DecimalFormatSymbols US(Locale::getUS(), ec);
1194    DecimalFormat fmt("a  b#0c  ", US, ec);
1195    if (U_FAILURE(ec)) {
1196        errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec));
1197        return;
1198    }
1199    int32_t n = 1234;
1200    expect(fmt, "a b1234c ", n);
1201    expect(fmt, "a   b1234c   ", n);
1202}
1203
1204/**
1205 * Test currencies whose display name is a ChoiceFormat.
1206 */
1207void NumberFormatTest::TestComplexCurrency() {
1208
1209//    UErrorCode ec = U_ZERO_ERROR;
1210//    Locale loc("kn", "IN", "");
1211//    NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
1212//    if (U_SUCCESS(ec)) {
1213//        expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00"));
1214//        Use .00392625 because that's 2^-8.  Any value less than 0.005 is fine.
1215//        expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky
1216//        expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00"));
1217//        expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50"));
1218//        expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00"));
1219//        expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00"));
1220//    } else {
1221//        errln("FAIL: getCurrencyInstance(kn_IN)");
1222//    }
1223//    delete fmt;
1224
1225}
1226
1227// -------------------------------------
1228
1229void
1230NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected)
1231{
1232    nf.setMaximumFractionDigits(maxFractionDigits);
1233    UnicodeString out; nf.format(x, out);
1234    logln((UnicodeString)"" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);
1235    if (!(out==expected)) errln((UnicodeString)"FAIL: Expected " + expected);
1236}
1237
1238/**
1239 * Upgrade to alphaWorks
1240 */
1241void NumberFormatTest::TestExponent(void) {
1242    UErrorCode status = U_ZERO_ERROR;
1243    DecimalFormatSymbols US(Locale::getUS(), status);
1244    CHECK(status, "DecimalFormatSymbols constructor");
1245    DecimalFormat fmt1(UnicodeString("0.###E0"), US, status);
1246    CHECK(status, "DecimalFormat(0.###E0)");
1247    DecimalFormat fmt2(UnicodeString("0.###E+0"), US, status);
1248    CHECK(status, "DecimalFormat(0.###E+0)");
1249    int32_t n = 1234;
1250    expect2(fmt1, n, "1.234E3");
1251    expect2(fmt2, n, "1.234E+3");
1252    expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
1253}
1254
1255/**
1256 * Upgrade to alphaWorks
1257 */
1258void NumberFormatTest::TestScientific(void) {
1259    UErrorCode status = U_ZERO_ERROR;
1260    DecimalFormatSymbols US(Locale::getUS(), status);
1261    CHECK(status, "DecimalFormatSymbols constructor");
1262
1263    // Test pattern round-trip
1264    const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
1265                          "0.###E0;[0.###E0]" };
1266    int32_t PAT_length = (int32_t)(sizeof(PAT) / sizeof(PAT[0]));
1267    int32_t DIGITS[] = {
1268        // min int, max int, min frac, max frac
1269        0, 1, 0, 0, // "#E0"
1270        1, 1, 0, 4, // "0.####E0"
1271        2, 2, 3, 3, // "00.000E00"
1272        1, 3, 0, 4, // "##0.####E000"
1273        1, 1, 0, 3, // "0.###E0;[0.###E0]"
1274    };
1275    for (int32_t i=0; i<PAT_length; ++i) {
1276        UnicodeString pat(PAT[i]);
1277        DecimalFormat df(pat, US, status);
1278        CHECK(status, "DecimalFormat constructor");
1279        UnicodeString pat2;
1280        df.toPattern(pat2);
1281        if (pat == pat2) {
1282            logln(UnicodeString("Ok   Pattern rt \"") +
1283                  pat + "\" -> \"" +
1284                  pat2 + "\"");
1285        } else {
1286            errln(UnicodeString("FAIL Pattern rt \"") +
1287                  pat + "\" -> \"" +
1288                  pat2 + "\"");
1289        }
1290        // Make sure digit counts match what we expect
1291        if (df.getMinimumIntegerDigits() != DIGITS[4*i] ||
1292            df.getMaximumIntegerDigits() != DIGITS[4*i+1] ||
1293            df.getMinimumFractionDigits() != DIGITS[4*i+2] ||
1294            df.getMaximumFractionDigits() != DIGITS[4*i+3]) {
1295            errln(UnicodeString("FAIL \"" + pat +
1296                                "\" min/max int; min/max frac = ") +
1297                  df.getMinimumIntegerDigits() + "/" +
1298                  df.getMaximumIntegerDigits() + ";" +
1299                  df.getMinimumFractionDigits() + "/" +
1300                  df.getMaximumFractionDigits() + ", expect " +
1301                  DIGITS[4*i] + "/" +
1302                  DIGITS[4*i+1] + ";" +
1303                  DIGITS[4*i+2] + "/" +
1304                  DIGITS[4*i+3]);
1305        }
1306    }
1307
1308
1309    // Test the constructor for default locale. We have to
1310    // manually set the default locale, as there is no
1311    // guarantee that the default locale has the same
1312    // scientific format.
1313    Locale def = Locale::getDefault();
1314    Locale::setDefault(Locale::getUS(), status);
1315    expect2(NumberFormat::createScientificInstance(status),
1316           12345.678901,
1317           "1.2345678901E4", status);
1318    Locale::setDefault(def, status);
1319
1320    expect2(new DecimalFormat("#E0", US, status),
1321           12345.0,
1322           "1.2345E4", status);
1323    expect(new DecimalFormat("0E0", US, status),
1324           12345.0,
1325           "1E4", status);
1326    expect2(NumberFormat::createScientificInstance(Locale::getUS(), status),
1327           12345.678901,
1328           "1.2345678901E4", status);
1329    expect(new DecimalFormat("##0.###E0", US, status),
1330           12345.0,
1331           "12.34E3", status);
1332    expect(new DecimalFormat("##0.###E0", US, status),
1333           12345.00001,
1334           "12.35E3", status);
1335    expect2(new DecimalFormat("##0.####E0", US, status),
1336           (int32_t) 12345,
1337           "12.345E3", status);
1338    expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status),
1339           12345.678901,
1340           "1,2345678901E4", status);
1341    expect(new DecimalFormat("##0.####E0", US, status),
1342           789.12345e-9,
1343           "789.12E-9", status);
1344    expect2(new DecimalFormat("##0.####E0", US, status),
1345           780.e-9,
1346           "780E-9", status);
1347    expect(new DecimalFormat(".###E0", US, status),
1348           45678.0,
1349           ".457E5", status);
1350    expect2(new DecimalFormat(".###E0", US, status),
1351           (int32_t) 0,
1352           ".0E0", status);
1353    /*
1354    expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1355                                 new DecimalFormat("##E0", US),
1356                                 new DecimalFormat("####E0", US),
1357                                 new DecimalFormat("0E0", US),
1358                                 new DecimalFormat("00E0", US),
1359                                 new DecimalFormat("000E0", US),
1360                               },
1361           new Long(45678000),
1362           new String[] { "4.5678E7",
1363                          "45.678E6",
1364                          "4567.8E4",
1365                          "5E7",
1366                          "46E6",
1367                          "457E5",
1368                        }
1369           );
1370    !
1371    ! Unroll this test into individual tests below...
1372    !
1373    */
1374    expect2(new DecimalFormat("#E0", US, status),
1375           (int32_t) 45678000, "4.5678E7", status);
1376    expect2(new DecimalFormat("##E0", US, status),
1377           (int32_t) 45678000, "45.678E6", status);
1378    expect2(new DecimalFormat("####E0", US, status),
1379           (int32_t) 45678000, "4567.8E4", status);
1380    expect(new DecimalFormat("0E0", US, status),
1381           (int32_t) 45678000, "5E7", status);
1382    expect(new DecimalFormat("00E0", US, status),
1383           (int32_t) 45678000, "46E6", status);
1384    expect(new DecimalFormat("000E0", US, status),
1385           (int32_t) 45678000, "457E5", status);
1386    /*
1387    expect(new DecimalFormat("###E0", US, status),
1388           new Object[] { new Double(0.0000123), "12.3E-6",
1389                          new Double(0.000123), "123E-6",
1390                          new Double(0.00123), "1.23E-3",
1391                          new Double(0.0123), "12.3E-3",
1392                          new Double(0.123), "123E-3",
1393                          new Double(1.23), "1.23E0",
1394                          new Double(12.3), "12.3E0",
1395                          new Double(123), "123E0",
1396                          new Double(1230), "1.23E3",
1397                         });
1398    !
1399    ! Unroll this test into individual tests below...
1400    !
1401    */
1402    expect2(new DecimalFormat("###E0", US, status),
1403           0.0000123, "12.3E-6", status);
1404    expect2(new DecimalFormat("###E0", US, status),
1405           0.000123, "123E-6", status);
1406    expect2(new DecimalFormat("###E0", US, status),
1407           0.00123, "1.23E-3", status);
1408    expect2(new DecimalFormat("###E0", US, status),
1409           0.0123, "12.3E-3", status);
1410    expect2(new DecimalFormat("###E0", US, status),
1411           0.123, "123E-3", status);
1412    expect2(new DecimalFormat("###E0", US, status),
1413           1.23, "1.23E0", status);
1414    expect2(new DecimalFormat("###E0", US, status),
1415           12.3, "12.3E0", status);
1416    expect2(new DecimalFormat("###E0", US, status),
1417           123.0, "123E0", status);
1418    expect2(new DecimalFormat("###E0", US, status),
1419           1230.0, "1.23E3", status);
1420    /*
1421    expect(new DecimalFormat("0.#E+00", US, status),
1422           new Object[] { new Double(0.00012), "1.2E-04",
1423                          new Long(12000),     "1.2E+04",
1424                         });
1425    !
1426    ! Unroll this test into individual tests below...
1427    !
1428    */
1429    expect2(new DecimalFormat("0.#E+00", US, status),
1430           0.00012, "1.2E-04", status);
1431    expect2(new DecimalFormat("0.#E+00", US, status),
1432           (int32_t) 12000, "1.2E+04", status);
1433}
1434
1435/**
1436 * Upgrade to alphaWorks
1437 */
1438void NumberFormatTest::TestPad(void) {
1439    UErrorCode status = U_ZERO_ERROR;
1440    DecimalFormatSymbols US(Locale::getUS(), status);
1441    CHECK(status, "DecimalFormatSymbols constructor");
1442
1443    expect2(new DecimalFormat("*^##.##", US, status),
1444           int32_t(0), "^^^^0", status);
1445    expect2(new DecimalFormat("*^##.##", US, status),
1446           -1.3, "^-1.3", status);
1447    expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
1448           int32_t(0), "0.0E0______ g-m/s^2", status);
1449    expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
1450           1.0/3, "333.333E-3_ g-m/s^2", status);
1451    expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
1452           int32_t(0), "0.0______ g-m/s^2", status);
1453    expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
1454           1.0/3, "0.33333__ g-m/s^2", status);
1455
1456    // Test padding before a sign
1457    const char *formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1458    expect2(new DecimalFormat(formatStr, US, status),
1459           int32_t(-10),  "xxxxxxxxxx(10.0)", status);
1460    expect2(new DecimalFormat(formatStr, US, status),
1461           int32_t(-1000),"xxxxxxx(1,000.0)", status);
1462    expect2(new DecimalFormat(formatStr, US, status),
1463           int32_t(-1000000),"xxx(1,000,000.0)", status);
1464    expect2(new DecimalFormat(formatStr, US, status),
1465           -100.37,       "xxxxxxxx(100.37)", status);
1466    expect2(new DecimalFormat(formatStr, US, status),
1467           -10456.37,     "xxxxx(10,456.37)", status);
1468    expect2(new DecimalFormat(formatStr, US, status),
1469           -1120456.37,   "xx(1,120,456.37)", status);
1470    expect2(new DecimalFormat(formatStr, US, status),
1471           -112045600.37, "(112,045,600.37)", status);
1472    expect2(new DecimalFormat(formatStr, US, status),
1473           -1252045600.37,"(1,252,045,600.37)", status);
1474
1475    expect2(new DecimalFormat(formatStr, US, status),
1476           int32_t(10),  "xxxxxxxxxxxx10.0", status);
1477    expect2(new DecimalFormat(formatStr, US, status),
1478           int32_t(1000),"xxxxxxxxx1,000.0", status);
1479    expect2(new DecimalFormat(formatStr, US, status),
1480           int32_t(1000000),"xxxxx1,000,000.0", status);
1481    expect2(new DecimalFormat(formatStr, US, status),
1482           100.37,       "xxxxxxxxxx100.37", status);
1483    expect2(new DecimalFormat(formatStr, US, status),
1484           10456.37,     "xxxxxxx10,456.37", status);
1485    expect2(new DecimalFormat(formatStr, US, status),
1486           1120456.37,   "xxxx1,120,456.37", status);
1487    expect2(new DecimalFormat(formatStr, US, status),
1488           112045600.37, "xx112,045,600.37", status);
1489    expect2(new DecimalFormat(formatStr, US, status),
1490           10252045600.37,"10,252,045,600.37", status);
1491
1492
1493    // Test padding between a sign and a number
1494    const char *formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1495    expect2(new DecimalFormat(formatStr2, US, status),
1496           int32_t(-10),  "(10.0xxxxxxxxxx)", status);
1497    expect2(new DecimalFormat(formatStr2, US, status),
1498           int32_t(-1000),"(1,000.0xxxxxxx)", status);
1499    expect2(new DecimalFormat(formatStr2, US, status),
1500           int32_t(-1000000),"(1,000,000.0xxx)", status);
1501    expect2(new DecimalFormat(formatStr2, US, status),
1502           -100.37,       "(100.37xxxxxxxx)", status);
1503    expect2(new DecimalFormat(formatStr2, US, status),
1504           -10456.37,     "(10,456.37xxxxx)", status);
1505    expect2(new DecimalFormat(formatStr2, US, status),
1506           -1120456.37,   "(1,120,456.37xx)", status);
1507    expect2(new DecimalFormat(formatStr2, US, status),
1508           -112045600.37, "(112,045,600.37)", status);
1509    expect2(new DecimalFormat(formatStr2, US, status),
1510           -1252045600.37,"(1,252,045,600.37)", status);
1511
1512    expect2(new DecimalFormat(formatStr2, US, status),
1513           int32_t(10),  "10.0xxxxxxxxxxxx", status);
1514    expect2(new DecimalFormat(formatStr2, US, status),
1515           int32_t(1000),"1,000.0xxxxxxxxx", status);
1516    expect2(new DecimalFormat(formatStr2, US, status),
1517           int32_t(1000000),"1,000,000.0xxxxx", status);
1518    expect2(new DecimalFormat(formatStr2, US, status),
1519           100.37,       "100.37xxxxxxxxxx", status);
1520    expect2(new DecimalFormat(formatStr2, US, status),
1521           10456.37,     "10,456.37xxxxxxx", status);
1522    expect2(new DecimalFormat(formatStr2, US, status),
1523           1120456.37,   "1,120,456.37xxxx", status);
1524    expect2(new DecimalFormat(formatStr2, US, status),
1525           112045600.37, "112,045,600.37xx", status);
1526    expect2(new DecimalFormat(formatStr2, US, status),
1527           10252045600.37,"10,252,045,600.37", status);
1528
1529    //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1530    DecimalFormat fmt("#", US, status);
1531    CHECK(status, "DecimalFormat constructor");
1532    UnicodeString padString("P");
1533    fmt.setPadCharacter(padString);
1534    expectPad(fmt, "*P##.##", DecimalFormat::kPadBeforePrefix, 5, padString);
1535    fmt.setPadCharacter((UnicodeString)"^");
1536    expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, (UnicodeString)"^");
1537    //commented untill implementation is complete
1538  /*  fmt.setPadCharacter((UnicodeString)"^^^");
1539    expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
1540    padString.remove();
1541    padString.append((UChar)0x0061);
1542    padString.append((UChar)0x0302);
1543    fmt.setPadCharacter(padString);
1544    UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
1545    UnicodeString pattern(patternChars);
1546    expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
1547 */
1548
1549}
1550
1551/**
1552 * Upgrade to alphaWorks
1553 */
1554void NumberFormatTest::TestPatterns2(void) {
1555    UErrorCode status = U_ZERO_ERROR;
1556    DecimalFormatSymbols US(Locale::getUS(), status);
1557    CHECK(status, "DecimalFormatSymbols constructor");
1558
1559    DecimalFormat fmt("#", US, status);
1560    CHECK(status, "DecimalFormat constructor");
1561
1562    UChar hat = 0x005E; /*^*/
1563
1564    expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat);
1565    expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat);
1566    expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat);
1567    expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat);
1568    expectPad(fmt, "$*^$#", ILLEGAL);
1569    expectPad(fmt, "#$*^$", ILLEGAL);
1570    expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix,
1571              12, (UChar)0x0078 /*x*/);
1572    expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix,
1573              3, (UChar)0x0078 /*x*/);
1574    expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix,
1575              10, (UChar)0x0061 /*a*/);
1576
1577    fmt.applyPattern("AA#,##0.00ZZ", status);
1578    CHECK(status, "applyPattern");
1579    fmt.setPadCharacter(hat);
1580
1581    fmt.setFormatWidth(10);
1582
1583    fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
1584    expectPat(fmt, "*^AA#,##0.00ZZ");
1585
1586    fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
1587    expectPat(fmt, "AA#,##0.00*^ZZ");
1588
1589    fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
1590    expectPat(fmt, "AA#,##0.00ZZ*^");
1591
1592    //            12  3456789012
1593    UnicodeString exp("AA*^#,##0.00ZZ", "");
1594    fmt.setFormatWidth(12);
1595    fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
1596    expectPat(fmt, exp);
1597
1598    fmt.setFormatWidth(13);
1599    //              12  34567890123
1600    expectPat(fmt, "AA*^##,##0.00ZZ");
1601
1602    fmt.setFormatWidth(14);
1603    //              12  345678901234
1604    expectPat(fmt, "AA*^###,##0.00ZZ");
1605
1606    fmt.setFormatWidth(15);
1607    //              12  3456789012345
1608    expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
1609
1610    fmt.setFormatWidth(16);
1611    //              12  34567890123456
1612    expectPat(fmt, "AA*^#,###,##0.00ZZ");
1613}
1614
1615void NumberFormatTest::TestSurrogateSupport(void) {
1616    UErrorCode status = U_ZERO_ERROR;
1617    DecimalFormatSymbols custom(Locale::getUS(), status);
1618    CHECK(status, "DecimalFormatSymbols constructor");
1619
1620    custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal");
1621    custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus");
1622    custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus ");
1623    custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent");
1624
1625    UnicodeString patternStr("*\\U00010000##.##", "");
1626    patternStr = patternStr.unescape();
1627    UnicodeString expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1628    expStr = expStr.unescape();
1629    expect2(new DecimalFormat(patternStr, custom, status),
1630           int32_t(0), expStr, status);
1631
1632    status = U_ZERO_ERROR;
1633    expect2(new DecimalFormat("*^##.##", custom, status),
1634           int32_t(0), "^^^^0", status);
1635    status = U_ZERO_ERROR;
1636    expect2(new DecimalFormat("##.##", custom, status),
1637           -1.3, " minus 1decimal3", status);
1638    status = U_ZERO_ERROR;
1639    expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
1640           int32_t(0), "0decimal0exponent0 g-m/s^2", status);
1641    status = U_ZERO_ERROR;
1642    expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
1643           1.0/3, "333decimal333exponent minus 3 g-m/s^2", status);
1644    status = U_ZERO_ERROR;
1645    expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
1646           int32_t(0), "0decimal0 g-m/s^2", status);
1647    status = U_ZERO_ERROR;
1648    expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
1649           1.0/3, "0decimal33333 g-m/s^2", status);
1650
1651    UnicodeString zero((UChar32)0x10000);
1652    UnicodeString one((UChar32)0x10001);
1653    UnicodeString two((UChar32)0x10002);
1654    UnicodeString five((UChar32)0x10005);
1655    custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
1656    custom.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, one);
1657    custom.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, two);
1658    custom.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, five);
1659    expStr = UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1660    expStr = expStr.unescape();
1661    status = U_ZERO_ERROR;
1662    expect2(new DecimalFormat("##0.000", custom, status),
1663           1.25, expStr, status);
1664
1665    custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30);
1666    custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money");
1667    custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator");
1668    patternStr = UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
1669    patternStr = patternStr.unescape();
1670    expStr = UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1671    status = U_ZERO_ERROR;
1672    expect2(new DecimalFormat(patternStr, custom, status),
1673           int32_t(-20), expStr, status);
1674
1675    custom.setSymbol(DecimalFormatSymbols::kPercentSymbol, "percent");
1676    patternStr = "'You''ve lost ' -0.00 %' of your money today'";
1677    patternStr = patternStr.unescape();
1678    expStr = UnicodeString(" minus You've lost   minus 2000decimal00 percent of your money today", "");
1679    status = U_ZERO_ERROR;
1680    expect2(new DecimalFormat(patternStr, custom, status),
1681           int32_t(-20), expStr, status);
1682}
1683
1684void NumberFormatTest::TestCurrencyPatterns(void) {
1685    int32_t i, locCount;
1686    const Locale* locs = NumberFormat::getAvailableLocales(locCount);
1687    for (i=0; i<locCount; ++i) {
1688        UErrorCode ec = U_ZERO_ERROR;
1689        NumberFormat* nf = NumberFormat::createCurrencyInstance(locs[i], ec);
1690        if (U_FAILURE(ec)) {
1691            errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec));
1692        } else {
1693            // Make sure currency formats do not have a variable number
1694            // of fraction digits
1695            int32_t min = nf->getMinimumFractionDigits();
1696            int32_t max = nf->getMaximumFractionDigits();
1697            if (min != max) {
1698                UnicodeString a, b;
1699                nf->format(1.0, a);
1700                nf->format(1.125, b);
1701                errln((UnicodeString)"FAIL: " + locs[i].getName() +
1702                      " min fraction digits != max fraction digits; "
1703                      "x 1.0 => " + escape(a) +
1704                      "; x 1.125 => " + escape(b));
1705            }
1706
1707            // Make sure EURO currency formats have exactly 2 fraction digits
1708            DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
1709            if (df != NULL) {
1710                if (u_strcmp(EUR, df->getCurrency()) == 0) {
1711                    if (min != 2 || max != 2) {
1712                        UnicodeString a;
1713                        nf->format(1.0, a);
1714                        errln((UnicodeString)"FAIL: " + locs[i].getName() +
1715                              " is a EURO format but it does not have 2 fraction digits; "
1716                              "x 1.0 => " +
1717                              escape(a));
1718                    }
1719                }
1720            }
1721        }
1722        delete nf;
1723    }
1724}
1725
1726void NumberFormatTest::TestRegCurrency(void) {
1727#if !UCONFIG_NO_SERVICE
1728    UErrorCode status = U_ZERO_ERROR;
1729    UChar USD[4];
1730    ucurr_forLocale("en_US", USD, 4, &status);
1731    UChar YEN[4];
1732    ucurr_forLocale("ja_JP", YEN, 4, &status);
1733    UChar TMP[4];
1734    static const UChar QQQ[] = {0x51, 0x51, 0x51, 0};
1735    if(U_FAILURE(status)) {
1736        errcheckln(status, "Unable to get currency for locale, error %s", u_errorName(status));
1737        return;
1738    }
1739
1740    UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status);
1741    UCurrRegistryKey enUSEUROkey = ucurr_register(QQQ, "en_US_EURO", &status);
1742
1743    ucurr_forLocale("en_US", TMP, 4, &status);
1744    if (u_strcmp(YEN, TMP) != 0) {
1745        errln("FAIL: didn't return YEN registered for en_US");
1746    }
1747
1748    ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1749    if (u_strcmp(QQQ, TMP) != 0) {
1750        errln("FAIL: didn't return QQQ for en_US_EURO");
1751    }
1752
1753    int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status);
1754    if (fallbackLen) {
1755        errln("FAIL: tried to fallback en_XX_BAR");
1756    }
1757    status = U_ZERO_ERROR; // reset
1758
1759    if (!ucurr_unregister(enkey, &status)) {
1760        errln("FAIL: couldn't unregister enkey");
1761    }
1762
1763    ucurr_forLocale("en_US", TMP, 4, &status);
1764    if (u_strcmp(USD, TMP) != 0) {
1765        errln("FAIL: didn't return USD for en_US after unregister of en_US");
1766    }
1767    status = U_ZERO_ERROR; // reset
1768
1769    ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1770    if (u_strcmp(QQQ, TMP) != 0) {
1771        errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US");
1772    }
1773
1774    ucurr_forLocale("en_US_BLAH", TMP, 4, &status);
1775    if (u_strcmp(USD, TMP) != 0) {
1776        errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1777    }
1778    status = U_ZERO_ERROR; // reset
1779
1780    if (!ucurr_unregister(enUSEUROkey, &status)) {
1781        errln("FAIL: couldn't unregister enUSEUROkey");
1782    }
1783
1784    ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1785    if (u_strcmp(EUR, TMP) != 0) {
1786        errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO");
1787    }
1788    status = U_ZERO_ERROR; // reset
1789#endif
1790}
1791
1792void NumberFormatTest::TestCurrencyNames(void) {
1793    // Do a basic check of getName()
1794    // USD { "US$", "US Dollar"            } // 04/04/1792-
1795    UErrorCode ec = U_ZERO_ERROR;
1796    static const UChar USD[] = {0x55, 0x53, 0x44, 0}; /*USD*/
1797    static const UChar USX[] = {0x55, 0x53, 0x58, 0}; /*USX*/
1798    static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
1799    static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
1800    UBool isChoiceFormat;
1801    int32_t len;
1802    const UBool possibleDataError = TRUE;
1803    // Warning: HARD-CODED LOCALE DATA in this test.  If it fails, CHECK
1804    // THE LOCALE DATA before diving into the code.
1805    assertEquals("USD.getName(SYMBOL_NAME)",
1806                 UnicodeString("$"),
1807                 UnicodeString(ucurr_getName(USD, "en",
1808                                             UCURR_SYMBOL_NAME,
1809                                             &isChoiceFormat, &len, &ec)),
1810                                             possibleDataError);
1811    assertEquals("USD.getName(LONG_NAME)",
1812                 UnicodeString("US Dollar"),
1813                 UnicodeString(ucurr_getName(USD, "en",
1814                                             UCURR_LONG_NAME,
1815                                             &isChoiceFormat, &len, &ec)),
1816                                             possibleDataError);
1817    assertEquals("CAD.getName(SYMBOL_NAME)",
1818                 UnicodeString("CA$"),
1819                 UnicodeString(ucurr_getName(CAD, "en",
1820                                             UCURR_SYMBOL_NAME,
1821                                             &isChoiceFormat, &len, &ec)),
1822                                             possibleDataError);
1823    assertEquals("CAD.getName(SYMBOL_NAME)",
1824                 UnicodeString("$"),
1825                 UnicodeString(ucurr_getName(CAD, "en_CA",
1826                                             UCURR_SYMBOL_NAME,
1827                                             &isChoiceFormat, &len, &ec)),
1828                                             possibleDataError);
1829    assertEquals("USD.getName(SYMBOL_NAME) in en_AU",
1830                 UnicodeString("US$"),
1831                 UnicodeString(ucurr_getName(USD, "en_AU",
1832                                             UCURR_SYMBOL_NAME,
1833                                             &isChoiceFormat, &len, &ec)),
1834                                             possibleDataError);
1835    assertEquals("CAD.getName(SYMBOL_NAME)",
1836                 UnicodeString("CA$"),
1837                 UnicodeString(ucurr_getName(CAD, "en_AU",
1838                                             UCURR_SYMBOL_NAME,
1839                                             &isChoiceFormat, &len, &ec)),
1840                                             possibleDataError);
1841    assertEquals("USX.getName(LONG_NAME)",
1842                 UnicodeString("USX"),
1843                 UnicodeString(ucurr_getName(USX, "en_US",
1844                                             UCURR_LONG_NAME,
1845                                             &isChoiceFormat, &len, &ec)),
1846                                             possibleDataError);
1847    assertSuccess("ucurr_getName", ec);
1848
1849    ec = U_ZERO_ERROR;
1850
1851    // Test that a default or fallback warning is being returned. JB 4239.
1852    ucurr_getName(CAD, "es_ES", UCURR_LONG_NAME, &isChoiceFormat,
1853                            &len, &ec);
1854    assertTrue("ucurr_getName (es_ES fallback)",
1855                    U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
1856
1857    ucurr_getName(CAD, "zh_TW", UCURR_LONG_NAME, &isChoiceFormat,
1858                            &len, &ec);
1859    assertTrue("ucurr_getName (zh_TW fallback)",
1860                    U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
1861
1862    ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat,
1863                            &len, &ec);
1864    assertTrue("ucurr_getName (en_US default)",
1865                    U_USING_DEFAULT_WARNING == ec || U_USING_FALLBACK_WARNING == ec, TRUE);
1866
1867    ucurr_getName(CAD, "ti", UCURR_LONG_NAME, &isChoiceFormat,
1868                            &len, &ec);
1869    assertTrue("ucurr_getName (ti default)",
1870                    U_USING_DEFAULT_WARNING == ec, TRUE);
1871
1872    // Test that a default warning is being returned when falling back to root. JB 4536.
1873    ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat,
1874                            &len, &ec);
1875    assertTrue("ucurr_getName (cy default to root)",
1876                    U_USING_DEFAULT_WARNING == ec, TRUE);
1877
1878    // TODO add more tests later
1879}
1880
1881void NumberFormatTest::TestCurrencyUnit(void){
1882    UErrorCode ec = U_ZERO_ERROR;
1883    static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
1884    CurrencyUnit cu(USD, ec);
1885    assertSuccess("CurrencyUnit", ec);
1886
1887    const UChar * r = cu.getISOCurrency(); // who is the buffer owner ?
1888    assertEquals("getISOCurrency()", USD, r);
1889
1890    CurrencyUnit cu2(cu);
1891    if (!(cu2 == cu)){
1892        errln("CurrencyUnit copy constructed object should be same");
1893    }
1894
1895    CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone();
1896    if (!(*cu3 == cu)){
1897        errln("CurrencyUnit cloned object should be same");
1898    }
1899    delete cu3;
1900}
1901
1902void NumberFormatTest::TestCurrencyAmount(void){
1903    UErrorCode ec = U_ZERO_ERROR;
1904    static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
1905    CurrencyAmount ca(9, USD, ec);
1906    assertSuccess("CurrencyAmount", ec);
1907
1908    CurrencyAmount ca2(ca);
1909    if (!(ca2 == ca)){
1910        errln("CurrencyAmount copy constructed object should be same");
1911    }
1912
1913    ca2=ca;
1914    if (!(ca2 == ca)){
1915        errln("CurrencyAmount assigned object should be same");
1916    }
1917
1918    CurrencyAmount *ca3 = (CurrencyAmount *)ca.clone();
1919    if (!(*ca3 == ca)){
1920        errln("CurrencyAmount cloned object should be same");
1921    }
1922    delete ca3;
1923}
1924
1925void NumberFormatTest::TestSymbolsWithBadLocale(void) {
1926    Locale locDefault;
1927    static const char *badLocales[] = {
1928        // length < ULOC_FULLNAME_CAPACITY
1929        "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME",
1930
1931        // length > ULOC_FULLNAME_CAPACITY
1932        "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME"
1933    }; // expect U_USING_DEFAULT_WARNING for both
1934
1935    unsigned int i;
1936    for (i = 0; i < sizeof(badLocales) / sizeof(char*); i++) {
1937        const char *localeName = badLocales[i];
1938        Locale locBad(localeName);
1939        UErrorCode status = U_ZERO_ERROR;
1940        UnicodeString intlCurrencySymbol((UChar)0xa4);
1941
1942        intlCurrencySymbol.append((UChar)0xa4);
1943
1944        logln("Current locale is %s", Locale::getDefault().getName());
1945        Locale::setDefault(locBad, status);
1946        logln("Current locale is %s", Locale::getDefault().getName());
1947        DecimalFormatSymbols mySymbols(status);
1948        if (status != U_USING_DEFAULT_WARNING) {
1949            errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING.");
1950        }
1951        if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) {
1952            errln("DecimalFormatSymbols does not have the right locale.", locBad.getName());
1953        }
1954        int symbolEnum = (int)DecimalFormatSymbols::kDecimalSeparatorSymbol;
1955        for (; symbolEnum < (int)DecimalFormatSymbols::kFormatSymbolCount; symbolEnum++) {
1956            UnicodeString symbolString = mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum);
1957            logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum + UnicodeString("] = ") + prettify(symbolString));
1958            if (symbolString.length() == 0
1959                && symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
1960                && symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol)
1961            {
1962                errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
1963            }
1964        }
1965
1966        status = U_ZERO_ERROR;
1967        Locale::setDefault(locDefault, status);
1968        logln("Current locale is %s", Locale::getDefault().getName());
1969    }
1970}
1971
1972/**
1973 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
1974 * behave the same, except for memory ownership semantics. (No
1975 * version of this test on Java, since Java has only one method.)
1976 */
1977void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
1978    UErrorCode ec = U_ZERO_ERROR;
1979    DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec);
1980    if (U_FAILURE(ec)) {
1981        errcheckln(ec, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec));
1982        delete sym;
1983        return;
1984    }
1985    UnicodeString pat(" #,##0.00");
1986    pat.insert(0, (UChar)0x00A4);
1987    DecimalFormat fmt(pat, sym, ec);
1988    if (U_FAILURE(ec)) {
1989        errln("Fail: DecimalFormat constructor");
1990        return;
1991    }
1992
1993    UnicodeString str;
1994    fmt.format(2350.75, str);
1995    if (str == "$ 2,350.75") {
1996        logln(str);
1997    } else {
1998        dataerrln("Fail: " + str + ", expected $ 2,350.75");
1999    }
2000
2001    sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2002    if (U_FAILURE(ec)) {
2003        errln("Fail: DecimalFormatSymbols constructor");
2004        delete sym;
2005        return;
2006    }
2007    sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2008    fmt.adoptDecimalFormatSymbols(sym);
2009
2010    str.truncate(0);
2011    fmt.format(2350.75, str);
2012    if (str == "Q 2,350.75") {
2013        logln(str);
2014    } else {
2015        dataerrln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
2016    }
2017
2018    sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2019    if (U_FAILURE(ec)) {
2020        errln("Fail: DecimalFormatSymbols constructor");
2021        delete sym;
2022        return;
2023    }
2024    DecimalFormat fmt2(pat, sym, ec);
2025    if (U_FAILURE(ec)) {
2026        errln("Fail: DecimalFormat constructor");
2027        return;
2028    }
2029
2030    DecimalFormatSymbols sym2(Locale::getUS(), ec);
2031    if (U_FAILURE(ec)) {
2032        errln("Fail: DecimalFormatSymbols constructor");
2033        return;
2034    }
2035    sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2036    fmt2.setDecimalFormatSymbols(sym2);
2037
2038    str.truncate(0);
2039    fmt2.format(2350.75, str);
2040    if (str == "Q 2,350.75") {
2041        logln(str);
2042    } else {
2043        dataerrln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
2044    }
2045}
2046
2047void NumberFormatTest::TestPerMill() {
2048    UErrorCode ec = U_ZERO_ERROR;
2049    UnicodeString str;
2050    DecimalFormat fmt(ctou("###.###\\u2030"), ec);
2051    if (!assertSuccess("DecimalFormat ct", ec)) return;
2052    assertEquals("0.4857 x ###.###\\u2030",
2053                 ctou("485.7\\u2030"), fmt.format(0.4857, str));
2054
2055    DecimalFormatSymbols sym(Locale::getUS(), ec);
2056    sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
2057    DecimalFormat fmt2("", sym, ec);
2058    fmt2.applyLocalizedPattern("###.###m", ec);
2059    if (!assertSuccess("setup", ec)) return;
2060    str.truncate(0);
2061    assertEquals("0.4857 x ###.###m",
2062                 "485.7m", fmt2.format(0.4857, str));
2063}
2064
2065/**
2066 * Generic test for patterns that should be legal/illegal.
2067 */
2068void NumberFormatTest::TestIllegalPatterns() {
2069    // Test cases:
2070    // Prefix with "-:" for illegal patterns
2071    // Prefix with "+:" for legal patterns
2072    const char* DATA[] = {
2073        // Unquoted special characters in the suffix are illegal
2074        "-:000.000|###",
2075        "+:000.000'|###'",
2076        0
2077    };
2078    for (int32_t i=0; DATA[i]; ++i) {
2079        const char* pat=DATA[i];
2080        UBool valid = (*pat) == '+';
2081        pat += 2;
2082        UErrorCode ec = U_ZERO_ERROR;
2083        DecimalFormat fmt(pat, ec); // locale doesn't matter here
2084        if (U_SUCCESS(ec) == valid) {
2085            logln("Ok: pattern \"%s\": %s",
2086                  pat, u_errorName(ec));
2087        } else {
2088            errcheckln(ec, "FAIL: pattern \"%s\" should have %s; got %s",
2089                  pat, (valid?"succeeded":"failed"),
2090                  u_errorName(ec));
2091        }
2092    }
2093}
2094
2095//----------------------------------------------------------------------
2096
2097static const char* KEYWORDS[] = {
2098    /*0*/ "ref=", // <reference pattern to parse numbers>
2099    /*1*/ "loc=", // <locale for formats>
2100    /*2*/ "f:",   // <pattern or '-'> <number> <exp. string>
2101    /*3*/ "fp:",  // <pattern or '-'> <number> <exp. string> <exp. number>
2102    /*4*/ "rt:",  // <pattern or '-'> <(exp.) number> <(exp.) string>
2103    /*5*/ "p:",   // <pattern or '-'> <string> <exp. number>
2104    /*6*/ "perr:", // <pattern or '-'> <invalid string>
2105    /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
2106    /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2107    0
2108};
2109
2110/**
2111 * Return an integer representing the next token from this
2112 * iterator.  The integer will be an index into the given list, or
2113 * -1 if there are no more tokens, or -2 if the token is not on
2114 * the list.
2115 */
2116static int32_t keywordIndex(const UnicodeString& tok) {
2117    for (int32_t i=0; KEYWORDS[i]!=0; ++i) {
2118        if (tok==KEYWORDS[i]) {
2119            return i;
2120        }
2121    }
2122    return -1;
2123}
2124
2125/**
2126 * Parse a CurrencyAmount using the given NumberFormat, with
2127 * the 'delim' character separating the number and the currency.
2128 */
2129static void parseCurrencyAmount(const UnicodeString& str,
2130                                const NumberFormat& fmt,
2131                                UChar delim,
2132                                Formattable& result,
2133                                UErrorCode& ec) {
2134    UnicodeString num, cur;
2135    int32_t i = str.indexOf(delim);
2136    str.extractBetween(0, i, num);
2137    str.extractBetween(i+1, INT32_MAX, cur);
2138    Formattable n;
2139    fmt.parse(num, n, ec);
2140    result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
2141}
2142
2143void NumberFormatTest::TestCases() {
2144    UErrorCode ec = U_ZERO_ERROR;
2145    TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
2146    if (U_FAILURE(ec)) {
2147        dataerrln("Couldn't open NumberFormatTestCases.txt");
2148        return;
2149    }
2150    TokenIterator tokens(&reader);
2151
2152    Locale loc("en", "US", "");
2153    DecimalFormat *ref = 0, *fmt = 0;
2154    MeasureFormat *mfmt = 0;
2155    UnicodeString pat, tok, mloc, str, out, where, currAmt;
2156    Formattable n;
2157
2158    for (;;) {
2159        ec = U_ZERO_ERROR;
2160        if (!tokens.next(tok, ec)) {
2161            break;
2162        }
2163        where = UnicodeString("(") + tokens.getLineNumber() + ") ";
2164        int32_t cmd = keywordIndex(tok);
2165        switch (cmd) {
2166        case 0:
2167            // ref= <reference pattern>
2168            if (!tokens.next(tok, ec)) goto error;
2169            delete ref;
2170            ref = new DecimalFormat(tok,
2171                      new DecimalFormatSymbols(Locale::getUS(), ec), ec);
2172            if (U_FAILURE(ec)) {
2173                dataerrln("Error constructing DecimalFormat");
2174                goto error;
2175            }
2176            break;
2177        case 1:
2178            // loc= <locale>
2179            if (!tokens.next(tok, ec)) goto error;
2180            loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data());
2181            break;
2182        case 2: // f:
2183        case 3: // fp:
2184        case 4: // rt:
2185        case 5: // p:
2186            if (!tokens.next(tok, ec)) goto error;
2187            if (tok != "-") {
2188                pat = tok;
2189                delete fmt;
2190                fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
2191                if (U_FAILURE(ec)) {
2192                    errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
2193                    ec = U_ZERO_ERROR;
2194                    if (!tokens.next(tok, ec)) goto error;
2195                    if (!tokens.next(tok, ec)) goto error;
2196                    if (cmd == 3) {
2197                        if (!tokens.next(tok, ec)) goto error;
2198                    }
2199                    continue;
2200                }
2201            }
2202            if (cmd == 2 || cmd == 3 || cmd == 4) {
2203                // f: <pattern or '-'> <number> <exp. string>
2204                // fp: <pattern or '-'> <number> <exp. string> <exp. number>
2205                // rt: <pattern or '-'> <number> <string>
2206                UnicodeString num;
2207                if (!tokens.next(num, ec)) goto error;
2208                if (!tokens.next(str, ec)) goto error;
2209                ref->parse(num, n, ec);
2210                assertSuccess("parse", ec);
2211                assertEquals(where + "\"" + pat + "\".format(" + num + ")",
2212                             str, fmt->format(n, out.remove(), ec));
2213                assertSuccess("format", ec);
2214                if (cmd == 3) { // fp:
2215                    if (!tokens.next(num, ec)) goto error;
2216                    ref->parse(num, n, ec);
2217                    assertSuccess("parse", ec);
2218                }
2219                if (cmd != 2) { // != f:
2220                    Formattable m;
2221                    fmt->parse(str, m, ec);
2222                    assertSuccess("parse", ec);
2223                    assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2224                                 n, m);
2225                }
2226            }
2227            // p: <pattern or '-'> <string to parse> <exp. number>
2228            else {
2229                UnicodeString expstr;
2230                if (!tokens.next(str, ec)) goto error;
2231                if (!tokens.next(expstr, ec)) goto error;
2232                Formattable exp, n;
2233                ref->parse(expstr, exp, ec);
2234                assertSuccess("parse", ec);
2235                fmt->parse(str, n, ec);
2236                assertSuccess("parse", ec);
2237                assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2238                             exp, n);
2239            }
2240            break;
2241        case 8: // fpc:
2242            if (!tokens.next(tok, ec)) goto error;
2243            if (tok != "-") {
2244                mloc = tok;
2245                delete mfmt;
2246                mfmt = MeasureFormat::createCurrencyFormat(
2247                    Locale::createFromName(
2248                        CharString().appendInvariantChars(mloc, ec).data()), ec);
2249                if (U_FAILURE(ec)) {
2250                    errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
2251                    ec = U_ZERO_ERROR;
2252                    if (!tokens.next(tok, ec)) goto error;
2253                    if (!tokens.next(tok, ec)) goto error;
2254                    if (!tokens.next(tok, ec)) goto error;
2255                    continue;
2256                }
2257            }
2258            // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2259            if (!tokens.next(currAmt, ec)) goto error;
2260            if (!tokens.next(str, ec)) goto error;
2261            parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2262            if (assertSuccess("parseCurrencyAmount", ec)) {
2263                assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
2264                             str, mfmt->format(n, out.remove(), ec));
2265                assertSuccess("format", ec);
2266            }
2267            if (!tokens.next(currAmt, ec)) goto error;
2268            parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2269            if (assertSuccess("parseCurrencyAmount", ec)) {
2270                Formattable m;
2271
2272                mfmt->parseObject(str, m, ec);
2273                if (assertSuccess("parseCurrency", ec)) {
2274                    assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
2275                                 n, m);
2276                } else {
2277                    errln("FAIL: source " + str);
2278                }
2279            }
2280            break;
2281        case 6:
2282            // perr: <pattern or '-'> <invalid string>
2283            errln("FAIL: Under construction");
2284            goto done;
2285        case 7: {
2286            // pat: <pattern> <exp. toPattern, or '-' or 'err'>
2287            UnicodeString testpat;
2288            UnicodeString exppat;
2289            if (!tokens.next(testpat, ec)) goto error;
2290            if (!tokens.next(exppat, ec)) goto error;
2291            UBool err = exppat == "err";
2292            UBool existingPat = FALSE;
2293            if (testpat == "-") {
2294                if (err) {
2295                    errln("FAIL: " + where + "Invalid command \"pat: - err\"");
2296                    continue;
2297                }
2298                existingPat = TRUE;
2299                testpat = pat;
2300            }
2301            if (exppat == "-") exppat = testpat;
2302            DecimalFormat* f = 0;
2303            UErrorCode ec2 = U_ZERO_ERROR;
2304            if (existingPat) {
2305                f = fmt;
2306            } else {
2307                f = new DecimalFormat(testpat, ec2);
2308            }
2309            if (U_SUCCESS(ec2)) {
2310                if (err) {
2311                    errln("FAIL: " + where + "Invalid pattern \"" + testpat +
2312                          "\" was accepted");
2313                } else {
2314                    UnicodeString pat2;
2315                    assertEquals(where + "\"" + testpat + "\".toPattern()",
2316                                 exppat, f->toPattern(pat2));
2317                }
2318            } else {
2319                if (err) {
2320                    logln("Ok: " + where + "Invalid pattern \"" + testpat +
2321                          "\" failed: " + u_errorName(ec2));
2322                } else {
2323                    errln("FAIL: " + where + "Valid pattern \"" + testpat +
2324                          "\" failed: " + u_errorName(ec2));
2325                }
2326            }
2327            if (!existingPat) delete f;
2328            } break;
2329        case -1:
2330            errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
2331            goto done;
2332        }
2333    }
2334    goto done;
2335
2336 error:
2337    if (U_SUCCESS(ec)) {
2338        errln("FAIL: Unexpected EOF");
2339    } else {
2340        errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec));
2341    }
2342
2343 done:
2344    delete mfmt;
2345    delete fmt;
2346    delete ref;
2347}
2348
2349
2350//----------------------------------------------------------------------
2351// Support methods
2352//----------------------------------------------------------------------
2353
2354UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) {
2355    if (a.getType() == b.getType()) {
2356        return a == b;
2357    }
2358
2359    if (a.getType() == Formattable::kLong) {
2360        if (b.getType() == Formattable::kInt64) {
2361            return a.getLong() == b.getLong();
2362        } else if (b.getType() == Formattable::kDouble) {
2363            return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long
2364        }
2365    } else if (a.getType() == Formattable::kDouble) {
2366        if (b.getType() == Formattable::kLong) {
2367            return a.getDouble() == (double) b.getLong();
2368        } else if (b.getType() == Formattable::kInt64) {
2369            return a.getDouble() == (double)b.getInt64();
2370        }
2371    } else if (a.getType() == Formattable::kInt64) {
2372        if (b.getType() == Formattable::kLong) {
2373                return a.getInt64() == (int64_t)b.getLong();
2374        } else if (b.getType() == Formattable::kDouble) {
2375            return a.getInt64() == (int64_t)b.getDouble();
2376        }
2377    }
2378    return FALSE;
2379}
2380
2381void NumberFormatTest::expect3(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2382    // Don't round-trip format test, since we explicitly do it
2383    expect_rbnf(fmt, n, str, FALSE);
2384    expect_rbnf(fmt, str, n);
2385}
2386
2387void NumberFormatTest::expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2388    // Don't round-trip format test, since we explicitly do it
2389    expect(fmt, n, str, FALSE);
2390    expect(fmt, str, n);
2391}
2392
2393void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
2394                               const UnicodeString& exp,
2395                               UErrorCode status) {
2396    if (fmt == NULL || U_FAILURE(status)) {
2397        dataerrln("FAIL: NumberFormat constructor");
2398    } else {
2399        expect2(*fmt, n, exp);
2400    }
2401    delete fmt;
2402}
2403
2404void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2405    UErrorCode status = U_ZERO_ERROR;
2406    Formattable num;
2407    fmt.parse(str, num, status);
2408    if (U_FAILURE(status)) {
2409        dataerrln(UnicodeString("FAIL: Parse failed for \"") + str + "\" - " + u_errorName(status));
2410        return;
2411    }
2412    UnicodeString pat;
2413    ((DecimalFormat*) &fmt)->toPattern(pat);
2414    if (equalValue(num, n)) {
2415        logln(UnicodeString("Ok   \"") + str + "\" x " +
2416              pat + " = " +
2417              toString(num));
2418    } else {
2419        dataerrln(UnicodeString("FAIL \"") + str + "\" x " +
2420              pat + " = " +
2421              toString(num) + ", expected " + toString(n));
2422    }
2423}
2424
2425void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2426    UErrorCode status = U_ZERO_ERROR;
2427    Formattable num;
2428    fmt.parse(str, num, status);
2429    if (U_FAILURE(status)) {
2430        errln(UnicodeString("FAIL: Parse failed for \"") + str + "\"");
2431        return;
2432    }
2433    if (equalValue(num, n)) {
2434        logln(UnicodeString("Ok   \"") + str + " = " +
2435              toString(num));
2436    } else {
2437        errln(UnicodeString("FAIL \"") + str + " = " +
2438              toString(num) + ", expected " + toString(n));
2439    }
2440}
2441
2442void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const Formattable& n,
2443                              const UnicodeString& exp, UBool rt) {
2444    UnicodeString saw;
2445    FieldPosition pos;
2446    UErrorCode status = U_ZERO_ERROR;
2447    fmt.format(n, saw, pos, status);
2448    CHECK(status, "NumberFormat::format");
2449    if (saw == exp) {
2450        logln(UnicodeString("Ok   ") + toString(n) +
2451              " = \"" +
2452              escape(saw) + "\"");
2453        // We should be able to round-trip the formatted string =>
2454        // number => string (but not the other way around: number
2455        // => string => number2, might have number2 != number):
2456        if (rt) {
2457            Formattable n2;
2458            fmt.parse(exp, n2, status);
2459            if (U_FAILURE(status)) {
2460                errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\"");
2461                return;
2462            }
2463            UnicodeString saw2;
2464            fmt.format(n2, saw2, pos, status);
2465            CHECK(status, "NumberFormat::format");
2466            if (saw2 != exp) {
2467                errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2468                      " => \"" + saw2 + "\"");
2469            }
2470        }
2471    } else {
2472        errln(UnicodeString("FAIL ") + toString(n) +
2473              " = \"" +
2474              escape(saw) + "\", expected \"" + exp + "\"");
2475    }
2476}
2477
2478void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n,
2479                              const UnicodeString& exp, UBool rt) {
2480    UnicodeString saw;
2481    FieldPosition pos;
2482    UErrorCode status = U_ZERO_ERROR;
2483    fmt.format(n, saw, pos, status);
2484    CHECK(status, "NumberFormat::format");
2485    UnicodeString pat;
2486    ((DecimalFormat*) &fmt)->toPattern(pat);
2487    if (saw == exp) {
2488        logln(UnicodeString("Ok   ") + toString(n) + " x " +
2489              escape(pat) + " = \"" +
2490              escape(saw) + "\"");
2491        // We should be able to round-trip the formatted string =>
2492        // number => string (but not the other way around: number
2493        // => string => number2, might have number2 != number):
2494        if (rt) {
2495            Formattable n2;
2496            fmt.parse(exp, n2, status);
2497            if (U_FAILURE(status)) {
2498                errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\" - " + u_errorName(status));
2499                return;
2500            }
2501            UnicodeString saw2;
2502            fmt.format(n2, saw2, pos, status);
2503            CHECK(status, "NumberFormat::format");
2504            if (saw2 != exp) {
2505                errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2506                      " => \"" + saw2 + "\"");
2507            }
2508        }
2509    } else {
2510        dataerrln(UnicodeString("FAIL ") + toString(n) + " x " +
2511              escape(pat) + " = \"" +
2512              escape(saw) + "\", expected \"" + exp + "\"");
2513    }
2514}
2515
2516void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
2517                              const UnicodeString& exp,
2518                              UErrorCode status) {
2519    if (fmt == NULL || U_FAILURE(status)) {
2520        dataerrln("FAIL: NumberFormat constructor");
2521    } else {
2522        expect(*fmt, n, exp);
2523    }
2524    delete fmt;
2525}
2526
2527void NumberFormatTest::expectCurrency(NumberFormat& nf, const Locale& locale,
2528                                      double value, const UnicodeString& string) {
2529    UErrorCode ec = U_ZERO_ERROR;
2530    DecimalFormat& fmt = * (DecimalFormat*) &nf;
2531    const UChar DEFAULT_CURR[] = {45/*-*/,0};
2532    UChar curr[4];
2533    u_strcpy(curr, DEFAULT_CURR);
2534    if (*locale.getLanguage() != 0) {
2535        ucurr_forLocale(locale.getName(), curr, 4, &ec);
2536        assertSuccess("ucurr_forLocale", ec);
2537        fmt.setCurrency(curr, ec);
2538        assertSuccess("DecimalFormat::setCurrency", ec);
2539        fmt.setCurrency(curr); //Deprecated variant, for coverage only
2540    }
2541    UnicodeString s;
2542    fmt.format(value, s);
2543    s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020);
2544
2545    // Default display of the number yields "1234.5599999999999"
2546    // instead of "1234.56".  Use a formatter to fix this.
2547    NumberFormat* f =
2548        NumberFormat::createInstance(Locale::getUS(), ec);
2549    UnicodeString v;
2550    if (U_FAILURE(ec)) {
2551        // Oops; bad formatter.  Use default op+= display.
2552        v = (UnicodeString)"" + value;
2553    } else {
2554        f->setMaximumFractionDigits(4);
2555        f->setGroupingUsed(FALSE);
2556        f->format(value, v);
2557    }
2558    delete f;
2559
2560    if (s == string) {
2561        logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s));
2562    } else {
2563        errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) +
2564              ", expected " + prettify(string));
2565    }
2566}
2567
2568void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) {
2569    UnicodeString pat;
2570    fmt.toPattern(pat);
2571    if (pat == exp) {
2572        logln(UnicodeString("Ok   \"") + pat + "\"");
2573    } else {
2574        errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\"");
2575    }
2576}
2577
2578void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2579                                 int32_t pos) {
2580    expectPad(fmt, pat, pos, 0, (UnicodeString)"");
2581}
2582void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2583                                 int32_t pos, int32_t width, UChar pad) {
2584    expectPad(fmt, pat, pos, width, UnicodeString(pad));
2585}
2586void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2587                                 int32_t pos, int32_t width, const UnicodeString& pad) {
2588    int32_t apos = 0, awidth = 0;
2589    UnicodeString apadStr;
2590    UErrorCode status = U_ZERO_ERROR;
2591    fmt.applyPattern(pat, status);
2592    if (U_SUCCESS(status)) {
2593        apos = fmt.getPadPosition();
2594        awidth = fmt.getFormatWidth();
2595        apadStr=fmt.getPadCharacterString();
2596    } else {
2597        apos = -1;
2598        awidth = width;
2599        apadStr = pad;
2600    }
2601    if (apos == pos && awidth == width && apadStr == pad) {
2602        UnicodeString infoStr;
2603        if (pos == ILLEGAL) {
2604            infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr;
2605        }
2606        logln(UnicodeString("Ok   \"") + pat + "\" pos=" + apos + infoStr);
2607    } else {
2608        errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos +
2609              " width=" + awidth + " pad=" + apadStr +
2610              ", expected " + pos + " " + width + " " + pad);
2611    }
2612}
2613void NumberFormatTest::TestJB3832(){
2614    const char* localeID = "pt_PT@currency=PTE";
2615    Locale loc(localeID);
2616    UErrorCode status = U_ZERO_ERROR;
2617    UnicodeString expected(CharsToUnicodeString("1,150$50\\u00A0Esc."));
2618    UnicodeString s;
2619    NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
2620    if(U_FAILURE(status)){
2621        dataerrln("Could not create currency formatter for locale %s - %s", localeID, u_errorName(status));
2622        return;
2623    }
2624    currencyFmt->format(1150.50, s);
2625    if(s!=expected){
2626        errln(UnicodeString("FAIL: Expected: ")+expected
2627                + UnicodeString(" Got: ") + s
2628                + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
2629    }
2630    if (U_FAILURE(status)){
2631        errln("FAIL: Status %s", u_errorName(status));
2632    }
2633    delete currencyFmt;
2634}
2635
2636void NumberFormatTest::TestHost()
2637{
2638#if U_PLATFORM_USES_ONLY_WIN32_API
2639    Win32NumberTest::testLocales(this);
2640#endif
2641    Locale loc("en_US@compat=host");
2642    for (UNumberFormatStyle k = UNUM_DECIMAL;
2643         k < UNUM_FORMAT_STYLE_COUNT; k = (UNumberFormatStyle)(k+1)) {
2644        UErrorCode status = U_ZERO_ERROR;
2645        LocalPointer<NumberFormat> full(NumberFormat::createInstance(loc, k, status));
2646        if (!NumberFormat::isStyleSupported(k)) {
2647            if (status != U_UNSUPPORTED_ERROR) {
2648                errln("FAIL: expected style %d to be unsupported - %s",
2649                      k, u_errorName(status));
2650            }
2651            continue;
2652        }
2653        if (full.isNull() || U_FAILURE(status)) {
2654            dataerrln("FAIL: Can't create number instance of style %d for host - %s",
2655                      k, u_errorName(status));
2656            return;
2657        }
2658        UnicodeString result1;
2659        Formattable number(10.00);
2660        full->format(number, result1, status);
2661        if (U_FAILURE(status)) {
2662            errln("FAIL: Can't format for host");
2663            return;
2664        }
2665        Formattable formattable;
2666        full->parse(result1, formattable, status);
2667        if (U_FAILURE(status)) {
2668            errln("FAIL: Can't parse for host");
2669            return;
2670        }
2671    }
2672}
2673
2674void NumberFormatTest::TestHostClone()
2675{
2676    /*
2677    Verify that a cloned formatter gives the same results
2678    and is useable after the original has been deleted.
2679    */
2680    // This is mainly important on Windows.
2681    UErrorCode status = U_ZERO_ERROR;
2682    Locale loc("en_US@compat=host");
2683    UDate now = Calendar::getNow();
2684    NumberFormat *full = NumberFormat::createInstance(loc, status);
2685    if (full == NULL || U_FAILURE(status)) {
2686        dataerrln("FAIL: Can't create Relative date instance - %s", u_errorName(status));
2687        return;
2688    }
2689    UnicodeString result1;
2690    full->format(now, result1, status);
2691    Format *fullClone = full->clone();
2692    delete full;
2693    full = NULL;
2694
2695    UnicodeString result2;
2696    fullClone->format(now, result2, status);
2697    if (U_FAILURE(status)) {
2698        errln("FAIL: format failure.");
2699    }
2700    if (result1 != result2) {
2701        errln("FAIL: Clone returned different result from non-clone.");
2702    }
2703    delete fullClone;
2704}
2705
2706void NumberFormatTest::TestCurrencyFormat()
2707{
2708    // This test is here to increase code coverage.
2709    UErrorCode status = U_ZERO_ERROR;
2710    MeasureFormat *cloneObj;
2711    UnicodeString str;
2712    Formattable toFormat, result;
2713    static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0};
2714
2715    Locale  saveDefaultLocale = Locale::getDefault();
2716    Locale::setDefault( Locale::getUK(), status );
2717    if (U_FAILURE(status)) {
2718        errln("couldn't set default Locale!");
2719        return;
2720    }
2721
2722    MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status);
2723    Locale::setDefault( saveDefaultLocale, status );
2724    if (U_FAILURE(status)){
2725        dataerrln("FAIL: Status %s", u_errorName(status));
2726        return;
2727    }
2728    cloneObj = (MeasureFormat *)measureObj->clone();
2729    if (cloneObj == NULL) {
2730        errln("Clone doesn't work");
2731        return;
2732    }
2733    toFormat.adoptObject(new CurrencyAmount(1234.56, ISO_CODE, status));
2734    measureObj->format(toFormat, str, status);
2735    measureObj->parseObject(str, result, status);
2736    if (U_FAILURE(status)){
2737        errln("FAIL: Status %s", u_errorName(status));
2738    }
2739    if (result != toFormat) {
2740        errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
2741    }
2742    status = U_ZERO_ERROR;
2743    str.truncate(0);
2744    cloneObj->format(toFormat, str, status);
2745    cloneObj->parseObject(str, result, status);
2746    if (U_FAILURE(status)){
2747        errln("FAIL: Status %s", u_errorName(status));
2748    }
2749    if (result != toFormat) {
2750        errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
2751    }
2752    if (*measureObj != *cloneObj) {
2753        errln("Cloned object is not equal to the original object");
2754    }
2755    delete measureObj;
2756    delete cloneObj;
2757
2758    status = U_USELESS_COLLATOR_ERROR;
2759    if (MeasureFormat::createCurrencyFormat(status) != NULL) {
2760        errln("createCurrencyFormat should have returned NULL.");
2761    }
2762}
2763
2764/* Port of ICU4J rounding test. */
2765void NumberFormatTest::TestRounding() {
2766    UErrorCode status = U_ZERO_ERROR;
2767    DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
2768
2769    if (U_FAILURE(status)) {
2770        dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
2771        return;
2772    }
2773
2774    int roundingIncrements[]={1, 2, 5, 20, 50, 100};
2775    int testValues[]={0, 300};
2776
2777    for (int j=0; j<2; j++) {
2778        for (int mode=DecimalFormat::kRoundUp;mode<DecimalFormat::kRoundHalfEven;mode++) {
2779            df->setRoundingMode((DecimalFormat::ERoundingMode)mode);
2780            for (int increment=0; increment<6; increment++) {
2781                double base=testValues[j];
2782                double rInc=roundingIncrements[increment];
2783                checkRounding(df, base, 20, rInc);
2784                rInc=1.000000000/rInc;
2785                checkRounding(df, base, 20, rInc);
2786            }
2787        }
2788    }
2789    delete df;
2790}
2791
2792void NumberFormatTest::TestRoundingPattern() {
2793    UErrorCode status = U_ZERO_ERROR;
2794    struct {
2795        UnicodeString  pattern;
2796        double        testCase;
2797        UnicodeString expected;
2798    } tests[] = {
2799            { (UnicodeString)"##0.65", 1.234, (UnicodeString)"1.30" },
2800            { (UnicodeString)"#50",    1230,  (UnicodeString)"1250" }
2801    };
2802    int32_t numOfTests = (sizeof(tests)/sizeof(tests[0]));
2803    UnicodeString result;
2804
2805    DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
2806    if (U_FAILURE(status)) {
2807        dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
2808        return;
2809    }
2810
2811    for (int32_t i = 0; i < numOfTests; i++) {
2812        result.remove();
2813
2814        df->applyPattern(tests[i].pattern, status);
2815        if (U_FAILURE(status)) {
2816            errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status));
2817        }
2818
2819        df->format(tests[i].testCase, result);
2820
2821        if (result != tests[i].expected) {
2822            errln("String Pattern Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected);
2823        }
2824    }
2825
2826    delete df;
2827}
2828
2829void NumberFormatTest::checkRounding(DecimalFormat* df, double base, int iterations, double increment) {
2830    df->setRoundingIncrement(increment);
2831    double lastParsed=INT32_MIN; //Intger.MIN_VALUE
2832    for (int i=-iterations; i<=iterations;i++) {
2833        double iValue=base+(increment*(i*0.1));
2834        double smallIncrement=0.00000001;
2835        if (iValue!=0) {
2836            smallIncrement*=iValue;
2837        }
2838        //we not only test the value, but some values in a small range around it
2839        lastParsed=checkRound(df, iValue-smallIncrement, lastParsed);
2840        lastParsed=checkRound(df, iValue, lastParsed);
2841        lastParsed=checkRound(df, iValue+smallIncrement, lastParsed);
2842    }
2843}
2844
2845double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double lastParsed) {
2846    UErrorCode status=U_ZERO_ERROR;
2847    UnicodeString formattedDecimal;
2848    double parsed;
2849    Formattable result;
2850    df->format(iValue, formattedDecimal, status);
2851
2852    if (U_FAILURE(status)) {
2853        errln("Error formatting number.");
2854    }
2855
2856    df->parse(formattedDecimal, result, status);
2857
2858    if (U_FAILURE(status)) {
2859        errln("Error parsing number.");
2860    }
2861
2862    parsed=result.getDouble();
2863
2864    if (lastParsed>parsed) {
2865        errln("Rounding wrong direction! %d > %d", lastParsed, parsed);
2866    }
2867
2868    return lastParsed;
2869}
2870
2871void NumberFormatTest::TestNonpositiveMultiplier() {
2872    UErrorCode status = U_ZERO_ERROR;
2873    DecimalFormatSymbols US(Locale::getUS(), status);
2874    CHECK(status, "DecimalFormatSymbols constructor");
2875    DecimalFormat df(UnicodeString("0"), US, status);
2876    CHECK(status, "DecimalFormat(0)");
2877
2878    // test zero multiplier
2879
2880    int32_t mult = df.getMultiplier();
2881    df.setMultiplier(0);
2882    if (df.getMultiplier() != mult) {
2883        errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
2884    }
2885
2886    // test negative multiplier
2887
2888    df.setMultiplier(-1);
2889    if (df.getMultiplier() != -1) {
2890        errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
2891        return;
2892    }
2893
2894    expect(df, "1122.123", -1122.123);
2895    expect(df, "-1122.123", 1122.123);
2896    expect(df, "1.2", -1.2);
2897    expect(df, "-1.2", 1.2);
2898
2899    // Note:  the tests with the final parameter of FALSE will not round trip.
2900    //        The initial numeric value will format correctly, after the multiplier.
2901    //        Parsing the formatted text will be out-of-range for an int64, however.
2902    //        The expect() function could be modified to detect this and fall back
2903    //        to looking at the decimal parsed value, but it doesn't.
2904    expect(df, U_INT64_MIN,    "9223372036854775808", FALSE);
2905    expect(df, U_INT64_MIN+1,  "9223372036854775807");
2906    expect(df, (int64_t)-123,                  "123");
2907    expect(df, (int64_t)123,                  "-123");
2908    expect(df, U_INT64_MAX-1, "-9223372036854775806");
2909    expect(df, U_INT64_MAX,   "-9223372036854775807");
2910
2911    df.setMultiplier(-2);
2912    expect(df, -(U_INT64_MIN/2)-1, "-9223372036854775806");
2913    expect(df, -(U_INT64_MIN/2),   "-9223372036854775808");
2914    expect(df, -(U_INT64_MIN/2)+1, "-9223372036854775810", FALSE);
2915
2916    df.setMultiplier(-7);
2917    expect(df, -(U_INT64_MAX/7)-1, "9223372036854775814", FALSE);
2918    expect(df, -(U_INT64_MAX/7),   "9223372036854775807");
2919    expect(df, -(U_INT64_MAX/7)+1, "9223372036854775800");
2920
2921    // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported
2922    // (right now the big numbers get turned into doubles and lose tons of accuracy)
2923    //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
2924    //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
2925    //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
2926    //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
2927
2928    // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
2929    //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
2930    //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
2931    //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
2932    //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
2933}
2934
2935typedef struct {
2936    const char * stringToParse;
2937    int          parsedPos;
2938    int          errorIndex;
2939    UBool        lenient;
2940} TestSpaceParsingItem;
2941
2942void
2943NumberFormatTest::TestSpaceParsing() {
2944    // the data are:
2945    // the string to be parsed, parsed position, parsed error index
2946    const TestSpaceParsingItem DATA[] = {
2947        // TOTO: Update the following TODOs, some may be handled now
2948        {"$124",           4, -1, FALSE},
2949        {"$124 $124",      4, -1, FALSE},
2950        {"$124 ",          4, -1, FALSE},
2951        //{"$ 124 ",       5, -1, FALSE}, // TODO: need to handle space correctly
2952        //{"$\\u00A0124 ", 5, -1, FALSE}, // TODO: need to handle space correctly
2953        {"$ 124 ",         0,  1, FALSE}, // errorIndex used to be 0, now 1 (better)
2954        {"$\\u00A0124 ",   0,  1, FALSE}, // errorIndex used to be 0, now 1 (better)
2955        {" $ 124 ",        0,  0, FALSE}, // TODO: need to handle space correctly
2956        {"124$",           0,  3, FALSE}, // TODO: need to handle space correctly
2957        // {"124 $",       5, -1, FALSE}, // TODO: OK or not, need currency spacing rule
2958        {"124 $",          0,  3, FALSE},
2959        {"$124",           4, -1, TRUE},
2960        {"$124 $124",      4, -1, TRUE},
2961        {"$124 ",          4, -1, TRUE},
2962        {"$ 124 ",         5, -1, TRUE},
2963        {"$\\u00A0124 ",   5, -1, TRUE},
2964        {" $ 124 ",        6, -1, TRUE},
2965        //{"124$",         4, -1, TRUE}, // TODO: need to handle trailing currency correctly
2966        {"124$",           3, -1, TRUE},
2967        //{"124 $",        5, -1, TRUE}, // TODO: OK or not, need currency spacing rule
2968        {"124 $",          4, -1, TRUE},
2969    };
2970    UErrorCode status = U_ZERO_ERROR;
2971    Locale locale("en_US");
2972    NumberFormat* foo = NumberFormat::createCurrencyInstance(locale, status);
2973
2974    if (U_FAILURE(status)) {
2975        delete foo;
2976        return;
2977    }
2978    for (uint32_t i = 0; i < sizeof(DATA)/sizeof(DATA[0]); ++i) {
2979        ParsePosition parsePosition(0);
2980        UnicodeString stringToBeParsed = ctou(DATA[i].stringToParse);
2981        int parsedPosition = DATA[i].parsedPos;
2982        int errorIndex = DATA[i].errorIndex;
2983        foo->setLenient(DATA[i].lenient);
2984        Formattable result;
2985        foo->parse(stringToBeParsed, result, parsePosition);
2986        if (parsePosition.getIndex() != parsedPosition ||
2987            parsePosition.getErrorIndex() != errorIndex) {
2988            errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
2989        }
2990        if (parsePosition.getErrorIndex() == -1 &&
2991            result.getType() == Formattable::kLong &&
2992            result.getLong() != 124) {
2993            errln("FAILED parse " + stringToBeParsed + "; wrong number, expect: 124, got " + result.getLong());
2994        }
2995    }
2996    delete foo;
2997}
2998
2999/**
3000 * Test using various numbering systems and numbering system keyword.
3001 */
3002typedef struct {
3003    const char *localeName;
3004    double      value;
3005    UBool        isRBNF;
3006    const char *expectedResult;
3007} TestNumberingSystemItem;
3008
3009void NumberFormatTest::TestNumberingSystems() {
3010
3011    const TestNumberingSystemItem DATA[] = {
3012        { "en_US@numbers=thai", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" },
3013        { "en_US@numbers=hebr", 5678.0, TRUE, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" },
3014        { "en_US@numbers=arabext", 1234.567, FALSE, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" },
3015        { "ar_EG", 1234.567, FALSE, "\\u0661\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
3016        { "th_TH@numbers=traditional", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35
3017        { "ar_MA", 1234.567, FALSE, "1.234,567" },
3018        { "en_US@numbers=hanidec", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3019        { "ta_IN@numbers=native", 1234.567, FALSE, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" },
3020        { "ta_IN@numbers=traditional", 1235.0, TRUE, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" },
3021        { "ta_IN@numbers=finance", 1234.567, FALSE, "1,234.567" }, // fall back to default per TR35
3022        { "zh_TW@numbers=native", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3023        { "zh_TW@numbers=traditional", 1234.567, TRUE, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" },
3024        { "zh_TW@numbers=finance", 1234.567, TRUE, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
3025        { NULL, 0, FALSE, NULL }
3026    };
3027
3028    UErrorCode ec;
3029
3030    const TestNumberingSystemItem *item;
3031    for (item = DATA; item->localeName != NULL; item++) {
3032        ec = U_ZERO_ERROR;
3033        Locale loc = Locale::createFromName(item->localeName);
3034        NumberFormat *fmt = NumberFormat::createInstance(loc,ec);
3035
3036        if (U_FAILURE(ec)) {
3037            dataerrln("FAIL: getInstance(%s) - %s", item->localeName, u_errorName(ec));
3038            continue;
3039        }
3040
3041        if (item->isRBNF) {
3042            expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3043        } else {
3044            expect2(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3045        }
3046        delete fmt;
3047    }
3048
3049
3050    // Test bogus keyword value
3051    ec = U_ZERO_ERROR;
3052    Locale loc4 = Locale::createFromName("en_US@numbers=foobar");
3053    NumberFormat* fmt4= NumberFormat::createInstance(loc4, ec);
3054    if ( ec != U_UNSUPPORTED_ERROR ) {
3055        errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR");
3056        delete fmt4;
3057    }
3058
3059    ec = U_ZERO_ERROR;
3060    NumberingSystem *ns = NumberingSystem::createInstance(ec);
3061    if (U_FAILURE(ec)) {
3062        dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec));
3063    }
3064
3065    if ( ns != NULL ) {
3066        ns->getDynamicClassID();
3067        ns->getStaticClassID();
3068    } else {
3069        errln("FAIL: getInstance() returned NULL.");
3070    }
3071
3072    NumberingSystem *ns1 = new NumberingSystem(*ns);
3073    if (ns1 == NULL) {
3074        errln("FAIL: NumberSystem copy constructor returned NULL.");
3075    }
3076
3077    delete ns1;
3078    delete ns;
3079
3080}
3081
3082
3083void
3084NumberFormatTest::TestMultiCurrencySign() {
3085    const char* DATA[][6] = {
3086        // the fields in the following test are:
3087        // locale,
3088        // currency pattern (with negative pattern),
3089        // currency number to be formatted,
3090        // currency format using currency symbol name, such as "$" for USD,
3091        // currency format using currency ISO name, such as "USD",
3092        // currency format using plural name, such as "US dollars".
3093        // for US locale
3094        {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"},
3095        {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"},
3096        {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollar1.00"},
3097        // for CHINA locale
3098        {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\uFFE51,234.56", "CNY1,234.56", "\\u4EBA\\u6C11\\u5E011,234.56"},
3099        {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\uFFE51,234.56)", "(CNY1,234.56)", "(\\u4EBA\\u6C11\\u5E011,234.56)"},
3100        {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\uFFE51.00", "CNY1.00", "\\u4EBA\\u6C11\\u5E011.00"}
3101    };
3102
3103    const UChar doubleCurrencySign[] = {0xA4, 0xA4, 0};
3104    UnicodeString doubleCurrencyStr(doubleCurrencySign);
3105    const UChar tripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
3106    UnicodeString tripleCurrencyStr(tripleCurrencySign);
3107
3108    for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) {
3109        const char* locale = DATA[i][0];
3110        UnicodeString pat = ctou(DATA[i][1]);
3111        double numberToBeFormat = atof(DATA[i][2]);
3112        UErrorCode status = U_ZERO_ERROR;
3113        DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale(locale), status);
3114        if (U_FAILURE(status)) {
3115            delete sym;
3116            continue;
3117        }
3118        for (int j=1; j<=3; ++j) {
3119            // j represents the number of currency sign in the pattern.
3120            if (j == 2) {
3121                pat = pat.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr);
3122            } else if (j == 3) {
3123                pat = pat.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr);
3124            }
3125
3126            DecimalFormat* fmt = new DecimalFormat(pat, new DecimalFormatSymbols(*sym), status);
3127            if (U_FAILURE(status)) {
3128                errln("FAILED init DecimalFormat ");
3129                delete fmt;
3130                continue;
3131            }
3132            UnicodeString s;
3133            ((NumberFormat*) fmt)->format(numberToBeFormat, s);
3134            // DATA[i][3] is the currency format result using a
3135            // single currency sign.
3136            // DATA[i][4] is the currency format result using
3137            // double currency sign.
3138            // DATA[i][5] is the currency format result using
3139            // triple currency sign.
3140            // DATA[i][j+2] is the currency format result using
3141            // 'j' number of currency sign.
3142            UnicodeString currencyFormatResult = ctou(DATA[i][2+j]);
3143            if (s.compare(currencyFormatResult)) {
3144                errln("FAIL format: Expected " + currencyFormatResult + "; Got " + s);
3145            }
3146            // mix style parsing
3147            for (int k=3; k<=5; ++k) {
3148              // DATA[i][3] is the currency format result using a
3149              // single currency sign.
3150              // DATA[i][4] is the currency format result using
3151              // double currency sign.
3152              // DATA[i][5] is the currency format result using
3153              // triple currency sign.
3154              UnicodeString oneCurrencyFormat = ctou(DATA[i][k]);
3155              UErrorCode status = U_ZERO_ERROR;
3156              Formattable parseRes;
3157              fmt->parse(oneCurrencyFormat, parseRes, status);
3158              if (U_FAILURE(status) ||
3159                  (parseRes.getType() == Formattable::kDouble &&
3160                   parseRes.getDouble() != numberToBeFormat) ||
3161                  (parseRes.getType() == Formattable::kLong &&
3162                   parseRes.getLong() != numberToBeFormat)) {
3163                  errln("FAILED parse " + oneCurrencyFormat + "; (i, j, k): " +
3164                        i + ", " + j + ", " + k);
3165              }
3166            }
3167            delete fmt;
3168        }
3169        delete sym;
3170    }
3171}
3172
3173
3174void
3175NumberFormatTest::TestCurrencyFormatForMixParsing() {
3176    UErrorCode status = U_ZERO_ERROR;
3177    MeasureFormat* curFmt = MeasureFormat::createCurrencyFormat(Locale("en_US"), status);
3178    if (U_FAILURE(status)) {
3179        delete curFmt;
3180        return;
3181    }
3182    const char* formats[] = {
3183        "$1,234.56",  // string to be parsed
3184        "USD1,234.56",
3185        "US dollars1,234.56",
3186        "1,234.56 US dollars"
3187    };
3188    const CurrencyAmount* curramt = NULL;
3189    for (uint32_t i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
3190        UnicodeString stringToBeParsed = ctou(formats[i]);
3191        logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed);
3192        Formattable result;
3193        UErrorCode status = U_ZERO_ERROR;
3194        curFmt->parseObject(stringToBeParsed, result, status);
3195        if (U_FAILURE(status)) {
3196          errln("FAIL: measure format parsing: '%s' ec: %s", formats[i], u_errorName(status));
3197        } else if (result.getType() != Formattable::kObject ||
3198            (curramt = dynamic_cast<const CurrencyAmount*>(result.getObject())) == NULL ||
3199            curramt->getNumber().getDouble() != 1234.56 ||
3200            UnicodeString(curramt->getISOCurrency()).compare(ISO_CURRENCY_USD)
3201        ) {
3202            errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
3203            if (curramt->getNumber().getDouble() != 1234.56) {
3204                errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + curramt->getNumber().getDouble());
3205            }
3206            if (curramt->getISOCurrency() != ISO_CURRENCY_USD) {
3207                errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency());
3208            }
3209        }
3210    }
3211    delete curFmt;
3212}
3213
3214
3215void
3216NumberFormatTest::TestDecimalFormatCurrencyParse() {
3217    // Locale.US
3218    UErrorCode status = U_ZERO_ERROR;
3219    DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale("en_US"), status);
3220    if (U_FAILURE(status)) {
3221        delete sym;
3222        return;
3223    }
3224    UnicodeString pat;
3225    UChar currency = 0x00A4;
3226    // "\xA4#,##0.00;-\xA4#,##0.00"
3227    pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");
3228    DecimalFormat* fmt = new DecimalFormat(pat, sym, status);
3229    if (U_FAILURE(status)) {
3230        delete fmt;
3231        errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
3232        return;
3233    }
3234    const char* DATA[][2] = {
3235        // the data are:
3236        // string to be parsed, the parsed result (number)
3237        {"$1.00", "1"},
3238        {"USD1.00", "1"},
3239        {"1.00 US dollar", "1"},
3240        {"$1,234.56", "1234.56"},
3241        {"USD1,234.56", "1234.56"},
3242        {"1,234.56 US dollar", "1234.56"},
3243    };
3244    for (uint32_t i = 0; i < sizeof(DATA)/sizeof(DATA[0]); ++i) {
3245        UnicodeString stringToBeParsed = ctou(DATA[i][0]);
3246        double parsedResult = atof(DATA[i][1]);
3247        UErrorCode status = U_ZERO_ERROR;
3248        Formattable result;
3249        fmt->parse(stringToBeParsed, result, status);
3250        if (U_FAILURE(status) ||
3251            (result.getType() == Formattable::kDouble &&
3252            result.getDouble() != parsedResult) ||
3253            (result.getType() == Formattable::kLong &&
3254            result.getLong() != parsedResult)) {
3255            errln((UnicodeString)"FAIL parse: Expected " + parsedResult);
3256        }
3257    }
3258    delete fmt;
3259}
3260
3261
3262void
3263NumberFormatTest::TestCurrencyIsoPluralFormat() {
3264    static const char* DATA[][6] = {
3265        // the data are:
3266        // locale,
3267        // currency amount to be formatted,
3268        // currency ISO code to be formatted,
3269        // format result using CURRENCYSTYLE,
3270        // format result using ISOCURRENCYSTYLE,
3271        // format result using PLURALCURRENCYSTYLE,
3272
3273        {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},
3274        {"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"},
3275        {"en_US", "-1234.56", "USD", "($1,234.56)", "(USD1,234.56)", "-1,234.56 US dollars"},
3276        {"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00\\u7F8E\\u5143"},
3277        {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56\\u7F8E\\u5143"},
3278        // wrong ISO code {"zh_CN", "1", "CHY", "CHY1.00", "CHY1.00", "1.00 CHY"},
3279        // wrong ISO code {"zh_CN", "1234.56", "CHY", "CHY1,234.56", "CHY1,234.56", "1,234.56 CHY"},
3280        {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY1.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3281        {"zh_CN", "1234.56", "CNY", "\\uFFE51,234.56", "CNY1,234.56", "1,234.56\\u4EBA\\u6C11\\u5E01"},
3282        {"ru_RU", "1", "RUB", "1,00\\u00A0\\u0440\\u0443\\u0431.", "1,00\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0439 \\u0440\\u0443\\u0431\\u043B\\u044C"},
3283        {"ru_RU", "2", "RUB", "2,00\\u00A0\\u0440\\u0443\\u0431.", "2,00\\u00A0RUB", "2,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0445 \\u0440\\u0443\\u0431\\u043B\\u044F"},
3284        {"ru_RU", "5", "RUB", "5,00\\u00A0\\u0440\\u0443\\u0431.", "5,00\\u00A0RUB", "5,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0445 \\u0440\\u0443\\u0431\\u043B\\u0435\\u0439"},
3285        // test locale without currency information
3286        {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
3287        // test choice format
3288        {"es_AR", "1", "INR", "Rs.1,00", "INR1,00", "1,00 rupia india"},  // Google Patch
3289    };
3290    static const UNumberFormatStyle currencyStyles[] = {
3291        UNUM_CURRENCY,
3292        UNUM_CURRENCY_ISO,
3293        UNUM_CURRENCY_PLURAL
3294    };
3295
3296    for (int32_t i=0; i<LENGTHOF(DATA); ++i) {
3297      for (int32_t kIndex = 0; kIndex < LENGTHOF(currencyStyles); ++kIndex) {
3298        UNumberFormatStyle k = currencyStyles[kIndex];
3299        const char* localeString = DATA[i][0];
3300        double numberToBeFormat = atof(DATA[i][1]);
3301        const char* currencyISOCode = DATA[i][2];
3302        Locale locale(localeString);
3303        UErrorCode status = U_ZERO_ERROR;
3304        NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3305        if (U_FAILURE(status)) {
3306            delete numFmt;
3307            dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3308            continue;
3309        }
3310        UChar currencyCode[4];
3311        u_charsToUChars(currencyISOCode, currencyCode, 4);
3312        numFmt->setCurrency(currencyCode, status);
3313        if (U_FAILURE(status)) {
3314            delete numFmt;
3315            errln((UnicodeString)"can not set currency:" + currencyISOCode);
3316            continue;
3317        }
3318
3319        UnicodeString strBuf;
3320        numFmt->format(numberToBeFormat, strBuf);
3321        int resultDataIndex = 3 + kIndex;
3322        // DATA[i][resultDataIndex] is the currency format result
3323        // using 'k' currency style.
3324        UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
3325        if (strBuf.compare(formatResult)) {
3326            errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
3327        }
3328        // test parsing, and test parsing for all currency formats.
3329        for (int j = 3; j < 6; ++j) {
3330            // DATA[i][3] is the currency format result using
3331            // CURRENCYSTYLE formatter.
3332            // DATA[i][4] is the currency format result using
3333            // ISOCURRENCYSTYLE formatter.
3334            // DATA[i][5] is the currency format result using
3335            // PLURALCURRENCYSTYLE formatter.
3336            UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
3337            UErrorCode status = U_ZERO_ERROR;
3338            Formattable parseResult;
3339            numFmt->parse(oneCurrencyFormatResult, parseResult, status);
3340            if (U_FAILURE(status) ||
3341                (parseResult.getType() == Formattable::kDouble &&
3342                 parseResult.getDouble() != numberToBeFormat) ||
3343                (parseResult.getType() == Formattable::kLong &&
3344                 parseResult.getLong() != numberToBeFormat)) {
3345                errln((UnicodeString)"FAIL: getCurrencyFormat of locale " +
3346                      localeString + " failed roundtripping the number");
3347                if (parseResult.getType() == Formattable::kDouble) {
3348                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getDouble());
3349                } else {
3350                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong());
3351                }
3352            }
3353        }
3354        delete numFmt;
3355      }
3356    }
3357}
3358
3359void
3360NumberFormatTest::TestCurrencyParsing() {
3361    static const char* DATA[][6] = {
3362        // the data are:
3363        // locale,
3364        // currency amount to be formatted,
3365        // currency ISO code to be formatted,
3366        // format result using CURRENCYSTYLE,
3367        // format result using ISOCURRENCYSTYLE,
3368        // format result using PLURALCURRENCYSTYLE,
3369        {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},
3370        {"pa_IN", "1", "USD", "US$\\u00a0\\u0a67.\\u0a66\\u0a66", "USD\\u00a0\\u0a67.\\u0a66\\u0a66", "\\u0a67.\\u0a66\\u0a66 USD"},
3371        {"es_AR", "1", "USD", "US$1,00", "USD1,00", "1,00 d\\u00f3lar estadounidense"},
3372        {"ar_EG", "1", "USD", "US$\\u00a0\\u0661\\u066b\\u0660\\u0660", "USD\\u00a0\\u0661\\u066b\\u0660\\u0660", "\\u0661\\u066b\\u0660\\u0660 \\u062f\\u0648\\u0644\\u0627\\u0631 \\u0623\\u0645\\u0631\\u064a\\u0643\\u064a"},
3373        {"fa_CA", "1", "USD", "\\u200eUS$\\u06f1\\u066b\\u06f0\\u06f0", "\\u200eUSD\\u06f1\\u066b\\u06f0\\u06f0", "\\u200e\\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627\\u06f1\\u066b\\u06f0\\u06f0"},
3374        {"he_IL", "1", "USD", "1.00\\u00a0US$", "1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
3375        {"hr_HR", "1", "USD", "1,00\\u00a0$", "1,00\\u00a0USD", "1,00 Ameri\\u010dki dolar"},
3376        {"id_ID", "1", "USD", "US$1,00", "USD1,00", "1,00 Dolar Amerika Serikat"},
3377        {"it_IT", "1", "USD", "US$\\u00a01,00", "USD\\u00a01,00", "1,00 Dollaro Statunitense"},
3378        {"ko_KR", "1", "USD", "US$1.00", "USD1.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
3379        {"ja_JP", "1", "USD", "$1.00", "USD1.00", "1.00 \\u7c73\\u30c9\\u30eb"},
3380        {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY1.00", "1.00\\u4EBA\\u6C11\\u5E01"},
3381        {"zh_TW", "1", "CNY", "\\uFFE51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
3382        {"ru_RU", "1", "RUB", "1,00\\u00A0\\u0440\\u0443\\u0431.", "1,00\\u00A0RUB", "1,00 \\u0420\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0439 \\u0440\\u0443\\u0431\\u043B\\u044C"},
3383    };
3384    static const UNumberFormatStyle currencyStyles[] = {
3385        UNUM_CURRENCY,
3386        UNUM_CURRENCY_ISO,
3387        UNUM_CURRENCY_PLURAL
3388    };
3389
3390#ifdef NUMFMTST_CACHE_DEBUG
3391int deadloop = 0;
3392for (;;) {
3393    printf("loop: %d\n", deadloop++);
3394#endif
3395    for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) {
3396      for (int32_t kIndex = 0; kIndex < LENGTHOF(currencyStyles); ++kIndex) {
3397        UNumberFormatStyle k = currencyStyles[kIndex];
3398        const char* localeString = DATA[i][0];
3399        double numberToBeFormat = atof(DATA[i][1]);
3400        const char* currencyISOCode = DATA[i][2];
3401        Locale locale(localeString);
3402        UErrorCode status = U_ZERO_ERROR;
3403        NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3404        if (U_FAILURE(status)) {
3405            delete numFmt;
3406            dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3407            continue;
3408        }
3409        UChar currencyCode[4];
3410        u_charsToUChars(currencyISOCode, currencyCode, 4);
3411        numFmt->setCurrency(currencyCode, status);
3412        if (U_FAILURE(status)) {
3413            delete numFmt;
3414            errln((UnicodeString)"can not set currency:" + currencyISOCode);
3415            continue;
3416        }
3417
3418        /*
3419        UnicodeString strBuf;
3420        numFmt->format(numberToBeFormat, strBuf);
3421        int resultDataIndex = 3 + kIndex;
3422        // DATA[i][resultDataIndex] is the currency format result
3423        // using 'k' currency style.
3424        UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
3425        if (strBuf.compare(formatResult)) {
3426            errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
3427        }
3428        */
3429        // test parsing, and test parsing for all currency formats.
3430        for (int j = 3; j < 6; ++j) {
3431            // DATA[i][3] is the currency format result using
3432            // CURRENCYSTYLE formatter.
3433            // DATA[i][4] is the currency format result using
3434            // ISOCURRENCYSTYLE formatter.
3435            // DATA[i][5] is the currency format result using
3436            // PLURALCURRENCYSTYLE formatter.
3437            UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
3438            UErrorCode status = U_ZERO_ERROR;
3439            Formattable parseResult;
3440            numFmt->parse(oneCurrencyFormatResult, parseResult, status);
3441            if (U_FAILURE(status) ||
3442                (parseResult.getType() == Formattable::kDouble &&
3443                 parseResult.getDouble() != numberToBeFormat) ||
3444                (parseResult.getType() == Formattable::kLong &&
3445                 parseResult.getLong() != numberToBeFormat)) {
3446                errln((UnicodeString)"FAIL: getCurrencyFormat of locale " +
3447                      localeString + " failed roundtripping the number" +
3448                      "(i,k,j): " + i + ", " + k + ", " + j);
3449                if (parseResult.getType() == Formattable::kDouble) {
3450                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getDouble());
3451                } else {
3452                    errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong());
3453                }
3454            }
3455        }
3456        delete numFmt;
3457      }
3458    }
3459#ifdef NUMFMTST_CACHE_DEBUG
3460}
3461#endif
3462}
3463
3464
3465void
3466NumberFormatTest::TestParseCurrencyInUCurr() {
3467    const char* DATA[] = {
3468        "1.00 US DOLLAR",  // case in-sensitive
3469        "$1.00",
3470        "USD1.00",
3471        "US dollar1.00",
3472        "US dollars1.00",
3473        "$1.00",
3474        "A$1.00",
3475        "ADP1.00",
3476        "ADP1.00",
3477        "AED1.00",
3478        "AED1.00",
3479        "AFA1.00",
3480        "AFA1.00",
3481        "AFN1.00",
3482        "ALL1.00",
3483        "AMD1.00",
3484        "ANG1.00",
3485        "AOA1.00",
3486        "AOK1.00",
3487        "AOK1.00",
3488        "AON1.00",
3489        "AON1.00",
3490        "AOR1.00",
3491        "AOR1.00",
3492        "ARS1.00",
3493        "ARA1.00",
3494        "ARA1.00",
3495        "ARP1.00",
3496        "ARP1.00",
3497        "ARS1.00",
3498        "ATS1.00",
3499        "ATS1.00",
3500        "AUD1.00",
3501        "AWG1.00",
3502        "AZM1.00",
3503        "AZM1.00",
3504        "AZN1.00",
3505        "Afghan Afghani (1927-2002)1.00",
3506        "Afghan afghani (1927-2002)1.00",
3507        "Afghan Afghani1.00",
3508        "Afghan Afghanis1.00",
3509        "Albanian Lek1.00",
3510        "Albanian lek1.00",
3511        "Albanian lek\\u00eb1.00",
3512        "Algerian Dinar1.00",
3513        "Algerian dinar1.00",
3514        "Algerian dinars1.00",
3515        "Andorran Peseta1.00",
3516        "Andorran peseta1.00",
3517        "Andorran pesetas1.00",
3518        "Angolan Kwanza (1977-1991)1.00",
3519        "Angolan Readjusted Kwanza (1995-1999)1.00",
3520        "Angolan Kwanza1.00",
3521        "Angolan New Kwanza (1990-2000)1.00",
3522        "Angolan kwanza (1977-1991)1.00",
3523        "Angolan readjusted kwanza (1995-1999)1.00",
3524        "Angolan kwanza1.00",
3525        "Angolan kwanzas (1977-1991)1.00",
3526        "Angolan readjusted kwanzas (1995-1999)1.00",
3527        "Angolan kwanzas1.00",
3528        "Angolan new kwanza (1990-2000)1.00",
3529        "Angolan new kwanzas (1990-2000)1.00",
3530        "Argentine Austral1.00",
3531        "Argentine Peso (1983-1985)1.00",
3532        "Argentine Peso1.00",
3533        "Argentine austral1.00",
3534        "Argentine australs1.00",
3535        "Argentine peso (1983-1985)1.00",
3536        "Argentine peso1.00",
3537        "Argentine pesos (1983-1985)1.00",
3538        "Argentine pesos1.00",
3539        "Armenian Dram1.00",
3540        "Armenian dram1.00",
3541        "Armenian drams1.00",
3542        "Aruban Florin1.00",
3543        "Aruban florin1.00",
3544        "Australian Dollar1.00",
3545        "Australian dollar1.00",
3546        "Australian dollars1.00",
3547        "Austrian Schilling1.00",
3548        "Austrian schilling1.00",
3549        "Austrian schillings1.00",
3550        "Azerbaijani Manat (1993-2006)1.00",
3551        "Azerbaijani Manat1.00",
3552        "Azerbaijani manat (1993-2006)1.00",
3553        "Azerbaijani manat1.00",
3554        "Azerbaijani manats (1993-2006)1.00",
3555        "Azerbaijani manats1.00",
3556        "BAD1.00",
3557        "BAD1.00",
3558        "BAM1.00",
3559        "BBD1.00",
3560        "BDT1.00",
3561        "BEC1.00",
3562        "BEC1.00",
3563        "BEF1.00",
3564        "BEL1.00",
3565        "BEL1.00",
3566        "BGL1.00",
3567        "BGN1.00",
3568        "BGN1.00",
3569        "BHD1.00",
3570        "BIF1.00",
3571        "BMD1.00",
3572        "BND1.00",
3573        "BOB1.00",
3574        "BOP1.00",
3575        "BOP1.00",
3576        "BOV1.00",
3577        "BOV1.00",
3578        "BRB1.00",
3579        "BRB1.00",
3580        "BRC1.00",
3581        "BRC1.00",
3582        "BRE1.00",
3583        "BRE1.00",
3584        "BRL1.00",
3585        "BRN1.00",
3586        "BRN1.00",
3587        "BRR1.00",
3588        "BRR1.00",
3589        "BSD1.00",
3590        "BSD1.00",
3591        "BTN1.00",
3592        "BUK1.00",
3593        "BUK1.00",
3594        "BWP1.00",
3595        "BYB1.00",
3596        "BYB1.00",
3597        "BYR1.00",
3598        "BZD1.00",
3599        "Bahamian Dollar1.00",
3600        "Bahamian dollar1.00",
3601        "Bahamian dollars1.00",
3602        "Bahraini Dinar1.00",
3603        "Bahraini dinar1.00",
3604        "Bahraini dinars1.00",
3605        "Bangladeshi Taka1.00",
3606        "Bangladeshi taka1.00",
3607        "Bangladeshi takas1.00",
3608        "Barbadian Dollar1.00",
3609        "Barbadian dollar1.00",
3610        "Barbadian dollars1.00",
3611        "Belarusian New Ruble (1994-1999)1.00",
3612        "Belarusian Ruble1.00",
3613        "Belarusian new ruble (1994-1999)1.00",
3614        "Belarusian new rubles (1994-1999)1.00",
3615        "Belarusian ruble1.00",
3616        "Belarusian rubles1.00",
3617        "Belgian Franc (convertible)1.00",
3618        "Belgian Franc (financial)1.00",
3619        "Belgian Franc1.00",
3620        "Belgian franc (convertible)1.00",
3621        "Belgian franc (financial)1.00",
3622        "Belgian franc1.00",
3623        "Belgian francs (convertible)1.00",
3624        "Belgian francs (financial)1.00",
3625        "Belgian francs1.00",
3626        "Belize Dollar1.00",
3627        "Belize dollar1.00",
3628        "Belize dollars1.00",
3629        "Bermudan Dollar1.00",
3630        "Bermudan dollar1.00",
3631        "Bermudan dollars1.00",
3632        "Bhutanese Ngultrum1.00",
3633        "Bhutanese ngultrum1.00",
3634        "Bhutanese ngultrums1.00",
3635        "Bolivian Mvdol1.00",
3636        "Bolivian Peso1.00",
3637        "Bolivian mvdol1.00",
3638        "Bolivian mvdols1.00",
3639        "Bolivian peso1.00",
3640        "Bolivian pesos1.00",
3641        "Bolivian Boliviano1.00",
3642        "Bolivian Boliviano1.00",
3643        "Bolivian Bolivianos1.00",
3644        "Bosnia-Herzegovina Convertible Mark1.00",
3645        "Bosnia-Herzegovina Dinar (1992-1994)1.00",
3646        "Bosnia-Herzegovina convertible mark1.00",
3647        "Bosnia-Herzegovina convertible marks1.00",
3648        "Bosnia-Herzegovina dinar (1992-1994)1.00",
3649        "Bosnia-Herzegovina dinars (1992-1994)1.00",
3650        "Botswanan Pula1.00",
3651        "Botswanan pula1.00",
3652        "Botswanan pulas1.00",
3653        "Brazilian New Cruzado (1989-1990)1.00",
3654        "Brazilian Cruzado (1986-1989)1.00",
3655        "Brazilian Cruzeiro (1990-1993)1.00",
3656        "Brazilian New Cruzeiro (1967-1986)1.00",
3657        "Brazilian Cruzeiro (1993-1994)1.00",
3658        "Brazilian Real1.00",
3659        "Brazilian new cruzado (1989-1990)1.00",
3660        "Brazilian new cruzados (1989-1990)1.00",
3661        "Brazilian cruzado (1986-1989)1.00",
3662        "Brazilian cruzados (1986-1989)1.00",
3663        "Brazilian cruzeiro (1990-1993)1.00",
3664        "Brazilian new cruzeiro (1967-1986)1.00",
3665        "Brazilian cruzeiro (1993-1994)1.00",
3666        "Brazilian cruzeiros (1990-1993)1.00",
3667        "Brazilian new cruzeiros (1967-1986)1.00",
3668        "Brazilian cruzeiros (1993-1994)1.00",
3669        "Brazilian real1.00",
3670        "Brazilian reals1.00",
3671        "British Pound Sterling1.00",
3672        "British pound sterling1.00",
3673        "British pounds sterling1.00",
3674        "Brunei Dollar1.00",
3675        "Brunei dollar1.00",
3676        "Brunei dollars1.00",
3677        "Bulgarian Hard Lev1.00",
3678        "Bulgarian Lev1.00",
3679        "Bulgarian Leva1.00",
3680        "Bulgarian hard lev1.00",
3681        "Bulgarian hard leva1.00",
3682        "Bulgarian lev1.00",
3683        "Burmese Kyat1.00",
3684        "Burmese kyat1.00",
3685        "Burmese kyats1.00",
3686        "Burundian Franc1.00",
3687        "Burundian franc1.00",
3688        "Burundian francs1.00",
3689        "CA$1.00",
3690        "CAD1.00",
3691        "CDF1.00",
3692        "CDF1.00",
3693        "CFA Franc BCEAO1.00",
3694        "CFA Franc BEAC1.00",
3695        "CFA franc BCEAO1.00",
3696        "CFA franc BEAC1.00",
3697        "CFA francs BCEAO1.00",
3698        "CFA francs BEAC1.00",
3699        "CFP Franc1.00",
3700        "CFP franc1.00",
3701        "CFP francs1.00",
3702        "CFPF1.00",
3703        "CHE1.00",
3704        "CHE1.00",
3705        "CHF1.00",
3706        "CHW1.00",
3707        "CHW1.00",
3708        "CLF1.00",
3709        "CLF1.00",
3710        "CLP1.00",
3711        "CNY1.00",
3712        "COP1.00",
3713        "COU1.00",
3714        "COU1.00",
3715        "CRC1.00",
3716        "CSD1.00",
3717        "CSD1.00",
3718        "CSK1.00",
3719        "CSK1.00",
3720        "CUP1.00",
3721        "CUP1.00",
3722        "CVE1.00",
3723        "CYP1.00",
3724        "CZK1.00",
3725        "Cambodian Riel1.00",
3726        "Cambodian riel1.00",
3727        "Cambodian riels1.00",
3728        "Canadian Dollar1.00",
3729        "Canadian dollar1.00",
3730        "Canadian dollars1.00",
3731        "Cape Verdean Escudo1.00",
3732        "Cape Verdean escudo1.00",
3733        "Cape Verdean escudos1.00",
3734        "Cayman Islands Dollar1.00",
3735        "Cayman Islands dollar1.00",
3736        "Cayman Islands dollars1.00",
3737        "Chilean Peso1.00",
3738        "Chilean Unit of Account (UF)1.00",
3739        "Chilean peso1.00",
3740        "Chilean pesos1.00",
3741        "Chilean unit of account (UF)1.00",
3742        "Chilean units of account (UF)1.00",
3743        "Chinese Yuan1.00",
3744        "Chinese yuan1.00",
3745        "Colombian Peso1.00",
3746        "Colombian peso1.00",
3747        "Colombian pesos1.00",
3748        "Comorian Franc1.00",
3749        "Comorian franc1.00",
3750        "Comorian francs1.00",
3751        "Congolese Franc1.00",
3752        "Congolese franc1.00",
3753        "Congolese francs1.00",
3754        "Costa Rican Col\\u00f3n1.00",
3755        "Costa Rican col\\u00f3n1.00",
3756        "Costa Rican col\\u00f3ns1.00",
3757        "Croatian Dinar1.00",
3758        "Croatian Kuna1.00",
3759        "Croatian dinar1.00",
3760        "Croatian dinars1.00",
3761        "Croatian kuna1.00",
3762        "Croatian kunas1.00",
3763        "Cuban Peso1.00",
3764        "Cuban peso1.00",
3765        "Cuban pesos1.00",
3766        "Cypriot Pound1.00",
3767        "Cypriot pound1.00",
3768        "Cypriot pounds1.00",
3769        "Czech Republic Koruna1.00",
3770        "Czech Republic koruna1.00",
3771        "Czech Republic korunas1.00",
3772        "Czechoslovak Hard Koruna1.00",
3773        "Czechoslovak hard koruna1.00",
3774        "Czechoslovak hard korunas1.00",
3775        "DDM1.00",
3776        "DDM1.00",
3777        "DEM1.00",
3778        "DEM1.00",
3779        "DJF1.00",
3780        "DKK1.00",
3781        "DOP1.00",
3782        "DZD1.00",
3783        "Danish Krone1.00",
3784        "Danish krone1.00",
3785        "Danish kroner1.00",
3786        "German Mark1.00",
3787        "German mark1.00",
3788        "German marks1.00",
3789        "Djiboutian Franc1.00",
3790        "Djiboutian franc1.00",
3791        "Djiboutian francs1.00",
3792        "Dominican Peso1.00",
3793        "Dominican peso1.00",
3794        "Dominican pesos1.00",
3795        "EC$1.00",
3796        "ECS1.00",
3797        "ECS1.00",
3798        "ECV1.00",
3799        "ECV1.00",
3800        "EEK1.00",
3801        "EEK1.00",
3802        "EGP1.00",
3803        "EGP1.00",
3804        "ERN1.00",
3805        "ERN1.00",
3806        "ESA1.00",
3807        "ESA1.00",
3808        "ESB1.00",
3809        "ESB1.00",
3810        "ESP1.00",
3811        "ETB1.00",
3812        "EUR1.00",
3813        "East Caribbean Dollar1.00",
3814        "East Caribbean dollar1.00",
3815        "East Caribbean dollars1.00",
3816        "East German Mark1.00",
3817        "East German mark1.00",
3818        "East German marks1.00",
3819        "Ecuadorian Sucre1.00",
3820        "Ecuadorian Unit of Constant Value1.00",
3821        "Ecuadorian sucre1.00",
3822        "Ecuadorian sucres1.00",
3823        "Ecuadorian unit of constant value1.00",
3824        "Ecuadorian units of constant value1.00",
3825        "Egyptian Pound1.00",
3826        "Egyptian pound1.00",
3827        "Egyptian pounds1.00",
3828        "Salvadoran Col\\u00f3n1.00",
3829        "Salvadoran col\\u00f3n1.00",
3830        "Salvadoran colones1.00",
3831        "Equatorial Guinean Ekwele1.00",
3832        "Equatorial Guinean ekwele1.00",
3833        "Eritrean Nakfa1.00",
3834        "Eritrean nakfa1.00",
3835        "Eritrean nakfas1.00",
3836        "Estonian Kroon1.00",
3837        "Estonian kroon1.00",
3838        "Estonian kroons1.00",
3839        "Ethiopian Birr1.00",
3840        "Ethiopian birr1.00",
3841        "Ethiopian birrs1.00",
3842        "Euro1.00",
3843        "European Composite Unit1.00",
3844        "European Currency Unit1.00",
3845        "European Monetary Unit1.00",
3846        "European Unit of Account (XBC)1.00",
3847        "European Unit of Account (XBD)1.00",
3848        "European composite unit1.00",
3849        "European composite units1.00",
3850        "European currency unit1.00",
3851        "European currency units1.00",
3852        "European monetary unit1.00",
3853        "European monetary units1.00",
3854        "European unit of account (XBC)1.00",
3855        "European unit of account (XBD)1.00",
3856        "European units of account (XBC)1.00",
3857        "European units of account (XBD)1.00",
3858        "FIM1.00",
3859        "FIM1.00",
3860        "FJD1.00",
3861        "FKP1.00",
3862        "FKP1.00",
3863        "FRF1.00",
3864        "FRF1.00",
3865        "Falkland Islands Pound1.00",
3866        "Falkland Islands pound1.00",
3867        "Falkland Islands pounds1.00",
3868        "Fijian Dollar1.00",
3869        "Fijian dollar1.00",
3870        "Fijian dollars1.00",
3871        "Finnish Markka1.00",
3872        "Finnish markka1.00",
3873        "Finnish markkas1.00",
3874        "CHF1.00",
3875        "French Franc1.00",
3876        "French Gold Franc1.00",
3877        "French UIC-Franc1.00",
3878        "French UIC-franc1.00",
3879        "French UIC-francs1.00",
3880        "French franc1.00",
3881        "French francs1.00",
3882        "French gold franc1.00",
3883        "French gold francs1.00",
3884        "GBP1.00",
3885        "GEK1.00",
3886        "GEK1.00",
3887        "GEL1.00",
3888        "GHC1.00",
3889        "GHC1.00",
3890        "GHS1.00",
3891        "GIP1.00",
3892        "GIP1.00",
3893        "GMD1.00",
3894        "GMD1.00",
3895        "GNF1.00",
3896        "GNS1.00",
3897        "GNS1.00",
3898        "GQE1.00",
3899        "GQE1.00",
3900        "GRD1.00",
3901        "GRD1.00",
3902        "GTQ1.00",
3903        "GWE1.00",
3904        "GWE1.00",
3905        "GWP1.00",
3906        "GWP1.00",
3907        "GYD1.00",
3908        "Gambian Dalasi1.00",
3909        "Gambian dalasi1.00",
3910        "Gambian dalasis1.00",
3911        "Georgian Kupon Larit1.00",
3912        "Georgian Lari1.00",
3913        "Georgian kupon larit1.00",
3914        "Georgian kupon larits1.00",
3915        "Georgian lari1.00",
3916        "Georgian laris1.00",
3917        "Ghanaian Cedi (1979-2007)1.00",
3918        "Ghanaian Cedi1.00",
3919        "Ghanaian cedi (1979-2007)1.00",
3920        "Ghanaian cedi1.00",
3921        "Ghanaian cedis (1979-2007)1.00",
3922        "Ghanaian cedis1.00",
3923        "Gibraltar Pound1.00",
3924        "Gibraltar pound1.00",
3925        "Gibraltar pounds1.00",
3926        "Gold1.00",
3927        "Gold1.00",
3928        "Greek Drachma1.00",
3929        "Greek drachma1.00",
3930        "Greek drachmas1.00",
3931        "Guatemalan Quetzal1.00",
3932        "Guatemalan quetzal1.00",
3933        "Guatemalan quetzals1.00",
3934        "Guinean Franc1.00",
3935        "Guinean Syli1.00",
3936        "Guinean franc1.00",
3937        "Guinean francs1.00",
3938        "Guinean syli1.00",
3939        "Guinean sylis1.00",
3940        "Guinea-Bissau Peso1.00",
3941        "Guinea-Bissau peso1.00",
3942        "Guinea-Bissau pesos1.00",
3943        "Guyanaese Dollar1.00",
3944        "Guyanaese dollar1.00",
3945        "Guyanaese dollars1.00",
3946        "HK$1.00",
3947        "HKD1.00",
3948        "HNL1.00",
3949        "HRD1.00",
3950        "HRD1.00",
3951        "HRK1.00",
3952        "HRK1.00",
3953        "HTG1.00",
3954        "HTG1.00",
3955        "HUF1.00",
3956        "Haitian Gourde1.00",
3957        "Haitian gourde1.00",
3958        "Haitian gourdes1.00",
3959        "Honduran Lempira1.00",
3960        "Honduran lempira1.00",
3961        "Honduran lempiras1.00",
3962        "Hong Kong Dollar1.00",
3963        "Hong Kong dollar1.00",
3964        "Hong Kong dollars1.00",
3965        "Hungarian Forint1.00",
3966        "Hungarian forint1.00",
3967        "Hungarian forints1.00",
3968        "IDR1.00",
3969        "IEP1.00",
3970        "ILP1.00",
3971        "ILP1.00",
3972        "ILS1.00",
3973        "INR1.00",
3974        "IQD1.00",
3975        "IRR1.00",
3976        "ISK1.00",
3977        "ISK1.00",
3978        "ITL1.00",
3979        "Icelandic Kr\\u00f3na1.00",
3980        "Icelandic kr\\u00f3na1.00",
3981        "Icelandic kr\\u00f3nur1.00",
3982        "Indian Rupee1.00",
3983        "Indian rupee1.00",
3984        "Indian rupees1.00",
3985        "Indonesian Rupiah1.00",
3986        "Indonesian rupiah1.00",
3987        "Indonesian rupiahs1.00",
3988        "Iranian Rial1.00",
3989        "Iranian rial1.00",
3990        "Iranian rials1.00",
3991        "Iraqi Dinar1.00",
3992        "Iraqi dinar1.00",
3993        "Iraqi dinars1.00",
3994        "Irish Pound1.00",
3995        "Irish pound1.00",
3996        "Irish pounds1.00",
3997        "Israeli Pound1.00",
3998        "Israeli new sheqel1.00",
3999        "Israeli pound1.00",
4000        "Israeli pounds1.00",
4001        "Italian Lira1.00",
4002        "Italian lira1.00",
4003        "Italian liras1.00",
4004        "JMD1.00",
4005        "JOD1.00",
4006        "JPY1.00",
4007        "Jamaican Dollar1.00",
4008        "Jamaican dollar1.00",
4009        "Jamaican dollars1.00",
4010        "Japanese Yen1.00",
4011        "Japanese yen1.00",
4012        "Jordanian Dinar1.00",
4013        "Jordanian dinar1.00",
4014        "Jordanian dinars1.00",
4015        "KES1.00",
4016        "KGS1.00",
4017        "KHR1.00",
4018        "KMF1.00",
4019        "KPW1.00",
4020        "KPW1.00",
4021        "KRW1.00",
4022        "KWD1.00",
4023        "KYD1.00",
4024        "KYD1.00",
4025        "KZT1.00",
4026        "Kazakhstani Tenge1.00",
4027        "Kazakhstani tenge1.00",
4028        "Kazakhstani tenges1.00",
4029        "Kenyan Shilling1.00",
4030        "Kenyan shilling1.00",
4031        "Kenyan shillings1.00",
4032        "Kuwaiti Dinar1.00",
4033        "Kuwaiti dinar1.00",
4034        "Kuwaiti dinars1.00",
4035        "Kyrgystani Som1.00",
4036        "Kyrgystani som1.00",
4037        "Kyrgystani soms1.00",
4038        "HNL1.00",
4039        "LAK1.00",
4040        "LAK1.00",
4041        "LBP1.00",
4042        "LKR1.00",
4043        "LRD1.00",
4044        "LRD1.00",
4045        "LSL1.00",
4046        "LTL1.00",
4047        "LTL1.00",
4048        "LTT1.00",
4049        "LTT1.00",
4050        "LUC1.00",
4051        "LUC1.00",
4052        "LUF1.00",
4053        "LUF1.00",
4054        "LUL1.00",
4055        "LUL1.00",
4056        "LVL1.00",
4057        "LVL1.00",
4058        "LVR1.00",
4059        "LVR1.00",
4060        "LYD1.00",
4061        "Laotian Kip1.00",
4062        "Laotian kip1.00",
4063        "Laotian kips1.00",
4064        "Latvian Lats1.00",
4065        "Latvian Ruble1.00",
4066        "Latvian lats1.00",
4067        "Latvian lati1.00",
4068        "Latvian ruble1.00",
4069        "Latvian rubles1.00",
4070        "Lebanese Pound1.00",
4071        "Lebanese pound1.00",
4072        "Lebanese pounds1.00",
4073        "Lesotho Loti1.00",
4074        "Lesotho loti1.00",
4075        "Lesotho lotis1.00",
4076        "Liberian Dollar1.00",
4077        "Liberian dollar1.00",
4078        "Liberian dollars1.00",
4079        "Libyan Dinar1.00",
4080        "Libyan dinar1.00",
4081        "Libyan dinars1.00",
4082        "Lithuanian Litas1.00",
4083        "Lithuanian Talonas1.00",
4084        "Lithuanian litas1.00",
4085        "Lithuanian litai1.00",
4086        "Lithuanian talonas1.00",
4087        "Lithuanian talonases1.00",
4088        "Luxembourgian Convertible Franc1.00",
4089        "Luxembourg Financial Franc1.00",
4090        "Luxembourgian Franc1.00",
4091        "Luxembourgian convertible franc1.00",
4092        "Luxembourgian convertible francs1.00",
4093        "Luxembourg financial franc1.00",
4094        "Luxembourg financial francs1.00",
4095        "Luxembourgian franc1.00",
4096        "Luxembourgian francs1.00",
4097        "MAD1.00",
4098        "MAD1.00",
4099        "MAF1.00",
4100        "MAF1.00",
4101        "MDL1.00",
4102        "MDL1.00",
4103        "MX$1.00",
4104        "MGA1.00",
4105        "MGA1.00",
4106        "MGF1.00",
4107        "MGF1.00",
4108        "MKD1.00",
4109        "MLF1.00",
4110        "MLF1.00",
4111        "MMK1.00",
4112        "MMK1.00",
4113        "MNT1.00",
4114        "MOP1.00",
4115        "MOP1.00",
4116        "MRO1.00",
4117        "MTL1.00",
4118        "MTP1.00",
4119        "MTP1.00",
4120        "MUR1.00",
4121        "MUR1.00",
4122        "MVR1.00",
4123        "MVR1.00",
4124        "MWK1.00",
4125        "MXN1.00",
4126        "MXP1.00",
4127        "MXP1.00",
4128        "MXV1.00",
4129        "MXV1.00",
4130        "MYR1.00",
4131        "MZE1.00",
4132        "MZE1.00",
4133        "MZM1.00",
4134        "MZN1.00",
4135        "Macanese Pataca1.00",
4136        "Macanese pataca1.00",
4137        "Macanese patacas1.00",
4138        "Macedonian Denar1.00",
4139        "Macedonian denar1.00",
4140        "Macedonian denari1.00",
4141        "Malagasy Ariaries1.00",
4142        "Malagasy Ariary1.00",
4143        "Malagasy Ariary1.00",
4144        "Malagasy Franc1.00",
4145        "Malagasy franc1.00",
4146        "Malagasy francs1.00",
4147        "Malawian Kwacha1.00",
4148        "Malawian Kwacha1.00",
4149        "Malawian Kwachas1.00",
4150        "Malaysian Ringgit1.00",
4151        "Malaysian ringgit1.00",
4152        "Malaysian ringgits1.00",
4153        "Maldivian Rufiyaa1.00",
4154        "Maldivian rufiyaa1.00",
4155        "Maldivian rufiyaas1.00",
4156        "Malian Franc1.00",
4157        "Malian franc1.00",
4158        "Malian francs1.00",
4159        "Maltese Lira1.00",
4160        "Maltese Pound1.00",
4161        "Maltese lira1.00",
4162        "Maltese lira1.00",
4163        "Maltese pound1.00",
4164        "Maltese pounds1.00",
4165        "Mauritanian Ouguiya1.00",
4166        "Mauritanian ouguiya1.00",
4167        "Mauritanian ouguiyas1.00",
4168        "Mauritian Rupee1.00",
4169        "Mauritian rupee1.00",
4170        "Mauritian rupees1.00",
4171        "Mexican Peso1.00",
4172        "Mexican Silver Peso (1861-1992)1.00",
4173        "Mexican Investment Unit1.00",
4174        "Mexican peso1.00",
4175        "Mexican pesos1.00",
4176        "Mexican silver peso (1861-1992)1.00",
4177        "Mexican silver pesos (1861-1992)1.00",
4178        "Mexican investment unit1.00",
4179        "Mexican investment units1.00",
4180        "Moldovan Leu1.00",
4181        "Moldovan leu1.00",
4182        "Moldovan lei1.00",
4183        "Mongolian Tugrik1.00",
4184        "Mongolian tugrik1.00",
4185        "Mongolian tugriks1.00",
4186        "Moroccan Dirham1.00",
4187        "Moroccan Franc1.00",
4188        "Moroccan dirham1.00",
4189        "Moroccan dirhams1.00",
4190        "Moroccan franc1.00",
4191        "Moroccan francs1.00",
4192        "Mozambican Escudo1.00",
4193        "Mozambican Metical1.00",
4194        "Mozambican escudo1.00",
4195        "Mozambican escudos1.00",
4196        "Mozambican metical1.00",
4197        "Mozambican meticals1.00",
4198        "Myanma Kyat1.00",
4199        "Myanma kyat1.00",
4200        "Myanma kyats1.00",
4201        "NAD1.00",
4202        "NGN1.00",
4203        "NIC1.00",
4204        "NIO1.00",
4205        "NIO1.00",
4206        "NLG1.00",
4207        "NLG1.00",
4208        "NOK1.00",
4209        "NPR1.00",
4210        "NT$1.00",
4211        "NZ$1.00",
4212        "NZD1.00",
4213        "Namibian Dollar1.00",
4214        "Namibian dollar1.00",
4215        "Namibian dollars1.00",
4216        "Nepalese Rupee1.00",
4217        "Nepalese rupee1.00",
4218        "Nepalese rupees1.00",
4219        "Netherlands Antillean Guilder1.00",
4220        "Netherlands Antillean guilder1.00",
4221        "Netherlands Antillean guilders1.00",
4222        "Dutch Guilder1.00",
4223        "Dutch guilder1.00",
4224        "Dutch guilders1.00",
4225        "Israeli New Sheqel1.00",
4226        "Israeli New Sheqels1.00",
4227        "New Zealand Dollar1.00",
4228        "New Zealand dollar1.00",
4229        "New Zealand dollars1.00",
4230        "Nicaraguan C\\u00f3rdoba1.00",
4231        "Nicaraguan C\\u00f3rdoba (1988-1991)1.00",
4232        "Nicaraguan c\\u00f3rdoba1.00",
4233        "Nicaraguan c\\u00f3rdobas1.00",
4234        "Nicaraguan c\\u00f3rdoba (1988-1991)1.00",
4235        "Nicaraguan c\\u00f3rdobas (1988-1991)1.00",
4236        "Nigerian Naira1.00",
4237        "Nigerian naira1.00",
4238        "Nigerian nairas1.00",
4239        "North Korean Won1.00",
4240        "North Korean won1.00",
4241        "North Korean won1.00",
4242        "Norwegian Krone1.00",
4243        "Norwegian krone1.00",
4244        "Norwegian kroner1.00",
4245        "OMR1.00",
4246        "Mozambican Metical (1980-2006)1.00",
4247        "Mozambican metical (1980-2006)1.00",
4248        "Mozambican meticals (1980-2006)1.00",
4249        "Romanian Lei (1952-2006)1.00",
4250        "Romanian Leu (1952-2006)1.00",
4251        "Romanian leu (1952-2006)1.00",
4252        "Serbian Dinar (2002-2006)1.00",
4253        "Serbian dinar (2002-2006)1.00",
4254        "Serbian dinars (2002-2006)1.00",
4255        "Sudanese Dinar (1992-2007)1.00",
4256        "Sudanese Pound (1957-1998)1.00",
4257        "Sudanese dinar (1992-2007)1.00",
4258        "Sudanese dinars (1992-2007)1.00",
4259        "Sudanese pound (1957-1998)1.00",
4260        "Sudanese pounds (1957-1998)1.00",
4261        "Turkish Lira (1922-2005)1.00",
4262        "Turkish Lira (1922-2005)1.00",
4263        "Omani Rial1.00",
4264        "Omani rial1.00",
4265        "Omani rials1.00",
4266        "PAB1.00",
4267        "PAB1.00",
4268        "PEI1.00",
4269        "PEI1.00",
4270        "PEN1.00",
4271        "PEN1.00",
4272        "PES1.00",
4273        "PES1.00",
4274        "PGK1.00",
4275        "PGK1.00",
4276        "PHP1.00",
4277        "PKR1.00",
4278        "PLN1.00",
4279        "PLZ1.00",
4280        "PLZ1.00",
4281        "PTE1.00",
4282        "PTE1.00",
4283        "PYG1.00",
4284        "Pakistani Rupee1.00",
4285        "Pakistani rupee1.00",
4286        "Pakistani rupees1.00",
4287        "Palladium1.00",
4288        "Palladium1.00",
4289        "Panamanian Balboa1.00",
4290        "Panamanian balboa1.00",
4291        "Panamanian balboas1.00",
4292        "Papua New Guinean Kina1.00",
4293        "Papua New Guinean kina1.00",
4294        "Papua New Guinean kina1.00",
4295        "Paraguayan Guarani1.00",
4296        "Paraguayan guarani1.00",
4297        "Paraguayan guaranis1.00",
4298        "Peruvian Inti1.00",
4299        "Peruvian Nuevo Sol1.00",
4300        "Peruvian Sol (1863-1965)1.00",
4301        "Peruvian inti1.00",
4302        "Peruvian intis1.00",
4303        "Peruvian nuevo sol1.00",
4304        "Peruvian nuevos soles1.00",
4305        "Peruvian sol (1863-1965)1.00",
4306        "Peruvian soles (1863-1965)1.00",
4307        "Philippine Peso1.00",
4308        "Philippine peso1.00",
4309        "Philippine pesos1.00",
4310        "Platinum1.00",
4311        "Platinum1.00",
4312        "Polish Zloty (1950-1995)1.00",
4313        "Polish Zloty1.00",
4314        "Polish zlotys1.00",
4315        "Polish zloty (PLZ)1.00",
4316        "Polish zloty1.00",
4317        "Polish zlotys (PLZ)1.00",
4318        "Portuguese Escudo1.00",
4319        "Portuguese Guinea Escudo1.00",
4320        "Portuguese Guinea escudo1.00",
4321        "Portuguese Guinea escudos1.00",
4322        "Portuguese escudo1.00",
4323        "Portuguese escudos1.00",
4324        "GTQ1.00",
4325        "QAR1.00",
4326        "Qatari Rial1.00",
4327        "Qatari rial1.00",
4328        "Qatari rials1.00",
4329        "RHD1.00",
4330        "RHD1.00",
4331        "RINET Funds1.00",
4332        "RINET Funds1.00",
4333        "CN\\u00a51.00",
4334        "ROL1.00",
4335        "ROL1.00",
4336        "RON1.00",
4337        "RON1.00",
4338        "RSD1.00",
4339        "RSD1.00",
4340        "RUB1.00",
4341        "RUB1.00",
4342        "RUR1.00",
4343        "RUR1.00",
4344        "RWF1.00",
4345        "RWF1.00",
4346        "Rhodesian Dollar1.00",
4347        "Rhodesian dollar1.00",
4348        "Rhodesian dollars1.00",
4349        "Romanian Leu1.00",
4350        "Romanian lei1.00",
4351        "Romanian leu1.00",
4352        "Russian Ruble (1991-1998)1.00",
4353        "Russian Ruble1.00",
4354        "Russian ruble (1991-1998)1.00",
4355        "Russian ruble1.00",
4356        "Russian rubles (1991-1998)1.00",
4357        "Russian rubles1.00",
4358        "Rwandan Franc1.00",
4359        "Rwandan franc1.00",
4360        "Rwandan francs1.00",
4361        "SAR1.00",
4362        "SBD1.00",
4363        "SCR1.00",
4364        "SDD1.00",
4365        "SDD1.00",
4366        "SDG1.00",
4367        "SDG1.00",
4368        "SDP1.00",
4369        "SDP1.00",
4370        "SEK1.00",
4371        "SGD1.00",
4372        "SHP1.00",
4373        "SHP1.00",
4374        "SIT1.00",
4375        "SIT1.00",
4376        "SKK1.00",
4377        "SLL1.00",
4378        "SLL1.00",
4379        "SOS1.00",
4380        "SRD1.00",
4381        "SRD1.00",
4382        "SRG1.00",
4383        "STD1.00",
4384        "SUR1.00",
4385        "SUR1.00",
4386        "SVC1.00",
4387        "SVC1.00",
4388        "SYP1.00",
4389        "SZL1.00",
4390        "Saint Helena Pound1.00",
4391        "Saint Helena pound1.00",
4392        "Saint Helena pounds1.00",
4393        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe Dobra1.00",
4394        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobra1.00",
4395        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobras1.00",
4396        "Saudi Riyal1.00",
4397        "Saudi riyal1.00",
4398        "Saudi riyals1.00",
4399        "Serbian Dinar1.00",
4400        "Serbian dinar1.00",
4401        "Serbian dinars1.00",
4402        "Seychellois Rupee1.00",
4403        "Seychellois rupee1.00",
4404        "Seychellois rupees1.00",
4405        "Sierra Leonean Leone1.00",
4406        "Sierra Leonean leone1.00",
4407        "Sierra Leonean leones1.00",
4408        "Silver1.00",
4409        "Silver1.00",
4410        "Singapore Dollar1.00",
4411        "Singapore dollar1.00",
4412        "Singapore dollars1.00",
4413        "Slovak Koruna1.00",
4414        "Slovak koruna1.00",
4415        "Slovak korunas1.00",
4416        "Slovenian Tolar1.00",
4417        "Slovenian tolar1.00",
4418        "Slovenian tolars1.00",
4419        "Solomon Islands Dollar1.00",
4420        "Solomon Islands dollar1.00",
4421        "Solomon Islands dollars1.00",
4422        "Somali Shilling1.00",
4423        "Somali shilling1.00",
4424        "Somali shillings1.00",
4425        "South African Rand (financial)1.00",
4426        "South African Rand1.00",
4427        "South African rand (financial)1.00",
4428        "South African rand1.00",
4429        "South African rands (financial)1.00",
4430        "South African rand1.00",
4431        "South Korean Won1.00",
4432        "South Korean won1.00",
4433        "South Korean won1.00",
4434        "Soviet Rouble1.00",
4435        "Soviet rouble1.00",
4436        "Soviet roubles1.00",
4437        "Spanish Peseta (A account)1.00",
4438        "Spanish Peseta (convertible account)1.00",
4439        "Spanish Peseta1.00",
4440        "Spanish peseta (A account)1.00",
4441        "Spanish peseta (convertible account)1.00",
4442        "Spanish peseta1.00",
4443        "Spanish pesetas (A account)1.00",
4444        "Spanish pesetas (convertible account)1.00",
4445        "Spanish pesetas1.00",
4446        "Special Drawing Rights1.00",
4447        "Sri Lankan Rupee1.00",
4448        "Sri Lankan rupee1.00",
4449        "Sri Lankan rupees1.00",
4450        "Sudanese Pound1.00",
4451        "Sudanese pound1.00",
4452        "Sudanese pounds1.00",
4453        "Surinamese Dollar1.00",
4454        "Surinamese dollar1.00",
4455        "Surinamese dollars1.00",
4456        "Surinamese Guilder1.00",
4457        "Surinamese guilder1.00",
4458        "Surinamese guilders1.00",
4459        "Swazi Lilangeni1.00",
4460        "Swazi lilangeni1.00",
4461        "Swazi emalangeni1.00",
4462        "Swedish Krona1.00",
4463        "Swedish krona1.00",
4464        "Swedish kronor1.00",
4465        "Swiss Franc1.00",
4466        "Swiss franc1.00",
4467        "Swiss francs1.00",
4468        "Syrian Pound1.00",
4469        "Syrian pound1.00",
4470        "Syrian pounds1.00",
4471        "THB1.00",
4472        "TJR1.00",
4473        "TJR1.00",
4474        "TJS1.00",
4475        "TJS1.00",
4476        "TMM1.00",
4477        "TMM1.00",
4478        "TND1.00",
4479        "TND1.00",
4480        "TOP1.00",
4481        "TPE1.00",
4482        "TPE1.00",
4483        "TRL1.00",
4484        "TRY1.00",
4485        "TRY1.00",
4486        "TTD1.00",
4487        "TWD1.00",
4488        "TZS1.00",
4489        "New Taiwan Dollar1.00",
4490        "New Taiwan dollar1.00",
4491        "New Taiwan dollars1.00",
4492        "Tajikistani Ruble1.00",
4493        "Tajikistani Somoni1.00",
4494        "Tajikistani ruble1.00",
4495        "Tajikistani rubles1.00",
4496        "Tajikistani somoni1.00",
4497        "Tajikistani somonis1.00",
4498        "Tanzanian Shilling1.00",
4499        "Tanzanian shilling1.00",
4500        "Tanzanian shillings1.00",
4501        "Testing Currency Code1.00",
4502        "Testing Currency Code1.00",
4503        "Thai Baht1.00",
4504        "Thai baht1.00",
4505        "Thai baht1.00",
4506        "Timorese Escudo1.00",
4507        "Timorese escudo1.00",
4508        "Timorese escudos1.00",
4509        "Tongan Pa\\u02bbanga1.00",
4510        "Tongan pa\\u02bbanga1.00",
4511        "Tongan pa\\u02bbanga1.00",
4512        "Trinidad and Tobago Dollar1.00",
4513        "Trinidad and Tobago dollar1.00",
4514        "Trinidad and Tobago dollars1.00",
4515        "Tunisian Dinar1.00",
4516        "Tunisian dinar1.00",
4517        "Tunisian dinars1.00",
4518        "Turkish Lira1.00",
4519        "Turkish Lira1.00",
4520        "Turkish lira1.00",
4521        "Turkmenistani Manat1.00",
4522        "Turkmenistani manat1.00",
4523        "Turkmenistani manat1.00",
4524        "UAE dirham1.00",
4525        "UAE dirhams1.00",
4526        "UAH1.00",
4527        "UAK1.00",
4528        "UAK1.00",
4529        "UGS1.00",
4530        "UGS1.00",
4531        "UGX1.00",
4532        "US Dollar (Next day)1.00",
4533        "US Dollar (Same day)1.00",
4534        "US Dollar1.00",
4535        "US dollar (next day)1.00",
4536        "US dollar (same day)1.00",
4537        "US dollar1.00",
4538        "US dollars (next day)1.00",
4539        "US dollars (same day)1.00",
4540        "US dollars1.00",
4541        "USD1.00",
4542        "USN1.00",
4543        "USN1.00",
4544        "USS1.00",
4545        "USS1.00",
4546        "UYI1.00",
4547        "UYI1.00",
4548        "UYP1.00",
4549        "UYP1.00",
4550        "UYU1.00",
4551        "UZS1.00",
4552        "UZS1.00",
4553        "Ugandan Shilling (1966-1987)1.00",
4554        "Ugandan Shilling1.00",
4555        "Ugandan shilling (1966-1987)1.00",
4556        "Ugandan shilling1.00",
4557        "Ugandan shillings (1966-1987)1.00",
4558        "Ugandan shillings1.00",
4559        "Ukrainian Hryvnia1.00",
4560        "Ukrainian Karbovanets1.00",
4561        "Ukrainian hryvnia1.00",
4562        "Ukrainian hryvnias1.00",
4563        "Ukrainian karbovanets1.00",
4564        "Ukrainian karbovantsiv1.00",
4565        "Colombian Real Value Unit1.00",
4566        "United Arab Emirates Dirham1.00",
4567        "Unknown Currency1.00",
4568        "Uruguayan Peso (1975-1993)1.00",
4569        "Uruguayan Peso1.00",
4570        "Uruguayan Peso (Indexed Units)1.00",
4571        "Uruguayan peso (1975-1993)1.00",
4572        "Uruguayan peso (indexed units)1.00",
4573        "Uruguayan peso1.00",
4574        "Uruguayan pesos (1975-1993)1.00",
4575        "Uruguayan pesos (indexed units)1.00",
4576        "Uruguayan pesos1.00",
4577        "Uzbekistan Som1.00",
4578        "Uzbekistan som1.00",
4579        "Uzbekistan som1.00",
4580        "VEB1.00",
4581        "VEF1.00",
4582        "VND1.00",
4583        "VUV1.00",
4584        "Vanuatu Vatu1.00",
4585        "Vanuatu vatu1.00",
4586        "Vanuatu vatus1.00",
4587        "Venezuelan Bol\\u00edvar1.00",
4588        "Venezuelan Bol\\u00edvar (1871-2008)1.00",
4589        "Venezuelan bol\\u00edvar1.00",
4590        "Venezuelan bol\\u00edvars1.00",
4591        "Venezuelan bol\\u00edvar (1871-2008)1.00",
4592        "Venezuelan bol\\u00edvars (1871-2008)1.00",
4593        "Vietnamese Dong1.00",
4594        "Vietnamese dong1.00",
4595        "Vietnamese dong1.00",
4596        "WIR Euro1.00",
4597        "WIR Franc1.00",
4598        "WIR euro1.00",
4599        "WIR euros1.00",
4600        "WIR franc1.00",
4601        "WIR francs1.00",
4602        "WST1.00",
4603        "WST1.00",
4604        "Samoan Tala1.00",
4605        "Samoan tala1.00",
4606        "Samoan tala1.00",
4607        "XAF1.00",
4608        "XAF1.00",
4609        "XAG1.00",
4610        "XAG1.00",
4611        "XAU1.00",
4612        "XAU1.00",
4613        "XBA1.00",
4614        "XBA1.00",
4615        "XBB1.00",
4616        "XBB1.00",
4617        "XBC1.00",
4618        "XBC1.00",
4619        "XBD1.00",
4620        "XBD1.00",
4621        "XCD1.00",
4622        "XDR1.00",
4623        "XDR1.00",
4624        "XEU1.00",
4625        "XEU1.00",
4626        "XFO1.00",
4627        "XFO1.00",
4628        "XFU1.00",
4629        "XFU1.00",
4630        "XOF1.00",
4631        "XOF1.00",
4632        "XPD1.00",
4633        "XPD1.00",
4634        "XPF1.00",
4635        "XPT1.00",
4636        "XPT1.00",
4637        "XRE1.00",
4638        "XRE1.00",
4639        "XTS1.00",
4640        "XTS1.00",
4641        "XXX1.00",
4642        "XXX1.00",
4643        "YDD1.00",
4644        "YDD1.00",
4645        "YER1.00",
4646        "YUD1.00",
4647        "YUD1.00",
4648        "YUM1.00",
4649        "YUM1.00",
4650        "YUN1.00",
4651        "YUN1.00",
4652        "Yemeni Dinar1.00",
4653        "Yemeni Rial1.00",
4654        "Yemeni dinar1.00",
4655        "Yemeni dinars1.00",
4656        "Yemeni rial1.00",
4657        "Yemeni rials1.00",
4658        "Yugoslavian Convertible Dinar (1990-1992)1.00",
4659        "Yugoslavian Hard Dinar (1966-1990)1.00",
4660        "Yugoslavian New Dinar (1994-2002)1.00",
4661        "Yugoslavian convertible dinar (1990-1992)1.00",
4662        "Yugoslavian convertible dinars (1990-1992)1.00",
4663        "Yugoslavian hard dinar (1966-1990)1.00",
4664        "Yugoslavian hard dinars (1966-1990)1.00",
4665        "Yugoslavian new dinar (1994-2002)1.00",
4666        "Yugoslavian new dinars (1994-2002)1.00",
4667        "ZAL1.00",
4668        "ZAL1.00",
4669        "ZAR1.00",
4670        "ZMK1.00",
4671        "ZMK1.00",
4672        "ZRN1.00",
4673        "ZRN1.00",
4674        "ZRZ1.00",
4675        "ZRZ1.00",
4676        "ZWD1.00",
4677        "Zairean New Zaire (1993-1998)1.00",
4678        "Zairean Zaire (1971-1993)1.00",
4679        "Zairean new zaire (1993-1998)1.00",
4680        "Zairean new zaires (1993-1998)1.00",
4681        "Zairean zaire (1971-1993)1.00",
4682        "Zairean zaires (1971-1993)1.00",
4683        "Zambian Kwacha1.00",
4684        "Zambian kwacha1.00",
4685        "Zambian kwachas1.00",
4686        "Zimbabwean Dollar (1980-2008)1.00",
4687        "Zimbabwean dollar (1980-2008)1.00",
4688        "Zimbabwean dollars (1980-2008)1.00",
4689        "euro1.00",
4690        "euros1.00",
4691        "Turkish lira (1922-2005)1.00",
4692        "special drawing rights1.00",
4693        "Colombian real value unit1.00",
4694        "Colombian real value units1.00",
4695        "unknown currency1.00",
4696        "\\u00a31.00",
4697        "\\u00a51.00",
4698        "\\u0e3f1.00",
4699        "\\u20ab1.00",
4700        "\\u20aa1.00",
4701        "\\u20ac1.00",
4702        "Rs.1.00",          // Google Patch: Indian Rupee symbol \u20B9 -> "Rs."
4703        //
4704        // Following has extra text, should be parsed correctly too
4705        "$1.00 random",
4706        "USD1.00 random",
4707        "1.00 US dollar random",
4708        "1.00 US dollars random",
4709        "1.00 Afghan Afghani random",
4710        "1.00 Afghan Afghani random",
4711        "1.00 Afghan Afghanis (1927-1992) random",
4712        "1.00 Afghan Afghanis random",
4713        "1.00 Albanian Lek random",
4714        "1.00 Albanian lek random",
4715        "1.00 Albanian lek\\u00eb random",
4716        "1.00 Algerian Dinar random",
4717        "1.00 Algerian dinar random",
4718        "1.00 Algerian dinars random",
4719        "1.00 Andorran Peseta random",
4720        "1.00 Andorran peseta random",
4721        "1.00 Andorran pesetas random",
4722        "1.00 Angolan Kwanza (1977-1990) random",
4723        "1.00 Angolan Readjusted Kwanza (1995-1999) random",
4724        "1.00 Angolan Kwanza random",
4725        "1.00 Angolan New Kwanza (1990-2000) random",
4726        "1.00 Angolan kwanza (1977-1991) random",
4727        "1.00 Angolan readjusted kwanza (1995-1999) random",
4728        "1.00 Angolan kwanza random",
4729        "1.00 Angolan kwanzas (1977-1991) random",
4730        "1.00 Angolan readjusted kwanzas (1995-1999) random",
4731        "1.00 Angolan kwanzas random",
4732        "1.00 Angolan new kwanza (1990-2000) random",
4733        "1.00 Angolan new kwanzas (1990-2000) random",
4734        "1.00 Argentine Austral random",
4735        "1.00 Argentine Peso (1983-1985) random",
4736        "1.00 Argentine Peso random",
4737        "1.00 Argentine austral random",
4738        "1.00 Argentine australs random",
4739        "1.00 Argentine peso (1983-1985) random",
4740        "1.00 Argentine peso random",
4741        "1.00 Argentine pesos (1983-1985) random",
4742        "1.00 Argentine pesos random",
4743        "1.00 Armenian Dram random",
4744        "1.00 Armenian dram random",
4745        "1.00 Armenian drams random",
4746        "1.00 Aruban Florin random",
4747        "1.00 Aruban florin random",
4748        "1.00 Australian Dollar random",
4749        "1.00 Australian dollar random",
4750        "1.00 Australian dollars random",
4751        "1.00 Austrian Schilling random",
4752        "1.00 Austrian schilling random",
4753        "1.00 Austrian schillings random",
4754        "1.00 Azerbaijani Manat (1993-2006) random",
4755        "1.00 Azerbaijani Manat random",
4756        "1.00 Azerbaijani manat (1993-2006) random",
4757        "1.00 Azerbaijani manat random",
4758        "1.00 Azerbaijani manats (1993-2006) random",
4759        "1.00 Azerbaijani manats random",
4760        "1.00 Bahamian Dollar random",
4761        "1.00 Bahamian dollar random",
4762        "1.00 Bahamian dollars random",
4763        "1.00 Bahraini Dinar random",
4764        "1.00 Bahraini dinar random",
4765        "1.00 Bahraini dinars random",
4766        "1.00 Bangladeshi Taka random",
4767        "1.00 Bangladeshi taka random",
4768        "1.00 Bangladeshi takas random",
4769        "1.00 Barbadian Dollar random",
4770        "1.00 Barbadian dollar random",
4771        "1.00 Barbadian dollars random",
4772        "1.00 Belarusian New Ruble (1994-1999) random",
4773        "1.00 Belarusian Ruble random",
4774        "1.00 Belarusian new ruble (1994-1999) random",
4775        "1.00 Belarusian new rubles (1994-1999) random",
4776        "1.00 Belarusian ruble random",
4777        "1.00 Belarusian rubles random",
4778        "1.00 Belgian Franc (convertible) random",
4779        "1.00 Belgian Franc (financial) random",
4780        "1.00 Belgian Franc random",
4781        "1.00 Belgian franc (convertible) random",
4782        "1.00 Belgian franc (financial) random",
4783        "1.00 Belgian franc random",
4784        "1.00 Belgian francs (convertible) random",
4785        "1.00 Belgian francs (financial) random",
4786        "1.00 Belgian francs random",
4787        "1.00 Belize Dollar random",
4788        "1.00 Belize dollar random",
4789        "1.00 Belize dollars random",
4790        "1.00 Bermudan Dollar random",
4791        "1.00 Bermudan dollar random",
4792        "1.00 Bermudan dollars random",
4793        "1.00 Bhutanese Ngultrum random",
4794        "1.00 Bhutanese ngultrum random",
4795        "1.00 Bhutanese ngultrums random",
4796        "1.00 Bolivian Mvdol random",
4797        "1.00 Bolivian Peso random",
4798        "1.00 Bolivian mvdol random",
4799        "1.00 Bolivian mvdols random",
4800        "1.00 Bolivian peso random",
4801        "1.00 Bolivian pesos random",
4802        "1.00 Bolivian Boliviano random",
4803        "1.00 Bolivian Boliviano random",
4804        "1.00 Bolivian Bolivianos random",
4805        "1.00 Bosnia-Herzegovina Convertible Mark random",
4806        "1.00 Bosnia-Herzegovina Dinar (1992-1994) random",
4807        "1.00 Bosnia-Herzegovina convertible mark random",
4808        "1.00 Bosnia-Herzegovina convertible marks random",
4809        "1.00 Bosnia-Herzegovina dinar (1992-1994) random",
4810        "1.00 Bosnia-Herzegovina dinars (1992-1994) random",
4811        "1.00 Botswanan Pula random",
4812        "1.00 Botswanan pula random",
4813        "1.00 Botswanan pulas random",
4814        "1.00 Brazilian New Cruzado (1989-1990) random",
4815        "1.00 Brazilian Cruzado (1986-1989) random",
4816        "1.00 Brazilian Cruzeiro (1990-1993) random",
4817        "1.00 Brazilian New Cruzeiro (1967-1986) random",
4818        "1.00 Brazilian Cruzeiro (1993-1994) random",
4819        "1.00 Brazilian Real random",
4820        "1.00 Brazilian new cruzado (1989-1990) random",
4821        "1.00 Brazilian new cruzados (1989-1990) random",
4822        "1.00 Brazilian cruzado (1986-1989) random",
4823        "1.00 Brazilian cruzados (1986-1989) random",
4824        "1.00 Brazilian cruzeiro (1990-1993) random",
4825        "1.00 Brazilian new cruzeiro (1967-1986) random",
4826        "1.00 Brazilian cruzeiro (1993-1994) random",
4827        "1.00 Brazilian cruzeiros (1990-1993) random",
4828        "1.00 Brazilian new cruzeiros (1967-1986) random",
4829        "1.00 Brazilian cruzeiros (1993-1994) random",
4830        "1.00 Brazilian real random",
4831        "1.00 Brazilian reals random",
4832        "1.00 British Pound Sterling random",
4833        "1.00 British pound sterling random",
4834        "1.00 British pounds sterling random",
4835        "1.00 Brunei Dollar random",
4836        "1.00 Brunei dollar random",
4837        "1.00 Brunei dollars random",
4838        "1.00 Bulgarian Hard Lev random",
4839        "1.00 Bulgarian Lev random",
4840        "1.00 Bulgarian Leva random",
4841        "1.00 Bulgarian hard lev random",
4842        "1.00 Bulgarian hard leva random",
4843        "1.00 Bulgarian lev random",
4844        "1.00 Burmese Kyat random",
4845        "1.00 Burmese kyat random",
4846        "1.00 Burmese kyats random",
4847        "1.00 Burundian Franc random",
4848        "1.00 Burundian franc random",
4849        "1.00 Burundian francs random",
4850        "1.00 Cambodian Riel random",
4851        "1.00 Cambodian riel random",
4852        "1.00 Cambodian riels random",
4853        "1.00 Canadian Dollar random",
4854        "1.00 Canadian dollar random",
4855        "1.00 Canadian dollars random",
4856        "1.00 Cape Verdean Escudo random",
4857        "1.00 Cape Verdean escudo random",
4858        "1.00 Cape Verdean escudos random",
4859        "1.00 Cayman Islands Dollar random",
4860        "1.00 Cayman Islands dollar random",
4861        "1.00 Cayman Islands dollars random",
4862        "1.00 Chilean Peso random",
4863        "1.00 Chilean Unit of Account (UF) random",
4864        "1.00 Chilean peso random",
4865        "1.00 Chilean pesos random",
4866        "1.00 Chilean unit of account (UF) random",
4867        "1.00 Chilean units of account (UF) random",
4868        "1.00 Chinese Yuan random",
4869        "1.00 Chinese yuan random",
4870        "1.00 Colombian Peso random",
4871        "1.00 Colombian peso random",
4872        "1.00 Colombian pesos random",
4873        "1.00 Comorian Franc random",
4874        "1.00 Comorian franc random",
4875        "1.00 Comorian francs random",
4876        "1.00 Congolese Franc Congolais random",
4877        "1.00 Congolese franc Congolais random",
4878        "1.00 Congolese francs Congolais random",
4879        "1.00 Costa Rican Col\\u00f3n random",
4880        "1.00 Costa Rican col\\u00f3n random",
4881        "1.00 Costa Rican col\\u00f3ns random",
4882        "1.00 Croatian Dinar random",
4883        "1.00 Croatian Kuna random",
4884        "1.00 Croatian dinar random",
4885        "1.00 Croatian dinars random",
4886        "1.00 Croatian kuna random",
4887        "1.00 Croatian kunas random",
4888        "1.00 Cuban Peso random",
4889        "1.00 Cuban peso random",
4890        "1.00 Cuban pesos random",
4891        "1.00 Cypriot Pound random",
4892        "1.00 Cypriot pound random",
4893        "1.00 Cypriot pounds random",
4894        "1.00 Czech Republic Koruna random",
4895        "1.00 Czech Republic koruna random",
4896        "1.00 Czech Republic korunas random",
4897        "1.00 Czechoslovak Hard Koruna random",
4898        "1.00 Czechoslovak hard koruna random",
4899        "1.00 Czechoslovak hard korunas random",
4900        "1.00 Danish Krone random",
4901        "1.00 Danish krone random",
4902        "1.00 Danish kroner random",
4903        "1.00 German Mark random",
4904        "1.00 German mark random",
4905        "1.00 German marks random",
4906        "1.00 Djiboutian Franc random",
4907        "1.00 Djiboutian franc random",
4908        "1.00 Djiboutian francs random",
4909        "1.00 Dominican Peso random",
4910        "1.00 Dominican peso random",
4911        "1.00 Dominican pesos random",
4912        "1.00 East Caribbean Dollar random",
4913        "1.00 East Caribbean dollar random",
4914        "1.00 East Caribbean dollars random",
4915        "1.00 East German Mark random",
4916        "1.00 East German mark random",
4917        "1.00 East German marks random",
4918        "1.00 Ecuadorian Sucre random",
4919        "1.00 Ecuadorian Unit of Constant Value random",
4920        "1.00 Ecuadorian sucre random",
4921        "1.00 Ecuadorian sucres random",
4922        "1.00 Ecuadorian unit of constant value random",
4923        "1.00 Ecuadorian units of constant value random",
4924        "1.00 Egyptian Pound random",
4925        "1.00 Egyptian pound random",
4926        "1.00 Egyptian pounds random",
4927        "1.00 Salvadoran Col\\u00f3n random",
4928        "1.00 Salvadoran col\\u00f3n random",
4929        "1.00 Salvadoran colones random",
4930        "1.00 Equatorial Guinean Ekwele random",
4931        "1.00 Equatorial Guinean ekwele random",
4932        "1.00 Eritrean Nakfa random",
4933        "1.00 Eritrean nakfa random",
4934        "1.00 Eritrean nakfas random",
4935        "1.00 Estonian Kroon random",
4936        "1.00 Estonian kroon random",
4937        "1.00 Estonian kroons random",
4938        "1.00 Ethiopian Birr random",
4939        "1.00 Ethiopian birr random",
4940        "1.00 Ethiopian birrs random",
4941        "1.00 European Composite Unit random",
4942        "1.00 European Currency Unit random",
4943        "1.00 European Monetary Unit random",
4944        "1.00 European Unit of Account (XBC) random",
4945        "1.00 European Unit of Account (XBD) random",
4946        "1.00 European composite unit random",
4947        "1.00 European composite units random",
4948        "1.00 European currency unit random",
4949        "1.00 European currency units random",
4950        "1.00 European monetary unit random",
4951        "1.00 European monetary units random",
4952        "1.00 European unit of account (XBC) random",
4953        "1.00 European unit of account (XBD) random",
4954        "1.00 European units of account (XBC) random",
4955        "1.00 European units of account (XBD) random",
4956        "1.00 Falkland Islands Pound random",
4957        "1.00 Falkland Islands pound random",
4958        "1.00 Falkland Islands pounds random",
4959        "1.00 Fijian Dollar random",
4960        "1.00 Fijian dollar random",
4961        "1.00 Fijian dollars random",
4962        "1.00 Finnish Markka random",
4963        "1.00 Finnish markka random",
4964        "1.00 Finnish markkas random",
4965        "1.00 French Franc random",
4966        "1.00 French Gold Franc random",
4967        "1.00 French UIC-Franc random",
4968        "1.00 French UIC-franc random",
4969        "1.00 French UIC-francs random",
4970        "1.00 French franc random",
4971        "1.00 French francs random",
4972        "1.00 French gold franc random",
4973        "1.00 French gold francs random",
4974        "1.00 Gambian Dalasi random",
4975        "1.00 Gambian dalasi random",
4976        "1.00 Gambian dalasis random",
4977        "1.00 Georgian Kupon Larit random",
4978        "1.00 Georgian Lari random",
4979        "1.00 Georgian kupon larit random",
4980        "1.00 Georgian kupon larits random",
4981        "1.00 Georgian lari random",
4982        "1.00 Georgian laris random",
4983        "1.00 Ghanaian Cedi (1979-2007) random",
4984        "1.00 Ghanaian Cedi random",
4985        "1.00 Ghanaian cedi (1979-2007) random",
4986        "1.00 Ghanaian cedi random",
4987        "1.00 Ghanaian cedis (1979-2007) random",
4988        "1.00 Ghanaian cedis random",
4989        "1.00 Gibraltar Pound random",
4990        "1.00 Gibraltar pound random",
4991        "1.00 Gibraltar pounds random",
4992        "1.00 Gold random",
4993        "1.00 Gold random",
4994        "1.00 Greek Drachma random",
4995        "1.00 Greek drachma random",
4996        "1.00 Greek drachmas random",
4997        "1.00 Guatemalan Quetzal random",
4998        "1.00 Guatemalan quetzal random",
4999        "1.00 Guatemalan quetzals random",
5000        "1.00 Guinean Franc random",
5001        "1.00 Guinean Syli random",
5002        "1.00 Guinean franc random",
5003        "1.00 Guinean francs random",
5004        "1.00 Guinean syli random",
5005        "1.00 Guinean sylis random",
5006        "1.00 Guinea-Bissau Peso random",
5007        "1.00 Guinea-Bissau peso random",
5008        "1.00 Guinea-Bissau pesos random",
5009        "1.00 Guyanaese Dollar random",
5010        "1.00 Guyanaese dollar random",
5011        "1.00 Guyanaese dollars random",
5012        "1.00 Haitian Gourde random",
5013        "1.00 Haitian gourde random",
5014        "1.00 Haitian gourdes random",
5015        "1.00 Honduran Lempira random",
5016        "1.00 Honduran lempira random",
5017        "1.00 Honduran lempiras random",
5018        "1.00 Hong Kong Dollar random",
5019        "1.00 Hong Kong dollar random",
5020        "1.00 Hong Kong dollars random",
5021        "1.00 Hungarian Forint random",
5022        "1.00 Hungarian forint random",
5023        "1.00 Hungarian forints random",
5024        "1.00 Icelandic Kr\\u00f3na random",
5025        "1.00 Icelandic kr\\u00f3na random",
5026        "1.00 Icelandic kr\\u00f3nur random",
5027        "1.00 Indian Rupee random",
5028        "1.00 Indian rupee random",
5029        "1.00 Indian rupees random",
5030        "1.00 Indonesian Rupiah random",
5031        "1.00 Indonesian rupiah random",
5032        "1.00 Indonesian rupiahs random",
5033        "1.00 Iranian Rial random",
5034        "1.00 Iranian rial random",
5035        "1.00 Iranian rials random",
5036        "1.00 Iraqi Dinar random",
5037        "1.00 Iraqi dinar random",
5038        "1.00 Iraqi dinars random",
5039        "1.00 Irish Pound random",
5040        "1.00 Irish pound random",
5041        "1.00 Irish pounds random",
5042        "1.00 Israeli Pound random",
5043        "1.00 Israeli new sheqel random",
5044        "1.00 Israeli pound random",
5045        "1.00 Israeli pounds random",
5046        "1.00 Italian Lira random",
5047        "1.00 Italian lira random",
5048        "1.00 Italian liras random",
5049        "1.00 Jamaican Dollar random",
5050        "1.00 Jamaican dollar random",
5051        "1.00 Jamaican dollars random",
5052        "1.00 Japanese Yen random",
5053        "1.00 Japanese yen random",
5054        "1.00 Jordanian Dinar random",
5055        "1.00 Jordanian dinar random",
5056        "1.00 Jordanian dinars random",
5057        "1.00 Kazakhstani Tenge random",
5058        "1.00 Kazakhstani tenge random",
5059        "1.00 Kazakhstani tenges random",
5060        "1.00 Kenyan Shilling random",
5061        "1.00 Kenyan shilling random",
5062        "1.00 Kenyan shillings random",
5063        "1.00 Kuwaiti Dinar random",
5064        "1.00 Kuwaiti dinar random",
5065        "1.00 Kuwaiti dinars random",
5066        "1.00 Kyrgystani Som random",
5067        "1.00 Kyrgystani som random",
5068        "1.00 Kyrgystani soms random",
5069        "1.00 Laotian Kip random",
5070        "1.00 Laotian kip random",
5071        "1.00 Laotian kips random",
5072        "1.00 Latvian Lats random",
5073        "1.00 Latvian Ruble random",
5074        "1.00 Latvian lats random",
5075        "1.00 Latvian lati random",
5076        "1.00 Latvian ruble random",
5077        "1.00 Latvian rubles random",
5078        "1.00 Lebanese Pound random",
5079        "1.00 Lebanese pound random",
5080        "1.00 Lebanese pounds random",
5081        "1.00 Lesotho Loti random",
5082        "1.00 Lesotho loti random",
5083        "1.00 Lesotho lotis random",
5084        "1.00 Liberian Dollar random",
5085        "1.00 Liberian dollar random",
5086        "1.00 Liberian dollars random",
5087        "1.00 Libyan Dinar random",
5088        "1.00 Libyan dinar random",
5089        "1.00 Libyan dinars random",
5090        "1.00 Lithuanian Litas random",
5091        "1.00 Lithuanian Talonas random",
5092        "1.00 Lithuanian litas random",
5093        "1.00 Lithuanian litai random",
5094        "1.00 Lithuanian talonas random",
5095        "1.00 Lithuanian talonases random",
5096        "1.00 Luxembourgian Convertible Franc random",
5097        "1.00 Luxembourg Financial Franc random",
5098        "1.00 Luxembourgian Franc random",
5099        "1.00 Luxembourgian convertible franc random",
5100        "1.00 Luxembourgian convertible francs random",
5101        "1.00 Luxembourg financial franc random",
5102        "1.00 Luxembourg financial francs random",
5103        "1.00 Luxembourgian franc random",
5104        "1.00 Luxembourgian francs random",
5105        "1.00 Macanese Pataca random",
5106        "1.00 Macanese pataca random",
5107        "1.00 Macanese patacas random",
5108        "1.00 Macedonian Denar random",
5109        "1.00 Macedonian denar random",
5110        "1.00 Macedonian denari random",
5111        "1.00 Malagasy Ariaries random",
5112        "1.00 Malagasy Ariary random",
5113        "1.00 Malagasy Ariary random",
5114        "1.00 Malagasy Franc random",
5115        "1.00 Malagasy franc random",
5116        "1.00 Malagasy francs random",
5117        "1.00 Malawian Kwacha random",
5118        "1.00 Malawian Kwacha random",
5119        "1.00 Malawian Kwachas random",
5120        "1.00 Malaysian Ringgit random",
5121        "1.00 Malaysian ringgit random",
5122        "1.00 Malaysian ringgits random",
5123        "1.00 Maldivian Rufiyaa random",
5124        "1.00 Maldivian rufiyaa random",
5125        "1.00 Maldivian rufiyaas random",
5126        "1.00 Malian Franc random",
5127        "1.00 Malian franc random",
5128        "1.00 Malian francs random",
5129        "1.00 Maltese Lira random",
5130        "1.00 Maltese Pound random",
5131        "1.00 Maltese lira random",
5132        "1.00 Maltese liras random",
5133        "1.00 Maltese pound random",
5134        "1.00 Maltese pounds random",
5135        "1.00 Mauritanian Ouguiya random",
5136        "1.00 Mauritanian ouguiya random",
5137        "1.00 Mauritanian ouguiyas random",
5138        "1.00 Mauritian Rupee random",
5139        "1.00 Mauritian rupee random",
5140        "1.00 Mauritian rupees random",
5141        "1.00 Mexican Peso random",
5142        "1.00 Mexican Silver Peso (1861-1992) random",
5143        "1.00 Mexican Investment Unit random",
5144        "1.00 Mexican peso random",
5145        "1.00 Mexican pesos random",
5146        "1.00 Mexican silver peso (1861-1992) random",
5147        "1.00 Mexican silver pesos (1861-1992) random",
5148        "1.00 Mexican investment unit random",
5149        "1.00 Mexican investment units random",
5150        "1.00 Moldovan Leu random",
5151        "1.00 Moldovan leu random",
5152        "1.00 Moldovan lei random",
5153        "1.00 Mongolian Tugrik random",
5154        "1.00 Mongolian tugrik random",
5155        "1.00 Mongolian tugriks random",
5156        "1.00 Moroccan Dirham random",
5157        "1.00 Moroccan Franc random",
5158        "1.00 Moroccan dirham random",
5159        "1.00 Moroccan dirhams random",
5160        "1.00 Moroccan franc random",
5161        "1.00 Moroccan francs random",
5162        "1.00 Mozambican Escudo random",
5163        "1.00 Mozambican Metical random",
5164        "1.00 Mozambican escudo random",
5165        "1.00 Mozambican escudos random",
5166        "1.00 Mozambican metical random",
5167        "1.00 Mozambican meticals random",
5168        "1.00 Myanma Kyat random",
5169        "1.00 Myanma kyat random",
5170        "1.00 Myanma kyats random",
5171        "1.00 Namibian Dollar random",
5172        "1.00 Namibian dollar random",
5173        "1.00 Namibian dollars random",
5174        "1.00 Nepalese Rupee random",
5175        "1.00 Nepalese rupee random",
5176        "1.00 Nepalese rupees random",
5177        "1.00 Netherlands Antillean Guilder random",
5178        "1.00 Netherlands Antillean guilder random",
5179        "1.00 Netherlands Antillean guilders random",
5180        "1.00 Dutch Guilder random",
5181        "1.00 Dutch guilder random",
5182        "1.00 Dutch guilders random",
5183        "1.00 Israeli New Sheqel random",
5184        "1.00 Israeli new sheqels random",
5185        "1.00 New Zealand Dollar random",
5186        "1.00 New Zealand dollar random",
5187        "1.00 New Zealand dollars random",
5188        "1.00 Nicaraguan C\\u00f3rdoba random",
5189        "1.00 Nicaraguan C\\u00f3rdoba (1988-1991) random",
5190        "1.00 Nicaraguan c\\u00f3rdoba random",
5191        "1.00 Nicaraguan c\\u00f3rdoba random",
5192        "1.00 Nicaraguan c\\u00f3rdoba (1988-1991) random",
5193        "1.00 Nicaraguan c\\u00f3rdobas (1988-1991) random",
5194        "1.00 Nigerian Naira random",
5195        "1.00 Nigerian naira random",
5196        "1.00 Nigerian nairas random",
5197        "1.00 North Korean Won random",
5198        "1.00 North Korean won random",
5199        "1.00 North Korean won random",
5200        "1.00 Norwegian Krone random",
5201        "1.00 Norwegian krone random",
5202        "1.00 Norwegian kroner random",
5203        "1.00 Mozambican Metical (1980-2006) random",
5204        "1.00 Mozambican metical (1980-2006) random",
5205        "1.00 Mozambican meticals (1980-2006) random",
5206        "1.00 Romanian Lei (1952-2006) random",
5207        "1.00 Romanian Leu (1952-2006) random",
5208        "1.00 Romanian leu (1952-2006) random",
5209        "1.00 Serbian Dinar (2002-2006) random",
5210        "1.00 Serbian dinar (2002-2006) random",
5211        "1.00 Serbian dinars (2002-2006) random",
5212        "1.00 Sudanese Dinar (1992-2007) random",
5213        "1.00 Sudanese Pound (1957-1998) random",
5214        "1.00 Sudanese dinar (1992-2007) random",
5215        "1.00 Sudanese dinars (1992-2007) random",
5216        "1.00 Sudanese pound (1957-1998) random",
5217        "1.00 Sudanese pounds (1957-1998) random",
5218        "1.00 Turkish Lira (1922-2005) random",
5219        "1.00 Turkish Lira (1922-2005) random",
5220        "1.00 Omani Rial random",
5221        "1.00 Omani rial random",
5222        "1.00 Omani rials random",
5223        "1.00 Pakistani Rupee random",
5224        "1.00 Pakistani rupee random",
5225        "1.00 Pakistani rupees random",
5226        "1.00 Palladium random",
5227        "1.00 Palladium random",
5228        "1.00 Panamanian Balboa random",
5229        "1.00 Panamanian balboa random",
5230        "1.00 Panamanian balboas random",
5231        "1.00 Papua New Guinean Kina random",
5232        "1.00 Papua New Guinean kina random",
5233        "1.00 Papua New Guinean kina random",
5234        "1.00 Paraguayan Guarani random",
5235        "1.00 Paraguayan guarani random",
5236        "1.00 Paraguayan guaranis random",
5237        "1.00 Peruvian Inti random",
5238        "1.00 Peruvian Nuevo Sol random",
5239        "1.00 Peruvian Sol (1863-1965) random",
5240        "1.00 Peruvian inti random",
5241        "1.00 Peruvian intis random",
5242        "1.00 Peruvian nuevo sol random",
5243        "1.00 Peruvian nuevos soles random",
5244        "1.00 Peruvian sol (1863-1965) random",
5245        "1.00 Peruvian soles (1863-1965) random",
5246        "1.00 Philippine Peso random",
5247        "1.00 Philippine peso random",
5248        "1.00 Philippine pesos random",
5249        "1.00 Platinum random",
5250        "1.00 Platinum random",
5251        "1.00 Polish Zloty (1950-1995) random",
5252        "1.00 Polish Zloty random",
5253        "1.00 Polish zlotys random",
5254        "1.00 Polish zloty (PLZ) random",
5255        "1.00 Polish zloty random",
5256        "1.00 Polish zlotys (PLZ) random",
5257        "1.00 Portuguese Escudo random",
5258        "1.00 Portuguese Guinea Escudo random",
5259        "1.00 Portuguese Guinea escudo random",
5260        "1.00 Portuguese Guinea escudos random",
5261        "1.00 Portuguese escudo random",
5262        "1.00 Portuguese escudos random",
5263        "1.00 Qatari Rial random",
5264        "1.00 Qatari rial random",
5265        "1.00 Qatari rials random",
5266        "1.00 RINET Funds random",
5267        "1.00 RINET Funds random",
5268        "1.00 Rhodesian Dollar random",
5269        "1.00 Rhodesian dollar random",
5270        "1.00 Rhodesian dollars random",
5271        "1.00 Romanian Leu random",
5272        "1.00 Romanian lei random",
5273        "1.00 Romanian leu random",
5274        "1.00 Russian Ruble (1991-1998) random",
5275        "1.00 Russian Ruble random",
5276        "1.00 Russian ruble (1991-1998) random",
5277        "1.00 Russian ruble random",
5278        "1.00 Russian rubles (1991-1998) random",
5279        "1.00 Russian rubles random",
5280        "1.00 Rwandan Franc random",
5281        "1.00 Rwandan franc random",
5282        "1.00 Rwandan francs random",
5283        "1.00 Saint Helena Pound random",
5284        "1.00 Saint Helena pound random",
5285        "1.00 Saint Helena pounds random",
5286        "1.00 S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe Dobra random",
5287        "1.00 S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobra random",
5288        "1.00 S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe dobras random",
5289        "1.00 Saudi Riyal random",
5290        "1.00 Saudi riyal random",
5291        "1.00 Saudi riyals random",
5292        "1.00 Serbian Dinar random",
5293        "1.00 Serbian dinar random",
5294        "1.00 Serbian dinars random",
5295        "1.00 Seychellois Rupee random",
5296        "1.00 Seychellois rupee random",
5297        "1.00 Seychellois rupees random",
5298        "1.00 Sierra Leonean Leone random",
5299        "1.00 Sierra Leonean leone random",
5300        "1.00 Sierra Leonean leones random",
5301        "1.00 Singapore Dollar random",
5302        "1.00 Singapore dollar random",
5303        "1.00 Singapore dollars random",
5304        "1.00 Slovak Koruna random",
5305        "1.00 Slovak koruna random",
5306        "1.00 Slovak korunas random",
5307        "1.00 Slovenian Tolar random",
5308        "1.00 Slovenian tolar random",
5309        "1.00 Slovenian tolars random",
5310        "1.00 Solomon Islands Dollar random",
5311        "1.00 Solomon Islands dollar random",
5312        "1.00 Solomon Islands dollars random",
5313        "1.00 Somali Shilling random",
5314        "1.00 Somali shilling random",
5315        "1.00 Somali shillings random",
5316        "1.00 South African Rand (financial) random",
5317        "1.00 South African Rand random",
5318        "1.00 South African rand (financial) random",
5319        "1.00 South African rand random",
5320        "1.00 South African rands (financial) random",
5321        "1.00 South African rand random",
5322        "1.00 South Korean Won random",
5323        "1.00 South Korean won random",
5324        "1.00 South Korean won random",
5325        "1.00 Soviet Rouble random",
5326        "1.00 Soviet rouble random",
5327        "1.00 Soviet roubles random",
5328        "1.00 Spanish Peseta (A account) random",
5329        "1.00 Spanish Peseta (convertible account) random",
5330        "1.00 Spanish Peseta random",
5331        "1.00 Spanish peseta (A account) random",
5332        "1.00 Spanish peseta (convertible account) random",
5333        "1.00 Spanish peseta random",
5334        "1.00 Spanish pesetas (A account) random",
5335        "1.00 Spanish pesetas (convertible account) random",
5336        "1.00 Spanish pesetas random",
5337        "1.00 Special Drawing Rights random",
5338        "1.00 Sri Lankan Rupee random",
5339        "1.00 Sri Lankan rupee random",
5340        "1.00 Sri Lankan rupees random",
5341        "1.00 Sudanese Pound random",
5342        "1.00 Sudanese pound random",
5343        "1.00 Sudanese pounds random",
5344        "1.00 Surinamese Dollar random",
5345        "1.00 Surinamese dollar random",
5346        "1.00 Surinamese dollars random",
5347        "1.00 Surinamese Guilder random",
5348        "1.00 Surinamese guilder random",
5349        "1.00 Surinamese guilders random",
5350        "1.00 Swazi Lilangeni random",
5351        "1.00 Swazi lilangeni random",
5352        "1.00 Swazi emalangeni random",
5353        "1.00 Swedish Krona random",
5354        "1.00 Swedish krona random",
5355        "1.00 Swedish kronor random",
5356        "1.00 Swiss Franc random",
5357        "1.00 Swiss franc random",
5358        "1.00 Swiss francs random",
5359        "1.00 Syrian Pound random",
5360        "1.00 Syrian pound random",
5361        "1.00 Syrian pounds random",
5362        "1.00 New Taiwan Dollar random",
5363        "1.00 New Taiwan dollar random",
5364        "1.00 New Taiwan dollars random",
5365        "1.00 Tajikistani Ruble random",
5366        "1.00 Tajikistani Somoni random",
5367        "1.00 Tajikistani ruble random",
5368        "1.00 Tajikistani rubles random",
5369        "1.00 Tajikistani somoni random",
5370        "1.00 Tajikistani somonis random",
5371        "1.00 Tanzanian Shilling random",
5372        "1.00 Tanzanian shilling random",
5373        "1.00 Tanzanian shillings random",
5374        "1.00 Testing Currency Code random",
5375        "1.00 Testing Currency Code random",
5376        "1.00 Thai Baht random",
5377        "1.00 Thai baht random",
5378        "1.00 Thai baht random",
5379        "1.00 Timorese Escudo random",
5380        "1.00 Timorese escudo random",
5381        "1.00 Timorese escudos random",
5382        "1.00 Trinidad and Tobago Dollar random",
5383        "1.00 Trinidad and Tobago dollar random",
5384        "1.00 Trinidad and Tobago dollars random",
5385        "1.00 Tunisian Dinar random",
5386        "1.00 Tunisian dinar random",
5387        "1.00 Tunisian dinars random",
5388        "1.00 Turkish Lira random",
5389        "1.00 Turkish Lira random",
5390        "1.00 Turkish lira random",
5391        "1.00 Turkmenistani Manat random",
5392        "1.00 Turkmenistani manat random",
5393        "1.00 Turkmenistani manat random",
5394        "1.00 US Dollar (Next day) random",
5395        "1.00 US Dollar (Same day) random",
5396        "1.00 US Dollar random",
5397        "1.00 US dollar (next day) random",
5398        "1.00 US dollar (same day) random",
5399        "1.00 US dollar random",
5400        "1.00 US dollars (next day) random",
5401        "1.00 US dollars (same day) random",
5402        "1.00 US dollars random",
5403        "1.00 Ugandan Shilling (1966-1987) random",
5404        "1.00 Ugandan Shilling random",
5405        "1.00 Ugandan shilling (1966-1987) random",
5406        "1.00 Ugandan shilling random",
5407        "1.00 Ugandan shillings (1966-1987) random",
5408        "1.00 Ugandan shillings random",
5409        "1.00 Ukrainian Hryvnia random",
5410        "1.00 Ukrainian Karbovanets random",
5411        "1.00 Ukrainian hryvnia random",
5412        "1.00 Ukrainian hryvnias random",
5413        "1.00 Ukrainian karbovanets random",
5414        "1.00 Ukrainian karbovantsiv random",
5415        "1.00 Colombian Real Value Unit random",
5416        "1.00 United Arab Emirates Dirham random",
5417        "1.00 Unknown Currency random",
5418        "1.00 Uruguayan Peso (1975-1993) random",
5419        "1.00 Uruguayan Peso random",
5420        "1.00 Uruguayan Peso (Indexed Units) random",
5421        "1.00 Uruguayan peso (1975-1993) random",
5422        "1.00 Uruguayan peso (indexed units) random",
5423        "1.00 Uruguayan peso random",
5424        "1.00 Uruguayan pesos (1975-1993) random",
5425        "1.00 Uruguayan pesos (indexed units) random",
5426        "1.00 Uzbekistan Som random",
5427        "1.00 Uzbekistan som random",
5428        "1.00 Uzbekistan som random",
5429        "1.00 Vanuatu Vatu random",
5430        "1.00 Vanuatu vatu random",
5431        "1.00 Vanuatu vatus random",
5432        "1.00 Venezuelan Bol\\u00edvar random",
5433        "1.00 Venezuelan Bol\\u00edvar (1871-2008) random",
5434        "1.00 Venezuelan bol\\u00edvar random",
5435        "1.00 Venezuelan bol\\u00edvars random",
5436        "1.00 Venezuelan bol\\u00edvar (1871-2008) random",
5437        "1.00 Venezuelan bol\\u00edvars (1871-2008) random",
5438        "1.00 Vietnamese Dong random",
5439        "1.00 Vietnamese dong random",
5440        "1.00 Vietnamese dong random",
5441        "1.00 WIR Euro random",
5442        "1.00 WIR Franc random",
5443        "1.00 WIR euro random",
5444        "1.00 WIR euros random",
5445        "1.00 WIR franc random",
5446        "1.00 WIR francs random",
5447        "1.00 Samoan Tala random",
5448        "1.00 Samoan tala random",
5449        "1.00 Samoan tala random",
5450        "1.00 Yemeni Dinar random",
5451        "1.00 Yemeni Rial random",
5452        "1.00 Yemeni dinar random",
5453        "1.00 Yemeni dinars random",
5454        "1.00 Yemeni rial random",
5455        "1.00 Yemeni rials random",
5456        "1.00 Yugoslavian Convertible Dinar (1990-1992) random",
5457        "1.00 Yugoslavian Hard Dinar (1966-1990) random",
5458        "1.00 Yugoslavian New Dinar (1994-2002) random",
5459        "1.00 Yugoslavian convertible dinar (1990-1992) random",
5460        "1.00 Yugoslavian convertible dinars (1990-1992) random",
5461        "1.00 Yugoslavian hard dinar (1966-1990) random",
5462        "1.00 Yugoslavian hard dinars (1966-1990) random",
5463        "1.00 Yugoslavian new dinar (1994-2002) random",
5464        "1.00 Yugoslavian new dinars (1994-2002) random",
5465        "1.00 Zairean New Zaire (1993-1998) random",
5466        "1.00 Zairean Zaire (1971-1993) random",
5467        "1.00 Zairean new zaire (1993-1998) random",
5468        "1.00 Zairean new zaires (1993-1998) random",
5469        "1.00 Zairean zaire (1971-1993) random",
5470        "1.00 Zairean zaires (1971-1993) random",
5471        "1.00 Zambian Kwacha random",
5472        "1.00 Zambian kwacha random",
5473        "1.00 Zambian kwachas random",
5474        "1.00 Zimbabwean Dollar (1980-2008) random",
5475        "1.00 Zimbabwean dollar (1980-2008) random",
5476        "1.00 Zimbabwean dollars (1980-2008) random",
5477        "1.00 euro random",
5478        "1.00 euros random",
5479        "1.00 Turkish lira (1922-2005) random",
5480        "1.00 special drawing rights random",
5481        "1.00 Colombian real value unit random",
5482        "1.00 Colombian real value units random",
5483        "1.00 unknown currency random",
5484    };
5485
5486    const char* WRONG_DATA[] = {
5487        // Following are missing one last char in the currency name
5488        "usd1.00", // case sensitive
5489        "1.00 Nicaraguan Cordob",
5490        "1.00 Namibian Dolla",
5491        "1.00 Namibian dolla",
5492        "1.00 Nepalese Rupe",
5493        "1.00 Nepalese rupe",
5494        "1.00 Netherlands Antillean Guilde",
5495        "1.00 Netherlands Antillean guilde",
5496        "1.00 Dutch Guilde",
5497        "1.00 Dutch guilde",
5498        "1.00 Israeli New Sheqe",
5499        "1.00 New Zealand Dolla",
5500        "1.00 New Zealand dolla",
5501        "1.00 Nicaraguan cordob",
5502        "1.00 Nigerian Nair",
5503        "1.00 Nigerian nair",
5504        "1.00 North Korean Wo",
5505        "1.00 North Korean wo",
5506        "1.00 Norwegian Kron",
5507        "1.00 Norwegian kron",
5508        "1.00 US dolla",
5509        "1.00",
5510        "A1.00",
5511        "AD1.00",
5512        "AE1.00",
5513        "AF1.00",
5514        "AL1.00",
5515        "AM1.00",
5516        "AN1.00",
5517        "AO1.00",
5518        "AR1.00",
5519        "AT1.00",
5520        "AU1.00",
5521        "AW1.00",
5522        "AZ1.00",
5523        "Afghan Afghan1.00",
5524        "Afghan Afghani (1927-20021.00",
5525        "Afl1.00",
5526        "Albanian Le1.00",
5527        "Algerian Dina1.00",
5528        "Andorran Peset1.00",
5529        "Angolan Kwanz1.00",
5530        "Angolan Kwanza (1977-19901.00",
5531        "Angolan Readjusted Kwanza (1995-19991.00",
5532        "Angolan New Kwanza (1990-20001.00",
5533        "Argentine Austra1.00",
5534        "Argentine Pes1.00",
5535        "Argentine Peso (1983-19851.00",
5536        "Armenian Dra1.00",
5537        "Aruban Flori1.00",
5538        "Australian Dolla1.00",
5539        "Austrian Schillin1.00",
5540        "Azerbaijani Mana1.00",
5541        "Azerbaijani Manat (1993-20061.00",
5542        "B1.00",
5543        "BA1.00",
5544        "BB1.00",
5545        "BE1.00",
5546        "BG1.00",
5547        "BH1.00",
5548        "BI1.00",
5549        "BM1.00",
5550        "BN1.00",
5551        "BO1.00",
5552        "BR1.00",
5553        "BS1.00",
5554        "BT1.00",
5555        "BU1.00",
5556        "BW1.00",
5557        "BY1.00",
5558        "BZ1.00",
5559        "Bahamian Dolla1.00",
5560        "Bahraini Dina1.00",
5561        "Bangladeshi Tak1.00",
5562        "Barbadian Dolla1.00",
5563        "Bds1.00",
5564        "Belarusian New Ruble (1994-19991.00",
5565        "Belarusian Rubl1.00",
5566        "Belgian Fran1.00",
5567        "Belgian Franc (convertible1.00",
5568        "Belgian Franc (financial1.00",
5569        "Belize Dolla1.00",
5570        "Bermudan Dolla1.00",
5571        "Bhutanese Ngultru1.00",
5572        "Bolivian Mvdo1.00",
5573        "Bolivian Pes1.00",
5574        "Bolivian Bolivian1.00",
5575        "Bosnia-Herzegovina Convertible Mar1.00",
5576        "Bosnia-Herzegovina Dina1.00",
5577        "Botswanan Pul1.00",
5578        "Brazilian Cruzad1.00",
5579        "Brazilian Cruzado Nov1.00",
5580        "Brazilian Cruzeir1.00",
5581        "Brazilian Cruzeiro (1990-19931.00",
5582        "Brazilian New Cruzeiro (1967-19861.00",
5583        "Brazilian Rea1.00",
5584        "British Pound Sterlin1.00",
5585        "Brunei Dolla1.00",
5586        "Bulgarian Hard Le1.00",
5587        "Bulgarian Le1.00",
5588        "Burmese Kya1.00",
5589        "Burundian Fran1.00",
5590        "C1.00",
5591        "CA1.00",
5592        "CD1.00",
5593        "CFA Franc BCEA1.00",
5594        "CFA Franc BEA1.00",
5595        "CFP Fran1.00",
5596        "CFP1.00",
5597        "CH1.00",
5598        "CL1.00",
5599        "CN1.00",
5600        "CO1.00",
5601        "CS1.00",
5602        "CU1.00",
5603        "CV1.00",
5604        "CY1.00",
5605        "CZ1.00",
5606        "Cambodian Rie1.00",
5607        "Canadian Dolla1.00",
5608        "Cape Verdean Escud1.00",
5609        "Cayman Islands Dolla1.00",
5610        "Chilean Pes1.00",
5611        "Chilean Unit of Accoun1.00",
5612        "Chinese Yua1.00",
5613        "Colombian Pes1.00",
5614        "Comoro Fran1.00",
5615        "Congolese Fran1.00",
5616        "Costa Rican Col\\u00f31.00",
5617        "Croatian Dina1.00",
5618        "Croatian Kun1.00",
5619        "Cuban Pes1.00",
5620        "Cypriot Poun1.00",
5621        "Czech Republic Korun1.00",
5622        "Czechoslovak Hard Korun1.00",
5623        "D1.00",
5624        "DD1.00",
5625        "DE1.00",
5626        "DJ1.00",
5627        "DK1.00",
5628        "DO1.00",
5629        "DZ1.00",
5630        "Danish Kron1.00",
5631        "German Mar1.00",
5632        "Djiboutian Fran1.00",
5633        "Dk1.00",
5634        "Dominican Pes1.00",
5635        "EC1.00",
5636        "EE1.00",
5637        "EG1.00",
5638        "EQ1.00",
5639        "ER1.00",
5640        "ES1.00",
5641        "ET1.00",
5642        "EU1.00",
5643        "East Caribbean Dolla1.00",
5644        "East German Ostmar1.00",
5645        "Ecuadorian Sucr1.00",
5646        "Ecuadorian Unit of Constant Valu1.00",
5647        "Egyptian Poun1.00",
5648        "Ekwel1.00",
5649        "Salvadoran Col\\u00f31.00",
5650        "Equatorial Guinean Ekwel1.00",
5651        "Eritrean Nakf1.00",
5652        "Es1.00",
5653        "Estonian Kroo1.00",
5654        "Ethiopian Bir1.00",
5655        "Eur1.00",
5656        "European Composite Uni1.00",
5657        "European Currency Uni1.00",
5658        "European Monetary Uni1.00",
5659        "European Unit of Account (XBC1.00",
5660        "European Unit of Account (XBD1.00",
5661        "F1.00",
5662        "FB1.00",
5663        "FI1.00",
5664        "FJ1.00",
5665        "FK1.00",
5666        "FR1.00",
5667        "Falkland Islands Poun1.00",
5668        "Fd1.00",
5669        "Fijian Dolla1.00",
5670        "Finnish Markk1.00",
5671        "Fr1.00",
5672        "French Fran1.00",
5673        "French Gold Fran1.00",
5674        "French UIC-Fran1.00",
5675        "G1.00",
5676        "GB1.00",
5677        "GE1.00",
5678        "GH1.00",
5679        "GI1.00",
5680        "GM1.00",
5681        "GN1.00",
5682        "GQ1.00",
5683        "GR1.00",
5684        "GT1.00",
5685        "GW1.00",
5686        "GY1.00",
5687        "Gambian Dalas1.00",
5688        "Georgian Kupon Lari1.00",
5689        "Georgian Lar1.00",
5690        "Ghanaian Ced1.00",
5691        "Ghanaian Cedi (1979-20071.00",
5692        "Gibraltar Poun1.00",
5693        "Gol1.00",
5694        "Greek Drachm1.00",
5695        "Guatemalan Quetza1.00",
5696        "Guinean Fran1.00",
5697        "Guinean Syl1.00",
5698        "Guinea-Bissau Pes1.00",
5699        "Guyanaese Dolla1.00",
5700        "HK1.00",
5701        "HN1.00",
5702        "HR1.00",
5703        "HT1.00",
5704        "HU1.00",
5705        "Haitian Gourd1.00",
5706        "Honduran Lempir1.00",
5707        "Hong Kong Dolla1.00",
5708        "Hungarian Forin1.00",
5709        "I1.00",
5710        "IE1.00",
5711        "IL1.00",
5712        "IN1.00",
5713        "IQ1.00",
5714        "IR1.00",
5715        "IS1.00",
5716        "IT1.00",
5717        "Icelandic Kron1.00",
5718        "Indian Rupe1.00",
5719        "Indonesian Rupia1.00",
5720        "Iranian Ria1.00",
5721        "Iraqi Dina1.00",
5722        "Irish Poun1.00",
5723        "Israeli Poun1.00",
5724        "Italian Lir1.00",
5725        "J1.00",
5726        "JM1.00",
5727        "JO1.00",
5728        "JP1.00",
5729        "Jamaican Dolla1.00",
5730        "Japanese Ye1.00",
5731        "Jordanian Dina1.00",
5732        "K S1.00",
5733        "K1.00",
5734        "KE1.00",
5735        "KG1.00",
5736        "KH1.00",
5737        "KP1.00",
5738        "KR1.00",
5739        "KW1.00",
5740        "KY1.00",
5741        "KZ1.00",
5742        "Kazakhstani Teng1.00",
5743        "Kenyan Shillin1.00",
5744        "Kuwaiti Dina1.00",
5745        "Kyrgystani So1.00",
5746        "LA1.00",
5747        "LB1.00",
5748        "LK1.00",
5749        "LR1.00",
5750        "LT1.00",
5751        "LU1.00",
5752        "LV1.00",
5753        "LY1.00",
5754        "Laotian Ki1.00",
5755        "Latvian Lat1.00",
5756        "Latvian Rubl1.00",
5757        "Lebanese Poun1.00",
5758        "Lesotho Lot1.00",
5759        "Liberian Dolla1.00",
5760        "Libyan Dina1.00",
5761        "Lithuanian Lit1.00",
5762        "Lithuanian Talona1.00",
5763        "Luxembourgian Convertible Fran1.00",
5764        "Luxembourg Financial Fran1.00",
5765        "Luxembourgian Fran1.00",
5766        "MA1.00",
5767        "MD1.00",
5768        "MDe1.00",
5769        "MEX1.00",
5770        "MG1.00",
5771        "ML1.00",
5772        "MM1.00",
5773        "MN1.00",
5774        "MO1.00",
5775        "MR1.00",
5776        "MT1.00",
5777        "MU1.00",
5778        "MV1.00",
5779        "MW1.00",
5780        "MX1.00",
5781        "MY1.00",
5782        "MZ1.00",
5783        "Macanese Patac1.00",
5784        "Macedonian Dena1.00",
5785        "Malagasy Ariar1.00",
5786        "Malagasy Fran1.00",
5787        "Malawian Kwach1.00",
5788        "Malaysian Ringgi1.00",
5789        "Maldivian Rufiya1.00",
5790        "Malian Fran1.00",
5791        "Malot1.00",
5792        "Maltese Lir1.00",
5793        "Maltese Poun1.00",
5794        "Mauritanian Ouguiy1.00",
5795        "Mauritian Rupe1.00",
5796        "Mexican Pes1.00",
5797        "Mexican Silver Peso (1861-19921.00",
5798        "Mexican Investment Uni1.00",
5799        "Moldovan Le1.00",
5800        "Mongolian Tugri1.00",
5801        "Moroccan Dirha1.00",
5802        "Moroccan Fran1.00",
5803        "Mozambican Escud1.00",
5804        "Mozambican Metica1.00",
5805        "Myanma Kya1.00",
5806        "N1.00",
5807        "NA1.00",
5808        "NAf1.00",
5809        "NG1.00",
5810        "NI1.00",
5811        "NK1.00",
5812        "NL1.00",
5813        "NO1.00",
5814        "NP1.00",
5815        "NT1.00",
5816        "Namibian Dolla1.00",
5817        "Nepalese Rupe1.00",
5818        "Netherlands Antillean Guilde1.00",
5819        "Dutch Guilde1.00",
5820        "Israeli New Sheqe1.00",
5821        "New Zealand Dolla1.00",
5822        "Nicaraguan C\\u00f3rdoba (1988-19911.00",
5823        "Nicaraguan C\\u00f3rdob1.00",
5824        "Nigerian Nair1.00",
5825        "North Korean Wo1.00",
5826        "Norwegian Kron1.00",
5827        "Nr1.00",
5828        "OM1.00",
5829        "Old Mozambican Metica1.00",
5830        "Romanian Leu (1952-20061.00",
5831        "Serbian Dinar (2002-20061.00",
5832        "Sudanese Dinar (1992-20071.00",
5833        "Sudanese Pound (1957-19981.00",
5834        "Turkish Lira (1922-20051.00",
5835        "Omani Ria1.00",
5836        "PA1.00",
5837        "PE1.00",
5838        "PG1.00",
5839        "PH1.00",
5840        "PK1.00",
5841        "PL1.00",
5842        "PT1.00",
5843        "PY1.00",
5844        "Pakistani Rupe1.00",
5845        "Palladiu1.00",
5846        "Panamanian Balbo1.00",
5847        "Papua New Guinean Kin1.00",
5848        "Paraguayan Guaran1.00",
5849        "Peruvian Int1.00",
5850        "Peruvian Sol (1863-19651.00",
5851        "Peruvian Sol Nuev1.00",
5852        "Philippine Pes1.00",
5853        "Platinu1.00",
5854        "Polish Zlot1.00",
5855        "Polish Zloty (1950-19951.00",
5856        "Portuguese Escud1.00",
5857        "Portuguese Guinea Escud1.00",
5858        "Pr1.00",
5859        "QA1.00",
5860        "Qatari Ria1.00",
5861        "RD1.00",
5862        "RH1.00",
5863        "RINET Fund1.00",
5864        "RS1.00",
5865        "RU1.00",
5866        "RW1.00",
5867        "Rb1.00",
5868        "Rhodesian Dolla1.00",
5869        "Romanian Le1.00",
5870        "Russian Rubl1.00",
5871        "Russian Ruble (1991-19981.00",
5872        "Rwandan Fran1.00",
5873        "S1.00",
5874        "SA1.00",
5875        "SB1.00",
5876        "SC1.00",
5877        "SD1.00",
5878        "SE1.00",
5879        "SG1.00",
5880        "SH1.00",
5881        "SI1.00",
5882        "SK1.00",
5883        "SL R1.00",
5884        "SL1.00",
5885        "SO1.00",
5886        "ST1.00",
5887        "SU1.00",
5888        "SV1.00",
5889        "SY1.00",
5890        "SZ1.00",
5891        "Saint Helena Poun1.00",
5892        "S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe Dobr1.00",
5893        "Saudi Riya1.00",
5894        "Serbian Dina1.00",
5895        "Seychellois Rupe1.00",
5896        "Sh1.00",
5897        "Sierra Leonean Leon1.00",
5898        "Silve1.00",
5899        "Singapore Dolla1.00",
5900        "Slovak Korun1.00",
5901        "Slovenian Tola1.00",
5902        "Solomon Islands Dolla1.00",
5903        "Somali Shillin1.00",
5904        "South African Ran1.00",
5905        "South African Rand (financial1.00",
5906        "South Korean Wo1.00",
5907        "Soviet Roubl1.00",
5908        "Spanish Peset1.00",
5909        "Spanish Peseta (A account1.00",
5910        "Spanish Peseta (convertible account1.00",
5911        "Special Drawing Right1.00",
5912        "Sri Lankan Rupe1.00",
5913        "Sudanese Poun1.00",
5914        "Surinamese Dolla1.00",
5915        "Surinamese Guilde1.00",
5916        "Swazi Lilangen1.00",
5917        "Swedish Kron1.00",
5918        "Swiss Fran1.00",
5919        "Syrian Poun1.00",
5920        "T S1.00",
5921        "TH1.00",
5922        "TJ1.00",
5923        "TM1.00",
5924        "TN1.00",
5925        "TO1.00",
5926        "TP1.00",
5927        "TR1.00",
5928        "TT1.00",
5929        "TW1.00",
5930        "TZ1.00",
5931        "New Taiwan Dolla1.00",
5932        "Tajikistani Rubl1.00",
5933        "Tajikistani Somon1.00",
5934        "Tanzanian Shillin1.00",
5935        "Testing Currency Cod1.00",
5936        "Thai Bah1.00",
5937        "Timorese Escud1.00",
5938        "Tongan Pa\\u20bbang1.00",
5939        "Trinidad and Tobago Dolla1.00",
5940        "Tunisian Dina1.00",
5941        "Turkish Lir1.00",
5942        "Turkmenistani Mana1.00",
5943        "U S1.00",
5944        "U1.00",
5945        "UA1.00",
5946        "UG1.00",
5947        "US Dolla1.00",
5948        "US Dollar (Next day1.00",
5949        "US Dollar (Same day1.00",
5950        "US1.00",
5951        "UY1.00",
5952        "UZ1.00",
5953        "Ugandan Shillin1.00",
5954        "Ugandan Shilling (1966-19871.00",
5955        "Ukrainian Hryvni1.00",
5956        "Ukrainian Karbovanet1.00",
5957        "Colombian Real Value Uni1.00",
5958        "United Arab Emirates Dirha1.00",
5959        "Unknown Currenc1.00",
5960        "Ur1.00",
5961        "Uruguay Peso (1975-19931.00",
5962        "Uruguay Peso Uruguay1.00",
5963        "Uruguay Peso (Indexed Units1.00",
5964        "Uzbekistan So1.00",
5965        "V1.00",
5966        "VE1.00",
5967        "VN1.00",
5968        "VU1.00",
5969        "Vanuatu Vat1.00",
5970        "Venezuelan Bol\\u00edva1.00",
5971        "Venezuelan Bol\\u00edvar Fuert1.00",
5972        "Vietnamese Don1.00",
5973        "WIR Eur1.00",
5974        "WIR Fran1.00",
5975        "WS1.00",
5976        "Samoa Tal1.00",
5977        "XA1.00",
5978        "XB1.00",
5979        "XC1.00",
5980        "XD1.00",
5981        "XE1.00",
5982        "XF1.00",
5983        "XO1.00",
5984        "XP1.00",
5985        "XR1.00",
5986        "XT1.00",
5987        "XX1.00",
5988        "YD1.00",
5989        "YE1.00",
5990        "YU1.00",
5991        "Yemeni Dina1.00",
5992        "Yemeni Ria1.00",
5993        "Yugoslavian Convertible Dina1.00",
5994        "Yugoslavian Hard Dinar (1966-19901.00",
5995        "Yugoslavian New Dina1.00",
5996        "Z1.00",
5997        "ZA1.00",
5998        "ZM1.00",
5999        "ZR1.00",
6000        "ZW1.00",
6001        "Zairean New Zaire (1993-19981.00",
6002        "Zairean Zair1.00",
6003        "Zambian Kwach1.00",
6004        "Zimbabwean Dollar (1980-20081.00",
6005        "dra1.00",
6006        "lar1.00",
6007        "le1.00",
6008        "man1.00",
6009        "so1.00",
6010    };
6011
6012    Locale locale("en_US");
6013    for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) {
6014      UnicodeString formatted = ctou(DATA[i]);
6015      UErrorCode status = U_ZERO_ERROR;
6016      NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6017      if (numFmt != NULL && U_SUCCESS(status)) {
6018          ParsePosition parsePos;
6019          LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
6020          if (parsePos.getIndex() > 0) {
6021              double doubleVal = currAmt->getNumber().getDouble(status);
6022              if ( doubleVal != 1.0 ) {
6023                  errln("Parsed as currency value other than 1.0: " + formatted + " -> " + doubleVal);
6024              }
6025          } else {
6026              errln("Failed to parse as currency: " + formatted);
6027          }
6028      } else {
6029          dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6030          delete numFmt;
6031          break;
6032      }
6033      delete numFmt;
6034    }
6035
6036    for (uint32_t i=0; i<sizeof(WRONG_DATA)/sizeof(WRONG_DATA[0]); ++i) {
6037      UnicodeString formatted = ctou(WRONG_DATA[i]);
6038      UErrorCode status = U_ZERO_ERROR;
6039      NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6040      if (numFmt != NULL && U_SUCCESS(status)) {
6041          ParsePosition parsePos;
6042          LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
6043          if (parsePos.getIndex() > 0) {
6044              double doubleVal = currAmt->getNumber().getDouble(status);
6045              errln("Parsed as currency, should not have: " + formatted + " -> " + doubleVal);
6046          }
6047      } else {
6048          dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6049          delete numFmt;
6050          break;
6051      }
6052      delete numFmt;
6053    }
6054}
6055
6056const char* attrString(int32_t);
6057
6058// UnicodeString s;
6059//  std::string ss;
6060//  std::cout << s.toUTF8String(ss)
6061void NumberFormatTest::expectPositions(FieldPositionIterator& iter, int32_t *values, int32_t tupleCount,
6062                                       const UnicodeString& str)  {
6063  UBool found[10];
6064  FieldPosition fp;
6065
6066  if (tupleCount > 10) {
6067    assertTrue("internal error, tupleCount too large", FALSE);
6068  } else {
6069    for (int i = 0; i < tupleCount; ++i) {
6070      found[i] = FALSE;
6071    }
6072  }
6073
6074  logln(str);
6075  while (iter.next(fp)) {
6076    UBool ok = FALSE;
6077    int32_t id = fp.getField();
6078    int32_t start = fp.getBeginIndex();
6079    int32_t limit = fp.getEndIndex();
6080
6081    // is there a logln using printf?
6082    char buf[128];
6083    sprintf(buf, "%24s %3d %3d %3d", attrString(id), id, start, limit);
6084    logln(buf);
6085
6086    for (int i = 0; i < tupleCount; ++i) {
6087      if (found[i]) {
6088        continue;
6089      }
6090      if (values[i*3] == id &&
6091          values[i*3+1] == start &&
6092          values[i*3+2] == limit) {
6093        found[i] = ok = TRUE;
6094        break;
6095      }
6096    }
6097
6098    assertTrue((UnicodeString)"found [" + id + "," + start + "," + limit + "]", ok);
6099  }
6100
6101  // check that all were found
6102  UBool ok = TRUE;
6103  for (int i = 0; i < tupleCount; ++i) {
6104    if (!found[i]) {
6105      ok = FALSE;
6106      assertTrue((UnicodeString) "missing [" + values[i*3] + "," + values[i*3+1] + "," + values[i*3+2] + "]", found[i]);
6107    }
6108  }
6109  assertTrue("no expected values were missing", ok);
6110}
6111
6112void NumberFormatTest::expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit,
6113                                       const UnicodeString& str)  {
6114  logln(str);
6115  assertTrue((UnicodeString)"id " + id + " == " + pos.getField(), id == pos.getField());
6116  assertTrue((UnicodeString)"begin " + start + " == " + pos.getBeginIndex(), start == pos.getBeginIndex());
6117  assertTrue((UnicodeString)"end " + limit + " == " + pos.getEndIndex(), limit == pos.getEndIndex());
6118}
6119
6120void NumberFormatTest::TestFieldPositionIterator() {
6121  // bug 7372
6122  UErrorCode status = U_ZERO_ERROR;
6123  FieldPositionIterator iter1;
6124  FieldPositionIterator iter2;
6125  FieldPosition pos;
6126
6127  DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(status);
6128  if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6129
6130  double num = 1234.56;
6131  UnicodeString str1;
6132  UnicodeString str2;
6133
6134  assertTrue((UnicodeString)"self==", iter1 == iter1);
6135  assertTrue((UnicodeString)"iter1==iter2", iter1 == iter2);
6136
6137  decFmt->format(num, str1, &iter1, status);
6138  assertTrue((UnicodeString)"iter1 != iter2", iter1 != iter2);
6139  decFmt->format(num, str2, &iter2, status);
6140  assertTrue((UnicodeString)"iter1 == iter2 (2)", iter1 == iter2);
6141  iter1.next(pos);
6142  assertTrue((UnicodeString)"iter1 != iter2 (2)", iter1 != iter2);
6143  iter2.next(pos);
6144  assertTrue((UnicodeString)"iter1 == iter2 (3)", iter1 == iter2);
6145
6146  // should format ok with no iterator
6147  str2.remove();
6148  decFmt->format(num, str2, NULL, status);
6149  assertEquals("null fpiter", str1, str2);
6150
6151  delete decFmt;
6152}
6153
6154void NumberFormatTest::TestFormatAttributes() {
6155  Locale locale("en_US");
6156  UErrorCode status = U_ZERO_ERROR;
6157  DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
6158    if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6159  double val = 12345.67;
6160
6161  {
6162    int32_t expected[] = {
6163      UNUM_CURRENCY_FIELD, 0, 1,
6164      UNUM_GROUPING_SEPARATOR_FIELD, 3, 4,
6165      UNUM_INTEGER_FIELD, 1, 7,
6166      UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8,
6167      UNUM_FRACTION_FIELD, 8, 10,
6168    };
6169    int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected));
6170
6171    FieldPositionIterator posIter;
6172    UnicodeString result;
6173    decFmt->format(val, result, &posIter, status);
6174    expectPositions(posIter, expected, tupleCount, result);
6175  }
6176  {
6177    FieldPosition fp(UNUM_INTEGER_FIELD);
6178    UnicodeString result;
6179    decFmt->format(val, result, fp);
6180    expectPosition(fp, UNUM_INTEGER_FIELD, 1, 7, result);
6181  }
6182  {
6183    FieldPosition fp(UNUM_FRACTION_FIELD);
6184    UnicodeString result;
6185    decFmt->format(val, result, fp);
6186    expectPosition(fp, UNUM_FRACTION_FIELD, 8, 10, result);
6187  }
6188  delete decFmt;
6189
6190  decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_SCIENTIFIC, status);
6191  val = -0.0000123;
6192  {
6193    int32_t expected[] = {
6194      UNUM_SIGN_FIELD, 0, 1,
6195      UNUM_INTEGER_FIELD, 1, 2,
6196      UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3,
6197      UNUM_FRACTION_FIELD, 3, 5,
6198      UNUM_EXPONENT_SYMBOL_FIELD, 5, 6,
6199      UNUM_EXPONENT_SIGN_FIELD, 6, 7,
6200      UNUM_EXPONENT_FIELD, 7, 8
6201    };
6202    int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected));
6203
6204    FieldPositionIterator posIter;
6205    UnicodeString result;
6206    decFmt->format(val, result, &posIter, status);
6207    expectPositions(posIter, expected, tupleCount, result);
6208  }
6209  {
6210    FieldPosition fp(UNUM_INTEGER_FIELD);
6211    UnicodeString result;
6212    decFmt->format(val, result, fp);
6213    expectPosition(fp, UNUM_INTEGER_FIELD, 1, 2, result);
6214  }
6215  {
6216    FieldPosition fp(UNUM_FRACTION_FIELD);
6217    UnicodeString result;
6218    decFmt->format(val, result, fp);
6219    expectPosition(fp, UNUM_FRACTION_FIELD, 3, 5, result);
6220  }
6221  delete decFmt;
6222
6223  fflush(stderr);
6224}
6225
6226const char* attrString(int32_t attrId) {
6227  switch (attrId) {
6228    case UNUM_INTEGER_FIELD: return "integer";
6229    case UNUM_FRACTION_FIELD: return "fraction";
6230    case UNUM_DECIMAL_SEPARATOR_FIELD: return "decimal separator";
6231    case UNUM_EXPONENT_SYMBOL_FIELD: return "exponent symbol";
6232    case UNUM_EXPONENT_SIGN_FIELD: return "exponent sign";
6233    case UNUM_EXPONENT_FIELD: return "exponent";
6234    case UNUM_GROUPING_SEPARATOR_FIELD: return "grouping separator";
6235    case UNUM_CURRENCY_FIELD: return "currency";
6236    case UNUM_PERCENT_FIELD: return "percent";
6237    case UNUM_PERMILL_FIELD: return "permille";
6238    case UNUM_SIGN_FIELD: return "sign";
6239    default: return "";
6240  }
6241}
6242
6243//
6244//   Test formatting & parsing of big decimals.
6245//      API test, not a comprehensive test.
6246//      See DecimalFormatTest/DataDrivenTests
6247//
6248#define ASSERT_SUCCESS(status) {if (U_FAILURE(status)) errln("file %s, line %d: status: %s", \
6249                                                __FILE__, __LINE__, u_errorName(status));}
6250#define ASSERT_EQUALS(expected, actual) {if ((expected) != (actual)) \
6251                  errln("file %s, line %d: %s != %s", __FILE__, __LINE__, #expected, #actual);}
6252
6253static UBool operator != (const char *s1, UnicodeString &s2) {
6254    // This function lets ASSERT_EQUALS("literal", UnicodeString) work.
6255    UnicodeString us1(s1);
6256    return us1 != s2;
6257}
6258
6259void NumberFormatTest::TestDecimal() {
6260    {
6261        UErrorCode  status = U_ZERO_ERROR;
6262        Formattable f("12.345678999987654321E666", status);
6263        ASSERT_SUCCESS(status);
6264        StringPiece s = f.getDecimalNumber(status);
6265        ASSERT_SUCCESS(status);
6266        ASSERT_EQUALS("1.2345678999987654321E+667", s);
6267        //printf("%s\n", s.data());
6268    }
6269
6270    {
6271        UErrorCode status = U_ZERO_ERROR;
6272        Formattable f1("this is not a number", status);
6273        ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR, status);
6274    }
6275
6276    {
6277        UErrorCode status = U_ZERO_ERROR;
6278        Formattable f;
6279        f.setDecimalNumber("123.45", status);
6280        ASSERT_SUCCESS(status);
6281        ASSERT_EQUALS( Formattable::kDouble, f.getType());
6282        ASSERT_EQUALS(123.45, f.getDouble());
6283        ASSERT_EQUALS(123.45, f.getDouble(status));
6284        ASSERT_SUCCESS(status);
6285        ASSERT_EQUALS("123.45", f.getDecimalNumber(status));
6286        ASSERT_SUCCESS(status);
6287
6288        f.setDecimalNumber("4.5678E7", status);
6289        int32_t n;
6290        n = f.getLong();
6291        ASSERT_EQUALS(45678000, n);
6292
6293        status = U_ZERO_ERROR;
6294        f.setDecimalNumber("-123", status);
6295        ASSERT_SUCCESS(status);
6296        ASSERT_EQUALS( Formattable::kLong, f.getType());
6297        ASSERT_EQUALS(-123, f.getLong());
6298        ASSERT_EQUALS(-123, f.getLong(status));
6299        ASSERT_SUCCESS(status);
6300        ASSERT_EQUALS("-123", f.getDecimalNumber(status));
6301        ASSERT_SUCCESS(status);
6302
6303        status = U_ZERO_ERROR;
6304        f.setDecimalNumber("1234567890123", status);  // Number too big for 32 bits
6305        ASSERT_SUCCESS(status);
6306        ASSERT_EQUALS( Formattable::kInt64, f.getType());
6307        ASSERT_EQUALS(1234567890123LL, f.getInt64());
6308        ASSERT_EQUALS(1234567890123LL, f.getInt64(status));
6309        ASSERT_SUCCESS(status);
6310        ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status));
6311        ASSERT_SUCCESS(status);
6312    }
6313
6314    {
6315        UErrorCode status = U_ZERO_ERROR;
6316        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6317        if (U_FAILURE(status) || fmtr == NULL) {
6318            dataerrln("Unable to create NumberFormat");
6319        } else {
6320            UnicodeString formattedResult;
6321            StringPiece num("244444444444444444444444444444444444446.4");
6322            fmtr->format(num, formattedResult, NULL, status);
6323            ASSERT_SUCCESS(status);
6324            ASSERT_EQUALS("244,444,444,444,444,444,444,444,444,444,444,444,446.4", formattedResult);
6325            //std::string ss; std::cout << formattedResult.toUTF8String(ss);
6326            delete fmtr;
6327        }
6328    }
6329
6330    {
6331        // Check formatting a DigitList.  DigitList is internal, but this is
6332        // a critical interface that must work.
6333        UErrorCode status = U_ZERO_ERROR;
6334        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6335        if (U_FAILURE(status) || fmtr == NULL) {
6336            dataerrln("Unable to create NumberFormat");
6337        } else {
6338            UnicodeString formattedResult;
6339            DigitList dl;
6340            StringPiece num("123.4566666666666666666666666666666666621E+40");
6341            dl.set(num, status);
6342            ASSERT_SUCCESS(status);
6343            fmtr->format(dl, formattedResult, NULL, status);
6344            ASSERT_SUCCESS(status);
6345            ASSERT_EQUALS("1,234,566,666,666,666,666,666,666,666,666,666,666,621,000", formattedResult);
6346
6347            status = U_ZERO_ERROR;
6348            num.set("666.666");
6349            dl.set(num, status);
6350            FieldPosition pos(NumberFormat::FRACTION_FIELD);
6351            ASSERT_SUCCESS(status);
6352            formattedResult.remove();
6353            fmtr->format(dl, formattedResult, pos, status);
6354            ASSERT_SUCCESS(status);
6355            ASSERT_EQUALS("666.666", formattedResult);
6356            ASSERT_EQUALS(4, pos.getBeginIndex());
6357            ASSERT_EQUALS(7, pos.getEndIndex());
6358            delete fmtr;
6359        }
6360    }
6361
6362    {
6363        // Check a parse with a formatter with a multiplier.
6364        UErrorCode status = U_ZERO_ERROR;
6365        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT, status);
6366        if (U_FAILURE(status) || fmtr == NULL) {
6367            dataerrln("Unable to create NumberFormat");
6368        } else {
6369            UnicodeString input = "1.84%";
6370            Formattable result;
6371            fmtr->parse(input, result, status);
6372            ASSERT_SUCCESS(status);
6373            ASSERT_EQUALS(0, strcmp("0.0184", result.getDecimalNumber(status).data()));
6374            //std::cout << result.getDecimalNumber(status).data();
6375            delete fmtr;
6376        }
6377    }
6378
6379#if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
6380    /*
6381     * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
6382     * See #9463
6383     */
6384    {
6385        // Check that a parse returns a decimal number with full accuracy
6386        UErrorCode status = U_ZERO_ERROR;
6387        NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
6388        if (U_FAILURE(status) || fmtr == NULL) {
6389            dataerrln("Unable to create NumberFormat");
6390        } else {
6391            UnicodeString input = "1.002200044400088880000070000";
6392            Formattable result;
6393            fmtr->parse(input, result, status);
6394            ASSERT_SUCCESS(status);
6395            ASSERT_EQUALS(0, strcmp("1.00220004440008888000007", result.getDecimalNumber(status).data()));
6396            ASSERT_EQUALS(1.00220004440008888,   result.getDouble());
6397            //std::cout << result.getDecimalNumber(status).data();
6398            delete fmtr;
6399        }
6400    }
6401#endif
6402
6403}
6404
6405void NumberFormatTest::TestCurrencyFractionDigits() {
6406    UErrorCode status = U_ZERO_ERROR;
6407    UnicodeString text1, text2;
6408    double value = 99.12345;
6409
6410    // Create currenct instance
6411    NumberFormat* fmt = NumberFormat::createCurrencyInstance("ja_JP", status);
6412    if (U_FAILURE(status) || fmt == NULL) {
6413        dataerrln("Unable to create NumberFormat");
6414    } else {
6415        fmt->format(value, text1);
6416
6417        // Reset the same currency and format the test value again
6418        fmt->setCurrency(fmt->getCurrency(), status);
6419        ASSERT_SUCCESS(status);
6420        fmt->format(value, text2);
6421
6422        if (text1 != text2) {
6423            errln((UnicodeString)"NumberFormat::format() should return the same result - text1="
6424                + text1 + " text2=" + text2);
6425        }
6426        delete fmt;
6427    }
6428}
6429
6430void NumberFormatTest::TestExponentParse() {
6431
6432    UErrorCode status = U_ZERO_ERROR;
6433    Formattable result;
6434    ParsePosition parsePos(0);
6435
6436    // set the exponent symbol
6437    status = U_ZERO_ERROR;
6438    DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status);
6439    if(U_FAILURE(status)) {
6440        dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)");
6441        return;
6442    }
6443
6444    // create format instance
6445    status = U_ZERO_ERROR;
6446    DecimalFormat fmt("#####", symbols, status);
6447    if(U_FAILURE(status)) {
6448        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
6449    }
6450
6451    // parse the text
6452    fmt.parse("5.06e-27", result, parsePos);
6453    if(result.getType() != Formattable::kDouble &&
6454       result.getDouble() != 5.06E-27 &&
6455       parsePos.getIndex() != 8
6456       )
6457    {
6458        errln("ERROR: parse failed - expected 5.06E-27, 8  - returned %d, %i",
6459              result.getDouble(), parsePos.getIndex());
6460    }
6461}
6462
6463void NumberFormatTest::TestExplicitParents() {
6464
6465    /* Test that number formats are properly inherited from es_419 */
6466    /* These could be subject to change if the CLDR data changes */
6467    static const char* parentLocaleTests[][2]= {
6468    /* locale ID */  /* expected */
6469    {"es_CO", "1.250,75" },
6470    {"es_CR", "1.250,75" },
6471    {"es_ES", "1.250,75" },
6472    {"es_GQ", "1.250,75" },
6473    {"es_MX", "1,250.75" },
6474    {"es_US", "1,250.75" },
6475    {"es_VE", "1.250,75" },
6476    };
6477
6478    UnicodeString s;
6479
6480    for(int i=0; i < (int)(sizeof(parentLocaleTests)/sizeof(parentLocaleTests[i])); i++){
6481        UErrorCode status = U_ZERO_ERROR;
6482        const char *localeID = parentLocaleTests[i][0];
6483        UnicodeString expected(parentLocaleTests[i][1], -1, US_INV);
6484        expected = expected.unescape();
6485        char loc[256]={0};
6486        uloc_canonicalize(localeID, loc, 256, &status);
6487        NumberFormat *fmt= NumberFormat::createInstance(Locale(loc), status);
6488        if(U_FAILURE(status)){
6489            dataerrln("Could not create number formatter for locale %s - %s",localeID, u_errorName(status));
6490            continue;
6491        }
6492        s.remove();
6493        fmt->format(1250.75, s);
6494        if(s!=expected){
6495            errln(UnicodeString("FAIL: Expected: ")+expected
6496                    + UnicodeString(" Got: ") + s
6497                    + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
6498        }
6499        if (U_FAILURE(status)){
6500            errln((UnicodeString)"FAIL: Status " + (int32_t)status);
6501        }
6502        delete fmt;
6503    }
6504
6505}
6506
6507/**
6508 * Test available numbering systems API.
6509 */
6510void NumberFormatTest::TestAvailableNumberingSystems() {
6511    UErrorCode status = U_ZERO_ERROR;
6512    StringEnumeration *availableNumberingSystems = NumberingSystem::getAvailableNames(status);
6513    CHECK_DATA(status, "NumberingSystem::getAvailableNames()")
6514
6515    int32_t nsCount = availableNumberingSystems->count(status);
6516    if ( nsCount < 36 ) {
6517        errln("FAIL: Didn't get as many numbering systems as we had hoped for. Need at least 36, got %d",nsCount);
6518    }
6519
6520    /* A relatively simple test of the API.  We call getAvailableNames() and cycle through */
6521    /* each name returned, attempting to create a numbering system based on that name and  */
6522    /* verifying that the name returned from the resulting numbering system is the same    */
6523    /* one that we initially thought.                                                      */
6524
6525    int32_t len;
6526    for ( int32_t i = 0 ; i < nsCount ; i++ ) {
6527        const char *nsname = availableNumberingSystems->next(&len,status);
6528        NumberingSystem* ns = NumberingSystem::createInstanceByName(nsname,status);
6529        if ( uprv_strcmp(nsname,ns->getName()) ) {
6530            errln("FAIL: Numbering system name didn't match for name = %s\n",nsname);
6531        }
6532
6533        delete ns;
6534    }
6535
6536    delete availableNumberingSystems;
6537}
6538
6539void
6540NumberFormatTest::Test9087(void)
6541{
6542    U_STRING_DECL(pattern,"#",1);
6543    U_STRING_INIT(pattern,"#",1);
6544
6545    U_STRING_DECL(infstr,"INF",3);
6546    U_STRING_INIT(infstr,"INF",3);
6547
6548    U_STRING_DECL(nanstr,"NAN",3);
6549    U_STRING_INIT(nanstr,"NAN",3);
6550
6551    UChar outputbuf[50] = {0};
6552    UErrorCode status = U_ZERO_ERROR;
6553    UNumberFormat* fmt = unum_open(UNUM_PATTERN_DECIMAL,pattern,1,NULL,NULL,&status);
6554    if ( U_FAILURE(status) ) {
6555        dataerrln("FAIL: error in unum_open() - %s", u_errorName(status));
6556        return;
6557    }
6558
6559    unum_setSymbol(fmt,UNUM_INFINITY_SYMBOL,infstr,3,&status);
6560    unum_setSymbol(fmt,UNUM_NAN_SYMBOL,nanstr,3,&status);
6561    if ( U_FAILURE(status) ) {
6562        errln("FAIL: error setting symbols");
6563    }
6564
6565    double inf = uprv_getInfinity();
6566
6567    unum_setAttribute(fmt,UNUM_ROUNDING_MODE,UNUM_ROUND_HALFEVEN);
6568    unum_setDoubleAttribute(fmt,UNUM_ROUNDING_INCREMENT,0);
6569
6570    UFieldPosition position = { 0, 0, 0};
6571    unum_formatDouble(fmt,inf,outputbuf,50,&position,&status);
6572
6573    if ( u_strcmp(infstr, outputbuf)) {
6574        errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf);
6575    }
6576
6577    unum_close(fmt);
6578}
6579
6580#include "dcfmtimp.h"
6581
6582void NumberFormatTest::TestFormatFastpaths() {
6583#if UCONFIG_FORMAT_FASTPATHS_49
6584    logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n",
6585        sizeof(DecimalFormat), sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
6586    if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) {
6587        errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
6588    } else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) {
6589        infoln("Note: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is %d. Decrease the #define? sizeof(DecimalFormat)=%d\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE, sizeof(DecimalFormat));
6590    }
6591#else
6592    infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped.");
6593#endif
6594
6595    // get some additional case
6596    {
6597        UErrorCode status=U_ZERO_ERROR;
6598        DecimalFormat df(UnicodeString("0000",""),status);
6599        int64_t long_number = 1;
6600        UnicodeString expect = "0001";
6601        UnicodeString result;
6602        FieldPosition pos;
6603        df.format(long_number, result, pos);
6604        if(U_FAILURE(status)||expect!=result) {
6605            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),""));
6606        } else {
6607            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
6608        }
6609    }
6610    {
6611        UErrorCode status=U_ZERO_ERROR;
6612        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6613        int64_t long_number = U_INT64_MIN; // -9223372036854775808L;
6614        // uint8_t bits[8];
6615        // memcpy(bits,&long_number,8);
6616        // for(int i=0;i<8;i++) {
6617        //   logln("bits: %02X", (unsigned int)bits[i]);
6618        // }
6619        UnicodeString expect = "-9223372036854775808";
6620        UnicodeString result;
6621        FieldPosition pos;
6622        df.format(long_number, result, pos);
6623        if(U_FAILURE(status)||expect!=result) {
6624            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
6625        } else {
6626            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
6627        }
6628    }
6629    {
6630        UErrorCode status=U_ZERO_ERROR;
6631        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6632        int64_t long_number = U_INT64_MAX; // -9223372036854775808L;
6633        // uint8_t bits[8];
6634        // memcpy(bits,&long_number,8);
6635        // for(int i=0;i<8;i++) {
6636        //   logln("bits: %02X", (unsigned int)bits[i]);
6637        // }
6638        UnicodeString expect = "9223372036854775807";
6639        UnicodeString result;
6640        FieldPosition pos;
6641        df.format(long_number, result, pos);
6642        if(U_FAILURE(status)||expect!=result) {
6643            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
6644        } else {
6645            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
6646        }
6647    }
6648    {
6649        UErrorCode status=U_ZERO_ERROR;
6650        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6651        int64_t long_number = 0;
6652        // uint8_t bits[8];
6653        // memcpy(bits,&long_number,8);
6654        // for(int i=0;i<8;i++) {
6655        //   logln("bits: %02X", (unsigned int)bits[i]);
6656        // }
6657        UnicodeString expect = "0000000000000000000";
6658        UnicodeString result;
6659        FieldPosition pos;
6660        df.format(long_number, result, pos);
6661        if(U_FAILURE(status)||expect!=result) {
6662            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
6663        } else {
6664            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
6665        }
6666    }
6667    {
6668        UErrorCode status=U_ZERO_ERROR;
6669        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
6670        int64_t long_number = U_INT64_MIN + 1;
6671        UnicodeString expect = "-9223372036854775807";
6672        UnicodeString result;
6673        FieldPosition pos;
6674        df.format(long_number, result, pos);
6675        if(U_FAILURE(status)||expect!=result) {
6676            errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
6677        } else {
6678            logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
6679        }
6680    }
6681}
6682
6683
6684void NumberFormatTest::TestFormattableSize(void) {
6685  if(sizeof(FmtStackData) > UNUM_INTERNAL_STACKARRAY_SIZE) {
6686    errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
6687          sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
6688  } else if(sizeof(FmtStackData) < UNUM_INTERNAL_STACKARRAY_SIZE) {
6689    logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
6690        sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
6691  } else {
6692    logln("sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
6693        sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
6694  }
6695}
6696
6697#endif /* #if !UCONFIG_NO_FORMATTING */
6698