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