150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/********************************************************************
250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * COPYRIGHT:
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Copyright (c) 2002-2014, International Business Machines Corporation and
450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * others. All Rights Reserved.
550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ********************************************************************/
650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   dcfmtest.cpp
950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//     Decimal Formatter tests, data driven.
1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "intltest.h"
1427f654740f2a26ad62a5c155af9199af9e69b889claireho
1527f654740f2a26ad62a5c155af9199af9e69b889claireho#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_REGULAR_EXPRESSIONS
1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/regex.h"
1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/uchar.h"
1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ustring.h"
2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/unistr.h"
2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/dcfmtsym.h"
2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/decimfmt.h"
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/locid.h"
2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "dcfmtest.h"
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "util.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h"
2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <stdlib.h>
2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <string.h>
3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <stdio.h>
3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !defined(_MSC_VER)
33fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusnamespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
34fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
35fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <string>
3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <iostream>
3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  Test class boilerplate
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormatTest::DecimalFormatTest()
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormatTest::~DecimalFormatTest()
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (exec) logln("TestSuite DecimalFormatTest: ");
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    switch (index) {
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_FILE_IO
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case 0: name = "DataDrivenTests";
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (exec) DataDrivenTests();
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case 0: name = "skip";
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        default: name = "";
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break; //needed to end loop
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   Error Checking / Reporting macros used in all of the tests.
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_CHECK_STATUS {if (U_FAILURE(status)) \
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {dataerrln("DecimalFormatTest failure at line %d.  status=%s", \
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    __LINE__, u_errorName(status)); return 0;}}
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_ASSERT(expr) {if ((expr)==FALSE) {errln("DecimalFormatTest failure at line %d.\n", __LINE__);};}
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_ASSERT_FAIL(expr, errcode) {UErrorCode status=U_ZERO_ERROR; (expr);\
8750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoif (status!=errcode) {dataerrln("DecimalFormatTest failure at line %d.  Expected status=%s, got %s", \
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    __LINE__, u_errorName(errcode), u_errorName(status));};}
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_CHECK_STATUS_L(line) {if (U_FAILURE(status)) {errln( \
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    "DecimalFormatTest failure at line %d, from %d.  status=%d\n",__LINE__, (line), status); }}
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_ASSERT_L(expr, line) {if ((expr)==FALSE) { \
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    errln("DecimalFormatTest failure at line %d, from %d.", __LINE__, (line)); return;}}
9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  InvariantStringPiece
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Wrap a StringPiece around the extracted invariant data of a UnicodeString.
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    The data is guaranteed to be nul terminated.  (This is not true of StringPiece
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    in general, but is true of InvariantStringPiece)
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass InvariantStringPiece: public StringPiece {
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  public:
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    InvariantStringPiece(const UnicodeString &s);
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~InvariantStringPiece() {};
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  private:
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    MaybeStackArray<char, 20>  buf;
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoInvariantStringPiece::InvariantStringPiece(const UnicodeString &s) {
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t  len = s.length();
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (len+1 > buf.getCapacity()) {
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buf.resize(len+1);
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Buffer size is len+1 so that s.extract() will nul-terminate the string.
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    s.extract(0, len, buf.getAlias(), len+1, US_INV);
11954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    this->set(buf.getAlias(), len);
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  UnicodeStringPiece
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Wrap a StringPiece around the extracted (to the default charset) data of
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    a UnicodeString.  The extracted data is guaranteed to be nul terminated.
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    (This is not true of StringPiece in general, but is true of UnicodeStringPiece)
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass UnicodeStringPiece: public StringPiece {
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  public:
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeStringPiece(const UnicodeString &s);
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~UnicodeStringPiece() {};
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  private:
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    MaybeStackArray<char, 20>  buf;
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeStringPiece::UnicodeStringPiece(const UnicodeString &s) {
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t  len = s.length();
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t  capacity = buf.getCapacity();
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t requiredCapacity = s.extract(0, len, buf.getAlias(), capacity) + 1;
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (capacity < requiredCapacity) {
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buf.resize(requiredCapacity);
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        capacity = requiredCapacity;
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        s.extract(0, len, buf.getAlias(), capacity);
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
14554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    this->set(buf.getAlias(), requiredCapacity - 1);
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      DataDrivenTests
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//             The test cases are in a separate data file,
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Translate a Formattable::type enum value to a string, for error message formatting.
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char *formattableType(Formattable::Type typ) {
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    static const char *types[] = {"kDate",
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kDouble",
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kLong",
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kString",
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kArray",
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kInt64",
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kObject"
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  };
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (typ<0 || typ>Formattable::kObject) {
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return "Unknown";
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return types[typ];
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst char *
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormatTest::getPath(char *buffer, const char *filename) {
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode status=U_ZERO_ERROR;
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char *testDataDirectory = IntlTest::getSourceTestData(status);
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DF_CHECK_STATUS;
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    strcpy(buffer, testDataDirectory);
18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    strcat(buffer, filename);
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return buffer;
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::DataDrivenTests() {
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char tdd[2048];
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char *srcPath;
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode  status  = U_ZERO_ERROR;
18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t     lineNum = 0;
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Open and read the test data file.
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    srcPath=getPath(tdd, "dcfmtest.txt");
19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(srcPath==NULL) {
19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return; /* something went wrong, error already output */
19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t    len;
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *testData = ReadAndConvertFile(srcPath, len, status);
20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return; /* something went wrong, error already output */
20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Put the test data into a UnicodeString
20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString testString(FALSE, testData, len);
20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    parseLineMat(UnicodeString(
21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "(?i)\\s*parse\\s+"
21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\"([^\"]*)\"\\s+"           // Capture group 1: input text
21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "([ild])\\s+"                // Capture group 2: expected parsed type
21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\"([^\"]*)\"\\s+"           // Capture group 3: expected parsed decimal
21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\\s*(?:#.*)?"),             // Trailing comment
21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         0, status);
21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    formatLineMat(UnicodeString(
21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "(?i)\\s*format\\s+"
21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "(\\S+)\\s+"                 // Capture group 1: pattern
220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "(ceiling|floor|down|up|halfeven|halfdown|halfup|default|unnecessary)\\s+"  // Capture group 2: Rounding Mode
22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\"([^\"]*)\"\\s+"           // Capture group 3: input
222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "\"([^\"]*)\""               // Capture group 4: expected output
22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\\s*(?:#.*)?"),             // Trailing comment
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         0, status);
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    commentMat    (UNICODE_STRING_SIMPLE("\\s*(#.*)?$"), 0, status);
22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    lineMat(UNICODE_STRING_SIMPLE("(?m)^(.*?)$"), testString, 0, status);
22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)){
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Construct RegexMatcher() error.");
23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete [] testData;
23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Loop over the test data file, once per line.
23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    while (lineMat.find()) {
23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        lineNum++;
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (U_FAILURE(status)) {
241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            dataerrln("File dcfmtest.txt, line %d: ICU Error \"%s\"", lineNum, u_errorName(status));
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_ZERO_ERROR;
24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString testLine = lineMat.group(1, status);
24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // printf("%s\n", UnicodeStringPiece(testLine).data());
24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (testLine.length() == 0) {
24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Parse the test line.  Skip blank and comment only lines.
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Separate out the three main fields - pattern, flags, target.
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        commentMat.reset(testLine);
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (commentMat.lookingAt(status)) {
25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // This line is a comment, or blank.
25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //  Handle "parse" test case line from file
26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parseLineMat.reset(testLine);
26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (parseLineMat.lookingAt(status)) {
26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            execParseTest(lineNum,
26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          parseLineMat.group(1, status),    // input
27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          parseLineMat.group(2, status),    // Expected Type
27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          parseLineMat.group(3, status),    // Expected Decimal String
27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          status
27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          );
27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //  Handle "format" test case line
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        formatLineMat.reset(testLine);
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (formatLineMat.lookingAt(status)) {
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            execFormatTest(lineNum,
28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(1, status),    // Pattern
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(2, status),    // rounding mode
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(3, status),    // input decimal number
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(4, status),    // expected formatted result
28754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           kFormattable,
28854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           status);
28954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
29054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            execFormatTest(lineNum,
29154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           formatLineMat.group(1, status),    // Pattern
29254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           formatLineMat.group(2, status),    // rounding mode
29354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           formatLineMat.group(3, status),    // input decimal number
29454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           formatLineMat.group(4, status),    // expected formatted result
29554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           kStringPiece,
29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           status);
29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //  Line is not a recognizable test case.
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("Badly formed test case at line %d.\n%s\n",
30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             lineNum, UnicodeStringPiece(testLine).data());
30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    delete [] testData;
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::execParseTest(int32_t lineNum,
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     const UnicodeString &inputText,
31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     const UnicodeString &expectedType,
31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     const UnicodeString &expectedDecimal,
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     UErrorCode &status) {
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormatSymbols symbols(Locale::getUS(), status);
32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString pattern = UNICODE_STRING_SIMPLE("####");
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormat format(pattern, symbols, status);
32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    Formattable   result;
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, u_errorName(status));
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ParsePosition pos;
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t expectedParseEndPosition = inputText.length();
33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    format.parse(inputText, result, pos);
33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (expectedParseEndPosition != pos.getIndex()) {
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: Expected parse position afeter parsing: %d.  "
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              "Actual parse position: %d", expectedParseEndPosition, pos.getIndex());
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char   expectedTypeC[2];
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    expectedType.extract(0, 1, expectedTypeC, 2, US_INV);
34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    Formattable::Type expectType = Formattable::kDate;
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    switch (expectedTypeC[0]) {
34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case 'd': expectType = Formattable::kDouble; break;
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case 'i': expectType = Formattable::kLong;   break;
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case 'l': expectType = Formattable::kInt64;  break;
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      default:
35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho          errln("file dcfmtest.tx, line %d: unrecongized expected type \"%s\"",
35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              lineNum, InvariantStringPiece(expectedType).data());
35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho          return;
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (result.getType() != expectType) {
35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: expectedParseType(%s) != actual parseType(%s)",
35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             lineNum, formattableType(expectType), formattableType(result.getType()));
35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    StringPiece decimalResult = result.getDecimalNumber(status);
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("File %s, line %d: error %s.  Line in file dcfmtest.txt:  %d:",
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            __FILE__, __LINE__, u_errorName(status), lineNum);
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    InvariantStringPiece expectedResults(expectedDecimal);
37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decimalResult != expectedResults) {
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, expectedResults.data(), decimalResult.data());
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return;
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::execFormatTest(int32_t lineNum,
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &pattern,     // Pattern
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &round,       // rounding mode
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &input,       // input decimal number
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &expected,    // expected formatted result
38454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                           EFormatInputType inType,          // input number type
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           UErrorCode &status) {
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormatSymbols symbols(Locale::getUS(), status);
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // printf("Pattern = %s\n", UnicodeStringPiece(pattern).data());
39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormat fmtr(pattern, symbols, status);
39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, u_errorName(status));
39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (round=="ceiling") {
39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundCeiling);
40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="floor") {
40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="down") {
40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundDown);
40450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="up") {
40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundUp);
40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="halfeven") {
40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundHalfEven);
40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="halfdown") {
40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundHalfDown);
41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="halfup") {
41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundHalfUp);
41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="default") {
41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // don't set any value.
414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else if (round=="unnecessary") {
415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fmtr.setRoundingMode(DecimalFormat::kRoundUnnecessary);
41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
41750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
41850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: Bad rounding mode \"%s\"",
41950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lineNum, UnicodeStringPiece(round).data());
42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
42154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
42259d709d503bab6e2b61931737e662dd293b40578ccornelius    const char *typeStr = "Unknown";
42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString result;
42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeStringPiece spInput(input);
42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
42654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    switch (inType) {
42754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case kFormattable:
42854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        {
42954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            typeStr = "Formattable";
43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            Formattable fmtbl;
43154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            fmtbl.setDecimalNumber(spInput, status);
43254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            fmtr.format(fmtbl, result, NULL, status);
43354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
43454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
43554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    case kStringPiece:
43654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        typeStr = "StringPiece";
43754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        fmtr.format(spInput, result, NULL, status);
43854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        break;
43954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ((status == U_FORMAT_INEXACT_ERROR) && (result == "") && (expected == "Inexact")) {
442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // Test succeeded.
443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_ZERO_ERROR;
444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return;
445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
44654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
44854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        errln("[%s] file dcfmtest.txt, line %d: format() returned %s.",
44954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            typeStr, lineNum, u_errorName(status));
450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_ZERO_ERROR;
45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (result != expected) {
45554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        errln("[%s] file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
45654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            typeStr, lineNum, UnicodeStringPiece(expected).data(), UnicodeStringPiece(result).data());
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//-------------------------------------------------------------------------------
46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  Read a text data file, convert it from UTF-8 to UChars, and return the data
46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    in one big UChar * buffer, which the caller must delete.
46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    (Lightly modified version of a similar function in regextst.cpp)
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//--------------------------------------------------------------------------------
46950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUChar *DecimalFormatTest::ReadAndConvertFile(const char *fileName, int32_t &ulen,
47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     UErrorCode &status) {
47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar       *retPtr  = NULL;
47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char        *fileBuf = NULL;
47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char  *fileBufNoBOM = NULL;
47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FILE        *f       = NULL;
47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ulen = 0;
47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return retPtr;
47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Open the file.
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    f = fopen(fileName, "rb");
48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (f == 0) {
48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Error opening test data file %s\n", fileName);
48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_FILE_ACCESS_ERROR;
48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return NULL;
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Read it in
49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t            fileSize;
49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t            amtRead;
49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t            amtReadNoBOM;
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fseek( f, 0, SEEK_END);
49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fileSize = ftell(f);
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fileBuf = new char[fileSize];
50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fseek(f, 0, SEEK_SET);
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    amtRead = fread(fileBuf, 1, fileSize, f);
50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (amtRead != fileSize || fileSize <= 0) {
50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("Error reading test data file.");
50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto cleanUpAndReturn;
50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
50850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Look for a UTF-8 BOM on the data just read.
50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    The test data file is UTF-8.
51050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    The BOM needs to be there in the source file to keep the Windows &
51150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    EBCDIC machines happy, so force an error if it goes missing.
51250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    Many Linux editors will silently strip it.
51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
51450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fileBufNoBOM = fileBuf + 3;
51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    amtReadNoBOM = amtRead - 3;
51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fileSize<3 || uprv_strncmp(fileBuf, "\xEF\xBB\xBF", 3) != 0) {
51750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // TODO:  restore this check.
51827f654740f2a26ad62a5c155af9199af9e69b889claireho        errln("Test data file %s is missing its BOM", fileName);
51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fileBufNoBOM = fileBuf;
52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        amtReadNoBOM = amtRead;
52150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Find the length of the input in UTF-16 UChars
52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  (by preflighting the conversion)
52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    u_strFromUTF8(NULL, 0, &ulen, fileBufNoBOM, amtReadNoBOM, &status);
52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
53050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Convert file contents from UTF-8 to UTF-16
53150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
53250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (status == U_BUFFER_OVERFLOW_ERROR) {
53350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Buffer Overflow is expected from the preflight operation.
53450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_ZERO_ERROR;
53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        retPtr = new UChar[ulen+1];
53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        u_strFromUTF8(retPtr, ulen+1, NULL, fileBufNoBOM, amtReadNoBOM, &status);
53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
53950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocleanUpAndReturn:
54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fclose(f);
54150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    delete[] fileBuf;
54250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
54350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("ICU Error \"%s\"\n", u_errorName(status));
54450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete retPtr;
54550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        retPtr = NULL;
54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    };
54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return retPtr;
54850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
54950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif  /* !UCONFIG_NO_REGULAR_EXPRESSIONS  */
55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
552