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