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