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