150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/********************************************************************
250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * COPYRIGHT:
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Copyright (c) 2002-2011, 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
3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <string>
3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <iostream>
3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  Test class boilerplate
3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormatTest::DecimalFormatTest()
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormatTest::~DecimalFormatTest()
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (exec) logln("TestSuite DecimalFormatTest: ");
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    switch (index) {
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_FILE_IO
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case 0: name = "DataDrivenTests";
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (exec) DataDrivenTests();
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        case 0: name = "skip";
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break;
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        default: name = "";
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            break; //needed to end loop
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//   Error Checking / Reporting macros used in all of the tests.
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_CHECK_STATUS {if (U_FAILURE(status)) \
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {dataerrln("DecimalFormatTest failure at line %d.  status=%s", \
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    __LINE__, u_errorName(status)); return 0;}}
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_ASSERT(expr) {if ((expr)==FALSE) {errln("DecimalFormatTest failure at line %d.\n", __LINE__);};}
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_ASSERT_FAIL(expr, errcode) {UErrorCode status=U_ZERO_ERROR; (expr);\
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoif (status!=errcode) {dataerrln("DecimalFormatTest failure at line %d.  Expected status=%s, got %s", \
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    __LINE__, u_errorName(errcode), u_errorName(status));};}
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_CHECK_STATUS_L(line) {if (U_FAILURE(status)) {errln( \
8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    "DecimalFormatTest failure at line %d, from %d.  status=%d\n",__LINE__, (line), status); }}
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define DF_ASSERT_L(expr, line) {if ((expr)==FALSE) { \
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    errln("DecimalFormatTest failure at line %d, from %d.", __LINE__, (line)); return;}}
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  InvariantStringPiece
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Wrap a StringPiece around the extracted invariant data of a UnicodeString.
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    The data is guaranteed to be nul terminated.  (This is not true of StringPiece
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    in general, but is true of InvariantStringPiece)
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass InvariantStringPiece: public StringPiece {
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  public:
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    InvariantStringPiece(const UnicodeString &s);
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~InvariantStringPiece() {};
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  private:
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    MaybeStackArray<char, 20>  buf;
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoInvariantStringPiece::InvariantStringPiece(const UnicodeString &s) {
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t  len = s.length();
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (len+1 > buf.getCapacity()) {
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buf.resize(len+1);
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Buffer size is len+1 so that s.extract() will nul-terminate the string.
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    s.extract(0, len, buf.getAlias(), len+1, US_INV);
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    this->set(buf, len);
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  UnicodeStringPiece
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    Wrap a StringPiece around the extracted (to the default charset) data of
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    a UnicodeString.  The extracted data is guaranteed to be nul terminated.
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    (This is not true of StringPiece in general, but is true of UnicodeStringPiece)
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass UnicodeStringPiece: public StringPiece {
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  public:
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeStringPiece(const UnicodeString &s);
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~UnicodeStringPiece() {};
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  private:
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    MaybeStackArray<char, 20>  buf;
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeStringPiece::UnicodeStringPiece(const UnicodeString &s) {
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t  len = s.length();
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t  capacity = buf.getCapacity();
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t requiredCapacity = s.extract(0, len, buf.getAlias(), capacity) + 1;
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (capacity < requiredCapacity) {
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buf.resize(requiredCapacity);
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        capacity = requiredCapacity;
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        s.extract(0, len, buf.getAlias(), capacity);
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    this->set(buf, requiredCapacity - 1);
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//      DataDrivenTests
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//             The test cases are in a separate data file,
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//---------------------------------------------------------------------------
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Translate a Formattable::type enum value to a string, for error message formatting.
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char *formattableType(Formattable::Type typ) {
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    static const char *types[] = {"kDate",
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kDouble",
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kLong",
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kString",
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kArray",
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kInt64",
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  "kObject"
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  };
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (typ<0 || typ>Formattable::kObject) {
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return "Unknown";
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return types[typ];
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst char *
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDecimalFormatTest::getPath(char *buffer, const char *filename) {
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode status=U_ZERO_ERROR;
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char *testDataDirectory = IntlTest::getSourceTestData(status);
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DF_CHECK_STATUS;
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    strcpy(buffer, testDataDirectory);
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    strcat(buffer, filename);
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return buffer;
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::DataDrivenTests() {
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char tdd[2048];
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char *srcPath;
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode  status  = U_ZERO_ERROR;
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t     lineNum = 0;
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Open and read the test data file.
18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    srcPath=getPath(tdd, "dcfmtest.txt");
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(srcPath==NULL) {
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return; /* something went wrong, error already output */
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t    len;
19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *testData = ReadAndConvertFile(srcPath, len, status);
19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return; /* something went wrong, error already output */
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Put the test data into a UnicodeString
20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString testString(FALSE, testData, len);
20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    parseLineMat(UnicodeString(
20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "(?i)\\s*parse\\s+"
20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\"([^\"]*)\"\\s+"           // Capture group 1: input text
20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "([ild])\\s+"                // Capture group 2: expected parsed type
20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\"([^\"]*)\"\\s+"           // Capture group 3: expected parsed decimal
21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\\s*(?:#.*)?"),             // Trailing comment
21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         0, status);
21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    formatLineMat(UnicodeString(
21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "(?i)\\s*format\\s+"
21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "(\\S+)\\s+"                 // Capture group 1: pattern
216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "(ceiling|floor|down|up|halfeven|halfdown|halfup|default|unnecessary)\\s+"  // Capture group 2: Rounding Mode
21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\"([^\"]*)\"\\s+"           // Capture group 3: input
218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "\"([^\"]*)\""               // Capture group 4: expected output
21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\\s*(?:#.*)?"),             // Trailing comment
22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         0, status);
22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    commentMat    (UNICODE_STRING_SIMPLE("\\s*(#.*)?$"), 0, status);
22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    RegexMatcher    lineMat(UNICODE_STRING_SIMPLE("(?m)^(.*?)$"), testString, 0, status);
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)){
22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Construct RegexMatcher() error.");
22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete [] testData;
22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Loop over the test data file, once per line.
23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    while (lineMat.find()) {
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        lineNum++;
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (U_FAILURE(status)) {
237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            dataerrln("File dcfmtest.txt, line %d: ICU Error \"%s\"", lineNum, u_errorName(status));
23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_ZERO_ERROR;
24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UnicodeString testLine = lineMat.group(1, status);
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // printf("%s\n", UnicodeStringPiece(testLine).data());
24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (testLine.length() == 0) {
24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Parse the test line.  Skip blank and comment only lines.
24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Separate out the three main fields - pattern, flags, target.
25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        commentMat.reset(testLine);
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (commentMat.lookingAt(status)) {
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // This line is a comment, or blank.
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //  Handle "parse" test case line from file
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parseLineMat.reset(testLine);
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (parseLineMat.lookingAt(status)) {
26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            execParseTest(lineNum,
26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          parseLineMat.group(1, status),    // input
26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          parseLineMat.group(2, status),    // Expected Type
26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          parseLineMat.group(3, status),    // Expected Decimal String
26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          status
26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          );
27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //  Handle "format" test case line
27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        formatLineMat.reset(testLine);
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (formatLineMat.lookingAt(status)) {
27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            execFormatTest(lineNum,
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(1, status),    // Pattern
28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(2, status),    // rounding mode
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(3, status),    // input decimal number
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           formatLineMat.group(4, status),    // expected formatted result
28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           status);
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //  Line is not a recognizable test case.
28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        //
29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("Badly formed test case at line %d.\n%s\n",
29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             lineNum, UnicodeStringPiece(testLine).data());
29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    delete [] testData;
29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::execParseTest(int32_t lineNum,
30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     const UnicodeString &inputText,
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     const UnicodeString &expectedType,
30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     const UnicodeString &expectedDecimal,
30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     UErrorCode &status) {
30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormatSymbols symbols(Locale::getUS(), status);
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString pattern = UNICODE_STRING_SIMPLE("####");
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormat format(pattern, symbols, status);
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    Formattable   result;
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, u_errorName(status));
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ParsePosition pos;
32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t expectedParseEndPosition = inputText.length();
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    format.parse(inputText, result, pos);
32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (expectedParseEndPosition != pos.getIndex()) {
32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: Expected parse position afeter parsing: %d.  "
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              "Actual parse position: %d", expectedParseEndPosition, pos.getIndex());
32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char   expectedTypeC[2];
33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    expectedType.extract(0, 1, expectedTypeC, 2, US_INV);
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    Formattable::Type expectType = Formattable::kDate;
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    switch (expectedTypeC[0]) {
33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case 'd': expectType = Formattable::kDouble; break;
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case 'i': expectType = Formattable::kLong;   break;
33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      case 'l': expectType = Formattable::kInt64;  break;
33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      default:
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho          errln("file dcfmtest.tx, line %d: unrecongized expected type \"%s\"",
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              lineNum, InvariantStringPiece(expectedType).data());
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho          return;
34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (result.getType() != expectType) {
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: expectedParseType(%s) != actual parseType(%s)",
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             lineNum, formattableType(expectType), formattableType(result.getType()));
34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    StringPiece decimalResult = result.getDecimalNumber(status);
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("File %s, line %d: error %s.  Line in file dcfmtest.txt:  %d:",
35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            __FILE__, __LINE__, u_errorName(status), lineNum);
35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    InvariantStringPiece expectedResults(expectedDecimal);
35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (decimalResult != expectedResults) {
35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, expectedResults.data(), decimalResult.data());
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return;
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid DecimalFormatTest::execFormatTest(int32_t lineNum,
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &pattern,     // Pattern
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &round,       // rounding mode
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &input,       // input decimal number
37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           const UnicodeString &expected,    // expected formatted result
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           UErrorCode &status) {
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormatSymbols symbols(Locale::getUS(), status);
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // printf("Pattern = %s\n", UnicodeStringPiece(pattern).data());
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    DecimalFormat fmtr(pattern, symbols, status);
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, u_errorName(status));
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (round=="ceiling") {
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundCeiling);
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="floor") {
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="down") {
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundDown);
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="up") {
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundUp);
39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="halfeven") {
39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundHalfEven);
39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="halfdown") {
39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundHalfDown);
39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="halfup") {
39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundHalfUp);
39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else if (round=="default") {
39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // don't set any value.
400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else if (round=="unnecessary") {
401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fmtr.setRoundingMode(DecimalFormat::kRoundUnnecessary);
40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
40450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: Bad rounding mode \"%s\"",
40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lineNum, UnicodeStringPiece(round).data());
40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString result;
40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeStringPiece spInput(input);
41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //fmtr.format(spInput, result, NULL, status);
41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    Formattable fmtbl;
41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fmtbl.setDecimalNumber(spInput, status);
41427f654740f2a26ad62a5c155af9199af9e69b889claireho    //NumberFormat &nfmtr = fmtr;
41550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fmtr.format(fmtbl, result, NULL, status);
41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ((status == U_FORMAT_INEXACT_ERROR) && (result == "") && (expected == "Inexact")) {
418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // Test succeeded.
419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_ZERO_ERROR;
420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return;
421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: format() returned %s.",
42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, u_errorName(status));
425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_ZERO_ERROR;
42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
42750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (result != expected) {
43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lineNum, UnicodeStringPiece(expected).data(), UnicodeStringPiece(result).data());
43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
43550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//-------------------------------------------------------------------------------
43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//  Read a text data file, convert it from UTF-8 to UChars, and return the data
43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    in one big UChar * buffer, which the caller must delete.
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//    (Lightly modified version of a similar function in regextst.cpp)
44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//
44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//--------------------------------------------------------------------------------
44450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUChar *DecimalFormatTest::ReadAndConvertFile(const char *fileName, int32_t &ulen,
44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     UErrorCode &status) {
44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar       *retPtr  = NULL;
44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char        *fileBuf = NULL;
44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char  *fileBufNoBOM = NULL;
44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    FILE        *f       = NULL;
45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ulen = 0;
45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return retPtr;
45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Open the file.
45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    f = fopen(fileName, "rb");
46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (f == 0) {
46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Error opening test data file %s\n", fileName);
46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_FILE_ACCESS_ERROR;
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return NULL;
46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  Read it in
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t            fileSize;
46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t            amtRead;
47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t            amtReadNoBOM;
47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fseek( f, 0, SEEK_END);
47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fileSize = ftell(f);
47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fileBuf = new char[fileSize];
47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fseek(f, 0, SEEK_SET);
47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    amtRead = fread(fileBuf, 1, fileSize, f);
47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (amtRead != fileSize || fileSize <= 0) {
47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("Error reading test data file.");
47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto cleanUpAndReturn;
48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Look for a UTF-8 BOM on the data just read.
48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    The test data file is UTF-8.
48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    The BOM needs to be there in the source file to keep the Windows &
48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    EBCDIC machines happy, so force an error if it goes missing.
48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //    Many Linux editors will silently strip it.
48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fileBufNoBOM = fileBuf + 3;
49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    amtReadNoBOM = amtRead - 3;
49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fileSize<3 || uprv_strncmp(fileBuf, "\xEF\xBB\xBF", 3) != 0) {
49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // TODO:  restore this check.
49327f654740f2a26ad62a5c155af9199af9e69b889claireho        errln("Test data file %s is missing its BOM", fileName);
49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        fileBufNoBOM = fileBuf;
49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        amtReadNoBOM = amtRead;
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Find the length of the input in UTF-16 UChars
50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //  (by preflighting the conversion)
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    u_strFromUTF8(NULL, 0, &ulen, fileBufNoBOM, amtReadNoBOM, &status);
50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Convert file contents from UTF-8 to UTF-16
50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //
50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (status == U_BUFFER_OVERFLOW_ERROR) {
50850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Buffer Overflow is expected from the preflight operation.
50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        status = U_ZERO_ERROR;
51050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        retPtr = new UChar[ulen+1];
51150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        u_strFromUTF8(retPtr, ulen+1, NULL, fileBufNoBOM, amtReadNoBOM, &status);
51250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
51450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocleanUpAndReturn:
51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fclose(f);
51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    delete[] fileBuf;
51750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
51850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errln("ICU Error \"%s\"\n", u_errorName(status));
51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete retPtr;
52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        retPtr = NULL;
52150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    };
52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return retPtr;
52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif  /* !UCONFIG_NO_REGULAR_EXPRESSIONS  */
52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
527