12e5b6d6dSopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci/********************************************************************
42e5b6d6dSopenharmony_ci * COPYRIGHT:
52e5b6d6dSopenharmony_ci * Copyright (c) 1997-2016, International Business Machines Corporation and
62e5b6d6dSopenharmony_ci * others. All Rights Reserved.
72e5b6d6dSopenharmony_ci ********************************************************************/
82e5b6d6dSopenharmony_ci
92e5b6d6dSopenharmony_ci
102e5b6d6dSopenharmony_ci#include "unicode/utypes.h"
112e5b6d6dSopenharmony_ci
122e5b6d6dSopenharmony_ci/**
132e5b6d6dSopenharmony_ci * IntlTest is a base class for tests.
142e5b6d6dSopenharmony_ci */
152e5b6d6dSopenharmony_ci
162e5b6d6dSopenharmony_ci#include <assert.h>
172e5b6d6dSopenharmony_ci#include <stdarg.h>
182e5b6d6dSopenharmony_ci#include <stdio.h>
192e5b6d6dSopenharmony_ci#include <stdlib.h>
202e5b6d6dSopenharmony_ci#include <string.h>
212e5b6d6dSopenharmony_ci#include <cmath>
222e5b6d6dSopenharmony_ci#include <math.h>
232e5b6d6dSopenharmony_ci
242e5b6d6dSopenharmony_ci#include "unicode/ctest.h" // for str_timeDelta
252e5b6d6dSopenharmony_ci#include "unicode/curramt.h"
262e5b6d6dSopenharmony_ci#include "unicode/locid.h"
272e5b6d6dSopenharmony_ci#include "unicode/putil.h"
282e5b6d6dSopenharmony_ci#include "unicode/smpdtfmt.h"
292e5b6d6dSopenharmony_ci#include "unicode/timezone.h"
302e5b6d6dSopenharmony_ci#include "unicode/uclean.h"
312e5b6d6dSopenharmony_ci#include "unicode/ucnv.h"
322e5b6d6dSopenharmony_ci#include "unicode/unistr.h"
332e5b6d6dSopenharmony_ci#include "unicode/ures.h"
342e5b6d6dSopenharmony_ci#include "unicode/utf16.h"
352e5b6d6dSopenharmony_ci
362e5b6d6dSopenharmony_ci#include "intltest.h"
372e5b6d6dSopenharmony_ci
382e5b6d6dSopenharmony_ci#include "caltztst.h"
392e5b6d6dSopenharmony_ci#include "cmemory.h"
402e5b6d6dSopenharmony_ci#include "cstring.h"
412e5b6d6dSopenharmony_ci#include "itmajor.h"
422e5b6d6dSopenharmony_ci#include "lstmbe.h"
432e5b6d6dSopenharmony_ci#include "mutex.h"
442e5b6d6dSopenharmony_ci#include "putilimp.h" // for uprv_getRawUTCtime()
452e5b6d6dSopenharmony_ci#include "uassert.h"
462e5b6d6dSopenharmony_ci#include "udbgutil.h"
472e5b6d6dSopenharmony_ci#include "umutex.h"
482e5b6d6dSopenharmony_ci#include "uoptions.h"
492e5b6d6dSopenharmony_ci#include "number_decnum.h"
502e5b6d6dSopenharmony_ci
512e5b6d6dSopenharmony_ci#ifdef XP_MAC_CONSOLE
522e5b6d6dSopenharmony_ci#include <console.h>
532e5b6d6dSopenharmony_ci#include "Files.h"
542e5b6d6dSopenharmony_ci#endif
552e5b6d6dSopenharmony_ci
562e5b6d6dSopenharmony_ci
572e5b6d6dSopenharmony_cistatic char* _testDataPath=NULL;
582e5b6d6dSopenharmony_ci
592e5b6d6dSopenharmony_ci// Static list of errors found
602e5b6d6dSopenharmony_cistatic UnicodeString errorList;
612e5b6d6dSopenharmony_cistatic void *knownList = NULL; // known issues
622e5b6d6dSopenharmony_cistatic UBool noKnownIssues = false; // if true, don't emit known issues
632e5b6d6dSopenharmony_ci
642e5b6d6dSopenharmony_ci//-----------------------------------------------------------------------------
652e5b6d6dSopenharmony_ci//convenience classes to ease porting code that uses the Java
662e5b6d6dSopenharmony_ci//string-concatenation operator (moved from findword test by rtg)
672e5b6d6dSopenharmony_ci
682e5b6d6dSopenharmony_ci// [LIU] Just to get things working
692e5b6d6dSopenharmony_ciUnicodeString
702e5b6d6dSopenharmony_ciUCharToUnicodeString(UChar c)
712e5b6d6dSopenharmony_ci{ return UnicodeString(c); }
722e5b6d6dSopenharmony_ci
732e5b6d6dSopenharmony_ci// [rtg] Just to get things working
742e5b6d6dSopenharmony_ciUnicodeString
752e5b6d6dSopenharmony_cioperator+(const UnicodeString& left,
762e5b6d6dSopenharmony_ci      long num)
772e5b6d6dSopenharmony_ci{
782e5b6d6dSopenharmony_ci    char buffer[64];    // nos changed from 10 to 64
792e5b6d6dSopenharmony_ci    char danger = 'p';  // guard against overrunning the buffer (rtg)
802e5b6d6dSopenharmony_ci
812e5b6d6dSopenharmony_ci    sprintf(buffer, "%ld", num);
822e5b6d6dSopenharmony_ci    assert(danger == 'p');
832e5b6d6dSopenharmony_ci
842e5b6d6dSopenharmony_ci    return left + buffer;
852e5b6d6dSopenharmony_ci}
862e5b6d6dSopenharmony_ci
872e5b6d6dSopenharmony_ciUnicodeString
882e5b6d6dSopenharmony_cioperator+(const UnicodeString& left,
892e5b6d6dSopenharmony_ci      unsigned long num)
902e5b6d6dSopenharmony_ci{
912e5b6d6dSopenharmony_ci    char buffer[64];    // nos changed from 10 to 64
922e5b6d6dSopenharmony_ci    char danger = 'p';  // guard against overrunning the buffer (rtg)
932e5b6d6dSopenharmony_ci
942e5b6d6dSopenharmony_ci    sprintf(buffer, "%lu", num);
952e5b6d6dSopenharmony_ci    assert(danger == 'p');
962e5b6d6dSopenharmony_ci
972e5b6d6dSopenharmony_ci    return left + buffer;
982e5b6d6dSopenharmony_ci}
992e5b6d6dSopenharmony_ci
1002e5b6d6dSopenharmony_ciUnicodeString
1012e5b6d6dSopenharmony_ciInt64ToUnicodeString(int64_t num)
1022e5b6d6dSopenharmony_ci{
1032e5b6d6dSopenharmony_ci    char buffer[64];    // nos changed from 10 to 64
1042e5b6d6dSopenharmony_ci    char danger = 'p';  // guard against overrunning the buffer (rtg)
1052e5b6d6dSopenharmony_ci
1062e5b6d6dSopenharmony_ci#if defined(_MSC_VER)
1072e5b6d6dSopenharmony_ci    sprintf(buffer, "%I64d", num);
1082e5b6d6dSopenharmony_ci#else
1092e5b6d6dSopenharmony_ci    sprintf(buffer, "%lld", (long long)num);
1102e5b6d6dSopenharmony_ci#endif
1112e5b6d6dSopenharmony_ci    assert(danger == 'p');
1122e5b6d6dSopenharmony_ci
1132e5b6d6dSopenharmony_ci    return buffer;
1142e5b6d6dSopenharmony_ci}
1152e5b6d6dSopenharmony_ci
1162e5b6d6dSopenharmony_ciUnicodeString
1172e5b6d6dSopenharmony_ciDoubleToUnicodeString(double num)
1182e5b6d6dSopenharmony_ci{
1192e5b6d6dSopenharmony_ci    char buffer[64];    // nos changed from 10 to 64
1202e5b6d6dSopenharmony_ci    char danger = 'p';  // guard against overrunning the buffer (rtg)
1212e5b6d6dSopenharmony_ci
1222e5b6d6dSopenharmony_ci    sprintf(buffer, "%1.14e", num);
1232e5b6d6dSopenharmony_ci    assert(danger == 'p');
1242e5b6d6dSopenharmony_ci
1252e5b6d6dSopenharmony_ci    return buffer;
1262e5b6d6dSopenharmony_ci}
1272e5b6d6dSopenharmony_ci
1282e5b6d6dSopenharmony_ci// [LIU] Just to get things working
1292e5b6d6dSopenharmony_ciUnicodeString
1302e5b6d6dSopenharmony_cioperator+(const UnicodeString& left,
1312e5b6d6dSopenharmony_ci      double num)
1322e5b6d6dSopenharmony_ci{
1332e5b6d6dSopenharmony_ci    char buffer[64];   // was 32, made it arbitrarily bigger (rtg)
1342e5b6d6dSopenharmony_ci    char danger = 'p'; // guard against overrunning the buffer (rtg)
1352e5b6d6dSopenharmony_ci
1362e5b6d6dSopenharmony_ci    // IEEE floating point has 52 bits of mantissa, plus one assumed bit
1372e5b6d6dSopenharmony_ci    //  53*log(2)/log(10) = 15.95
1382e5b6d6dSopenharmony_ci    // so there is no need to show more than 16 digits. [alan]
1392e5b6d6dSopenharmony_ci
1402e5b6d6dSopenharmony_ci    sprintf(buffer, "%.17g", num);
1412e5b6d6dSopenharmony_ci    assert(danger == 'p');
1422e5b6d6dSopenharmony_ci
1432e5b6d6dSopenharmony_ci    return left + buffer;
1442e5b6d6dSopenharmony_ci}
1452e5b6d6dSopenharmony_ci
1462e5b6d6dSopenharmony_ci#if 0
1472e5b6d6dSopenharmony_ciUnicodeString
1482e5b6d6dSopenharmony_cioperator+(const UnicodeString& left,
1492e5b6d6dSopenharmony_ci          int64_t num) {
1502e5b6d6dSopenharmony_ci  return left + Int64ToUnicodeString(num);
1512e5b6d6dSopenharmony_ci}
1522e5b6d6dSopenharmony_ci#endif
1532e5b6d6dSopenharmony_ci
1542e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
1552e5b6d6dSopenharmony_ci
1562e5b6d6dSopenharmony_ci/**
1572e5b6d6dSopenharmony_ci * Return a string display for this, without surrounding braces.
1582e5b6d6dSopenharmony_ci */
1592e5b6d6dSopenharmony_ciUnicodeString _toString(const Formattable& f) {
1602e5b6d6dSopenharmony_ci    UnicodeString s;
1612e5b6d6dSopenharmony_ci    switch (f.getType()) {
1622e5b6d6dSopenharmony_ci    case Formattable::kDate:
1632e5b6d6dSopenharmony_ci        {
1642e5b6d6dSopenharmony_ci            UErrorCode status = U_ZERO_ERROR;
1652e5b6d6dSopenharmony_ci            SimpleDateFormat fmt(status);
1662e5b6d6dSopenharmony_ci            if (U_SUCCESS(status)) {
1672e5b6d6dSopenharmony_ci                FieldPosition pos;
1682e5b6d6dSopenharmony_ci                fmt.format(f.getDate(), s, pos);
1692e5b6d6dSopenharmony_ci                s.insert(0, "Date:");
1702e5b6d6dSopenharmony_ci            } else {
1712e5b6d6dSopenharmony_ci                s = UnicodeString("Error creating date format]");
1722e5b6d6dSopenharmony_ci            }
1732e5b6d6dSopenharmony_ci        }
1742e5b6d6dSopenharmony_ci        break;
1752e5b6d6dSopenharmony_ci    case Formattable::kDouble:
1762e5b6d6dSopenharmony_ci        s = UnicodeString("double:") + f.getDouble();
1772e5b6d6dSopenharmony_ci        break;
1782e5b6d6dSopenharmony_ci    case Formattable::kLong:
1792e5b6d6dSopenharmony_ci        s = UnicodeString("long:") + f.getLong();
1802e5b6d6dSopenharmony_ci        break;
1812e5b6d6dSopenharmony_ci
1822e5b6d6dSopenharmony_ci    case Formattable::kInt64:
1832e5b6d6dSopenharmony_ci        s = UnicodeString("int64:") + Int64ToUnicodeString(f.getInt64());
1842e5b6d6dSopenharmony_ci        break;
1852e5b6d6dSopenharmony_ci
1862e5b6d6dSopenharmony_ci    case Formattable::kString:
1872e5b6d6dSopenharmony_ci        f.getString(s);
1882e5b6d6dSopenharmony_ci        s.insert(0, "String:");
1892e5b6d6dSopenharmony_ci        break;
1902e5b6d6dSopenharmony_ci    case Formattable::kArray:
1912e5b6d6dSopenharmony_ci        {
1922e5b6d6dSopenharmony_ci            int32_t i, n;
1932e5b6d6dSopenharmony_ci            const Formattable* array = f.getArray(n);
1942e5b6d6dSopenharmony_ci            s.insert(0, UnicodeString("Array:"));
1952e5b6d6dSopenharmony_ci            UnicodeString delim(", ");
1962e5b6d6dSopenharmony_ci            for (i=0; i<n; ++i) {
1972e5b6d6dSopenharmony_ci                if (i > 0) {
1982e5b6d6dSopenharmony_ci                    s.append(delim);
1992e5b6d6dSopenharmony_ci                }
2002e5b6d6dSopenharmony_ci                s = s + _toString(array[i]);
2012e5b6d6dSopenharmony_ci            }
2022e5b6d6dSopenharmony_ci        }
2032e5b6d6dSopenharmony_ci        break;
2042e5b6d6dSopenharmony_ci    case Formattable::kObject: {
2052e5b6d6dSopenharmony_ci        const CurrencyAmount* c = dynamic_cast<const CurrencyAmount*>(f.getObject());
2062e5b6d6dSopenharmony_ci        if (c != NULL) {
2072e5b6d6dSopenharmony_ci            s = _toString(c->getNumber()) + " " + UnicodeString(c->getISOCurrency());
2082e5b6d6dSopenharmony_ci        } else {
2092e5b6d6dSopenharmony_ci            s = UnicodeString("Unknown UObject");
2102e5b6d6dSopenharmony_ci        }
2112e5b6d6dSopenharmony_ci        break;
2122e5b6d6dSopenharmony_ci    }
2132e5b6d6dSopenharmony_ci    default:
2142e5b6d6dSopenharmony_ci        s = UnicodeString("Unknown Formattable type=") + (int32_t)f.getType();
2152e5b6d6dSopenharmony_ci        break;
2162e5b6d6dSopenharmony_ci    }
2172e5b6d6dSopenharmony_ci    return s;
2182e5b6d6dSopenharmony_ci}
2192e5b6d6dSopenharmony_ci
2202e5b6d6dSopenharmony_ci/**
2212e5b6d6dSopenharmony_ci * Originally coded this as operator+, but that makes the expression
2222e5b6d6dSopenharmony_ci * + char* ambiguous. - liu
2232e5b6d6dSopenharmony_ci */
2242e5b6d6dSopenharmony_ciUnicodeString toString(const Formattable& f) {
2252e5b6d6dSopenharmony_ci    UnicodeString s((UChar)91/*[*/);
2262e5b6d6dSopenharmony_ci    s.append(_toString(f));
2272e5b6d6dSopenharmony_ci    s.append((UChar)0x5d/*]*/);
2282e5b6d6dSopenharmony_ci    return s;
2292e5b6d6dSopenharmony_ci}
2302e5b6d6dSopenharmony_ci
2312e5b6d6dSopenharmony_ci#endif
2322e5b6d6dSopenharmony_ci
2332e5b6d6dSopenharmony_ci// useful when operator+ won't cooperate
2342e5b6d6dSopenharmony_ciUnicodeString toString(int32_t n) {
2352e5b6d6dSopenharmony_ci    return UnicodeString() + (long)n;
2362e5b6d6dSopenharmony_ci}
2372e5b6d6dSopenharmony_ci
2382e5b6d6dSopenharmony_ci
2392e5b6d6dSopenharmony_ci
2402e5b6d6dSopenharmony_ciUnicodeString toString(UBool b) {
2412e5b6d6dSopenharmony_ci  return b ? UnicodeString("true"):UnicodeString("false");
2422e5b6d6dSopenharmony_ci}
2432e5b6d6dSopenharmony_ci
2442e5b6d6dSopenharmony_ciUnicodeString toString(const UnicodeSet& uniset, UErrorCode& status) {
2452e5b6d6dSopenharmony_ci    UnicodeString result;
2462e5b6d6dSopenharmony_ci    uniset.toPattern(result, status);
2472e5b6d6dSopenharmony_ci    return result;
2482e5b6d6dSopenharmony_ci}
2492e5b6d6dSopenharmony_ci
2502e5b6d6dSopenharmony_ci// stephen - cleaned up 05/05/99
2512e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, char num)
2522e5b6d6dSopenharmony_ci{ return left + (long)num; }
2532e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, short num)
2542e5b6d6dSopenharmony_ci{ return left + (long)num; }
2552e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, int num)
2562e5b6d6dSopenharmony_ci{ return left + (long)num; }
2572e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, unsigned char num)
2582e5b6d6dSopenharmony_ci{ return left + (unsigned long)num; }
2592e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, unsigned short num)
2602e5b6d6dSopenharmony_ci{ return left + (unsigned long)num; }
2612e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, unsigned int num)
2622e5b6d6dSopenharmony_ci{ return left + (unsigned long)num; }
2632e5b6d6dSopenharmony_ciUnicodeString operator+(const UnicodeString& left, float num)
2642e5b6d6dSopenharmony_ci{ return left + (double)num; }
2652e5b6d6dSopenharmony_ci
2662e5b6d6dSopenharmony_ci//------------------
2672e5b6d6dSopenharmony_ci
2682e5b6d6dSopenharmony_ci// Append a hex string to the target
2692e5b6d6dSopenharmony_ciUnicodeString&
2702e5b6d6dSopenharmony_ciIntlTest::appendHex(uint32_t number,
2712e5b6d6dSopenharmony_ci            int32_t digits,
2722e5b6d6dSopenharmony_ci            UnicodeString& target)
2732e5b6d6dSopenharmony_ci{
2742e5b6d6dSopenharmony_ci    static const UChar digitString[] = {
2752e5b6d6dSopenharmony_ci        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
2762e5b6d6dSopenharmony_ci        0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
2772e5b6d6dSopenharmony_ci    }; /* "0123456789ABCDEF" */
2782e5b6d6dSopenharmony_ci
2792e5b6d6dSopenharmony_ci    if (digits < 0) {  // auto-digits
2802e5b6d6dSopenharmony_ci        digits = 2;
2812e5b6d6dSopenharmony_ci        uint32_t max = 0xff;
2822e5b6d6dSopenharmony_ci        while (number > max) {
2832e5b6d6dSopenharmony_ci            digits += 2;
2842e5b6d6dSopenharmony_ci            max = (max << 8) | 0xff;
2852e5b6d6dSopenharmony_ci        }
2862e5b6d6dSopenharmony_ci    }
2872e5b6d6dSopenharmony_ci    switch (digits)
2882e5b6d6dSopenharmony_ci    {
2892e5b6d6dSopenharmony_ci    case 8:
2902e5b6d6dSopenharmony_ci        target += digitString[(number >> 28) & 0xF];
2912e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
2922e5b6d6dSopenharmony_ci    case 7:
2932e5b6d6dSopenharmony_ci        target += digitString[(number >> 24) & 0xF];
2942e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
2952e5b6d6dSopenharmony_ci    case 6:
2962e5b6d6dSopenharmony_ci        target += digitString[(number >> 20) & 0xF];
2972e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
2982e5b6d6dSopenharmony_ci    case 5:
2992e5b6d6dSopenharmony_ci        target += digitString[(number >> 16) & 0xF];
3002e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
3012e5b6d6dSopenharmony_ci    case 4:
3022e5b6d6dSopenharmony_ci        target += digitString[(number >> 12) & 0xF];
3032e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
3042e5b6d6dSopenharmony_ci    case 3:
3052e5b6d6dSopenharmony_ci        target += digitString[(number >>  8) & 0xF];
3062e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
3072e5b6d6dSopenharmony_ci    case 2:
3082e5b6d6dSopenharmony_ci        target += digitString[(number >>  4) & 0xF];
3092e5b6d6dSopenharmony_ci        U_FALLTHROUGH;
3102e5b6d6dSopenharmony_ci    case 1:
3112e5b6d6dSopenharmony_ci        target += digitString[(number >>  0) & 0xF];
3122e5b6d6dSopenharmony_ci        break;
3132e5b6d6dSopenharmony_ci    default:
3142e5b6d6dSopenharmony_ci        target += "**";
3152e5b6d6dSopenharmony_ci    }
3162e5b6d6dSopenharmony_ci    return target;
3172e5b6d6dSopenharmony_ci}
3182e5b6d6dSopenharmony_ci
3192e5b6d6dSopenharmony_ciUnicodeString
3202e5b6d6dSopenharmony_ciIntlTest::toHex(uint32_t number, int32_t digits) {
3212e5b6d6dSopenharmony_ci    UnicodeString result;
3222e5b6d6dSopenharmony_ci    appendHex(number, digits, result);
3232e5b6d6dSopenharmony_ci    return result;
3242e5b6d6dSopenharmony_ci}
3252e5b6d6dSopenharmony_ci
3262e5b6d6dSopenharmony_cistatic inline UBool isPrintable(UChar32 c) {
3272e5b6d6dSopenharmony_ci    return c <= 0x7E && (c >= 0x20 || c == 9 || c == 0xA || c == 0xD);
3282e5b6d6dSopenharmony_ci}
3292e5b6d6dSopenharmony_ci
3302e5b6d6dSopenharmony_ci// Replace nonprintable characters with unicode escapes
3312e5b6d6dSopenharmony_ciUnicodeString&
3322e5b6d6dSopenharmony_ciIntlTest::prettify(const UnicodeString &source,
3332e5b6d6dSopenharmony_ci           UnicodeString &target)
3342e5b6d6dSopenharmony_ci{
3352e5b6d6dSopenharmony_ci    int32_t i;
3362e5b6d6dSopenharmony_ci
3372e5b6d6dSopenharmony_ci    target.remove();
3382e5b6d6dSopenharmony_ci    target += "\"";
3392e5b6d6dSopenharmony_ci
3402e5b6d6dSopenharmony_ci    for (i = 0; i < source.length(); )
3412e5b6d6dSopenharmony_ci    {
3422e5b6d6dSopenharmony_ci        UChar32 ch = source.char32At(i);
3432e5b6d6dSopenharmony_ci        i += U16_LENGTH(ch);
3442e5b6d6dSopenharmony_ci
3452e5b6d6dSopenharmony_ci        if (!isPrintable(ch))
3462e5b6d6dSopenharmony_ci        {
3472e5b6d6dSopenharmony_ci            if (ch <= 0xFFFF) {
3482e5b6d6dSopenharmony_ci                target += "\\u";
3492e5b6d6dSopenharmony_ci                appendHex(ch, 4, target);
3502e5b6d6dSopenharmony_ci            } else {
3512e5b6d6dSopenharmony_ci                target += "\\U";
3522e5b6d6dSopenharmony_ci                appendHex(ch, 8, target);
3532e5b6d6dSopenharmony_ci            }
3542e5b6d6dSopenharmony_ci        }
3552e5b6d6dSopenharmony_ci        else
3562e5b6d6dSopenharmony_ci        {
3572e5b6d6dSopenharmony_ci            target += ch;
3582e5b6d6dSopenharmony_ci        }
3592e5b6d6dSopenharmony_ci    }
3602e5b6d6dSopenharmony_ci
3612e5b6d6dSopenharmony_ci    target += "\"";
3622e5b6d6dSopenharmony_ci
3632e5b6d6dSopenharmony_ci    return target;
3642e5b6d6dSopenharmony_ci}
3652e5b6d6dSopenharmony_ci
3662e5b6d6dSopenharmony_ci// Replace nonprintable characters with unicode escapes
3672e5b6d6dSopenharmony_ciUnicodeString
3682e5b6d6dSopenharmony_ciIntlTest::prettify(const UnicodeString &source, UBool parseBackslash)
3692e5b6d6dSopenharmony_ci{
3702e5b6d6dSopenharmony_ci    int32_t i;
3712e5b6d6dSopenharmony_ci    UnicodeString target;
3722e5b6d6dSopenharmony_ci    target.remove();
3732e5b6d6dSopenharmony_ci    target += "\"";
3742e5b6d6dSopenharmony_ci
3752e5b6d6dSopenharmony_ci    for (i = 0; i < source.length();)
3762e5b6d6dSopenharmony_ci    {
3772e5b6d6dSopenharmony_ci        UChar32 ch = source.char32At(i);
3782e5b6d6dSopenharmony_ci        i += U16_LENGTH(ch);
3792e5b6d6dSopenharmony_ci
3802e5b6d6dSopenharmony_ci        if (!isPrintable(ch))
3812e5b6d6dSopenharmony_ci        {
3822e5b6d6dSopenharmony_ci            if (parseBackslash) {
3832e5b6d6dSopenharmony_ci                // If we are preceded by an odd number of backslashes,
3842e5b6d6dSopenharmony_ci                // then this character has already been backslash escaped.
3852e5b6d6dSopenharmony_ci                // Delete a backslash.
3862e5b6d6dSopenharmony_ci                int32_t backslashCount = 0;
3872e5b6d6dSopenharmony_ci                for (int32_t j=target.length()-1; j>=0; --j) {
3882e5b6d6dSopenharmony_ci                    if (target.charAt(j) == (UChar)92) {
3892e5b6d6dSopenharmony_ci                        ++backslashCount;
3902e5b6d6dSopenharmony_ci                    } else {
3912e5b6d6dSopenharmony_ci                        break;
3922e5b6d6dSopenharmony_ci                    }
3932e5b6d6dSopenharmony_ci                }
3942e5b6d6dSopenharmony_ci                if ((backslashCount % 2) == 1) {
3952e5b6d6dSopenharmony_ci                    target.truncate(target.length() - 1);
3962e5b6d6dSopenharmony_ci                }
3972e5b6d6dSopenharmony_ci            }
3982e5b6d6dSopenharmony_ci            if (ch <= 0xFFFF) {
3992e5b6d6dSopenharmony_ci                target += "\\u";
4002e5b6d6dSopenharmony_ci                appendHex(ch, 4, target);
4012e5b6d6dSopenharmony_ci            } else {
4022e5b6d6dSopenharmony_ci                target += "\\U";
4032e5b6d6dSopenharmony_ci                appendHex(ch, 8, target);
4042e5b6d6dSopenharmony_ci            }
4052e5b6d6dSopenharmony_ci        }
4062e5b6d6dSopenharmony_ci        else
4072e5b6d6dSopenharmony_ci        {
4082e5b6d6dSopenharmony_ci            target += ch;
4092e5b6d6dSopenharmony_ci        }
4102e5b6d6dSopenharmony_ci    }
4112e5b6d6dSopenharmony_ci
4122e5b6d6dSopenharmony_ci    target += "\"";
4132e5b6d6dSopenharmony_ci
4142e5b6d6dSopenharmony_ci    return target;
4152e5b6d6dSopenharmony_ci}
4162e5b6d6dSopenharmony_ci
4172e5b6d6dSopenharmony_ci/*  IntlTest::setICU_DATA  - if the ICU_DATA environment variable is not already
4182e5b6d6dSopenharmony_ci *                       set, try to deduce the directory in which ICU was built,
4192e5b6d6dSopenharmony_ci *                       and set ICU_DATA to "icu/source/data" in that location.
4202e5b6d6dSopenharmony_ci *                       The intent is to allow the tests to have a good chance
4212e5b6d6dSopenharmony_ci *                       of running without requiring that the user manually set
4222e5b6d6dSopenharmony_ci *                       ICU_DATA.  Common data isn't a problem, since it is
4232e5b6d6dSopenharmony_ci *                       picked up via a static (build time) reference, but the
4242e5b6d6dSopenharmony_ci *                       tests dynamically load some data.
4252e5b6d6dSopenharmony_ci */
4262e5b6d6dSopenharmony_civoid IntlTest::setICU_DATA() {
4272e5b6d6dSopenharmony_ci    const char *original_ICU_DATA = getenv("ICU_DATA");
4282e5b6d6dSopenharmony_ci
4292e5b6d6dSopenharmony_ci    if (original_ICU_DATA != NULL && *original_ICU_DATA != 0) {
4302e5b6d6dSopenharmony_ci        /*  If the user set ICU_DATA, don't second-guess the person. */
4312e5b6d6dSopenharmony_ci        return;
4322e5b6d6dSopenharmony_ci    }
4332e5b6d6dSopenharmony_ci
4342e5b6d6dSopenharmony_ci    // U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
4352e5b6d6dSopenharmony_ci    //              to point to the top of the build hierarchy, which may or
4362e5b6d6dSopenharmony_ci    //              may not be the same as the source directory, depending on
4372e5b6d6dSopenharmony_ci    //              the configure options used.  At any rate,
4382e5b6d6dSopenharmony_ci    //              set the data path to the built data from this directory.
4392e5b6d6dSopenharmony_ci    //              The value is complete with quotes, so it can be used
4402e5b6d6dSopenharmony_ci    //              as-is as a string constant.
4412e5b6d6dSopenharmony_ci
4422e5b6d6dSopenharmony_ci#if defined (U_TOPBUILDDIR)
4432e5b6d6dSopenharmony_ci    {
4442e5b6d6dSopenharmony_ci        static char env_string[] = U_TOPBUILDDIR "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
4452e5b6d6dSopenharmony_ci        u_setDataDirectory(env_string);
4462e5b6d6dSopenharmony_ci        return;
4472e5b6d6dSopenharmony_ci    }
4482e5b6d6dSopenharmony_ci
4492e5b6d6dSopenharmony_ci#else
4502e5b6d6dSopenharmony_ci    // Use #else so we don't get compiler warnings due to the return above.
4512e5b6d6dSopenharmony_ci
4522e5b6d6dSopenharmony_ci    /* On Windows, the file name obtained from __FILE__ includes a full path.
4532e5b6d6dSopenharmony_ci     *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
4542e5b6d6dSopenharmony_ci     *             Change to    "wherever\icu\source\data"
4552e5b6d6dSopenharmony_ci     */
4562e5b6d6dSopenharmony_ci    {
4572e5b6d6dSopenharmony_ci        char p[sizeof(__FILE__) + 10];
4582e5b6d6dSopenharmony_ci        char *pBackSlash;
4592e5b6d6dSopenharmony_ci        int i;
4602e5b6d6dSopenharmony_ci
4612e5b6d6dSopenharmony_ci        strcpy(p, __FILE__);
4622e5b6d6dSopenharmony_ci        /* We want to back over three '\' chars.                            */
4632e5b6d6dSopenharmony_ci        /*   Only Windows should end up here, so looking for '\' is safe.   */
4642e5b6d6dSopenharmony_ci        for (i=1; i<=3; i++) {
4652e5b6d6dSopenharmony_ci            pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
4662e5b6d6dSopenharmony_ci            if (pBackSlash != NULL) {
4672e5b6d6dSopenharmony_ci                *pBackSlash = 0;        /* Truncate the string at the '\'   */
4682e5b6d6dSopenharmony_ci            }
4692e5b6d6dSopenharmony_ci        }
4702e5b6d6dSopenharmony_ci
4712e5b6d6dSopenharmony_ci        if (pBackSlash != NULL) {
4722e5b6d6dSopenharmony_ci            /* We found and truncated three names from the path.
4732e5b6d6dSopenharmony_ci             *  Now append "source\data" and set the environment
4742e5b6d6dSopenharmony_ci             */
4752e5b6d6dSopenharmony_ci            strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
4762e5b6d6dSopenharmony_ci            u_setDataDirectory(p);     /*  p is "ICU_DATA=wherever\icu\source\data"    */
4772e5b6d6dSopenharmony_ci            return;
4782e5b6d6dSopenharmony_ci        }
4792e5b6d6dSopenharmony_ci        else {
4802e5b6d6dSopenharmony_ci            /* __FILE__ on MSVC7 does not contain the directory */
4812e5b6d6dSopenharmony_ci            u_setDataDirectory(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
4822e5b6d6dSopenharmony_ci            return;
4832e5b6d6dSopenharmony_ci        }
4842e5b6d6dSopenharmony_ci    }
4852e5b6d6dSopenharmony_ci#endif
4862e5b6d6dSopenharmony_ci
4872e5b6d6dSopenharmony_ci    /* No location for the data dir was identifiable.
4882e5b6d6dSopenharmony_ci     *   Add other fallbacks for the test data location here if the need arises
4892e5b6d6dSopenharmony_ci     */
4902e5b6d6dSopenharmony_ci}
4912e5b6d6dSopenharmony_ci
4922e5b6d6dSopenharmony_ci
4932e5b6d6dSopenharmony_ci//--------------------------------------------------------------------------------------
4942e5b6d6dSopenharmony_ci
4952e5b6d6dSopenharmony_cistatic const int32_t indentLevel_offset = 3;
4962e5b6d6dSopenharmony_cistatic const char delim = '/';
4972e5b6d6dSopenharmony_ci
4982e5b6d6dSopenharmony_ciIntlTest* IntlTest::gTest = NULL;
4992e5b6d6dSopenharmony_ci
5002e5b6d6dSopenharmony_cistatic int32_t execCount = 0;
5012e5b6d6dSopenharmony_ci
5022e5b6d6dSopenharmony_civoid it_log( UnicodeString message )
5032e5b6d6dSopenharmony_ci{
5042e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5052e5b6d6dSopenharmony_ci        IntlTest::gTest->log( message );
5062e5b6d6dSopenharmony_ci}
5072e5b6d6dSopenharmony_ci
5082e5b6d6dSopenharmony_civoid it_logln( UnicodeString message )
5092e5b6d6dSopenharmony_ci{
5102e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5112e5b6d6dSopenharmony_ci        IntlTest::gTest->logln( message );
5122e5b6d6dSopenharmony_ci}
5132e5b6d6dSopenharmony_ci
5142e5b6d6dSopenharmony_civoid it_logln( void )
5152e5b6d6dSopenharmony_ci{
5162e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5172e5b6d6dSopenharmony_ci        IntlTest::gTest->logln();
5182e5b6d6dSopenharmony_ci}
5192e5b6d6dSopenharmony_ci
5202e5b6d6dSopenharmony_civoid it_info( UnicodeString message )
5212e5b6d6dSopenharmony_ci{
5222e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5232e5b6d6dSopenharmony_ci        IntlTest::gTest->info( message );
5242e5b6d6dSopenharmony_ci}
5252e5b6d6dSopenharmony_ci
5262e5b6d6dSopenharmony_civoid it_infoln( UnicodeString message )
5272e5b6d6dSopenharmony_ci{
5282e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5292e5b6d6dSopenharmony_ci        IntlTest::gTest->infoln( message );
5302e5b6d6dSopenharmony_ci}
5312e5b6d6dSopenharmony_ci
5322e5b6d6dSopenharmony_civoid it_infoln( void )
5332e5b6d6dSopenharmony_ci{
5342e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5352e5b6d6dSopenharmony_ci        IntlTest::gTest->infoln();
5362e5b6d6dSopenharmony_ci}
5372e5b6d6dSopenharmony_ci
5382e5b6d6dSopenharmony_civoid it_err()
5392e5b6d6dSopenharmony_ci{
5402e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5412e5b6d6dSopenharmony_ci        IntlTest::gTest->err();
5422e5b6d6dSopenharmony_ci}
5432e5b6d6dSopenharmony_ci
5442e5b6d6dSopenharmony_civoid it_err( UnicodeString message )
5452e5b6d6dSopenharmony_ci{
5462e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5472e5b6d6dSopenharmony_ci        IntlTest::gTest->err( message );
5482e5b6d6dSopenharmony_ci}
5492e5b6d6dSopenharmony_ci
5502e5b6d6dSopenharmony_civoid it_errln( UnicodeString message )
5512e5b6d6dSopenharmony_ci{
5522e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5532e5b6d6dSopenharmony_ci        IntlTest::gTest->errln( message );
5542e5b6d6dSopenharmony_ci}
5552e5b6d6dSopenharmony_ci
5562e5b6d6dSopenharmony_civoid it_dataerr( UnicodeString message )
5572e5b6d6dSopenharmony_ci{
5582e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5592e5b6d6dSopenharmony_ci        IntlTest::gTest->dataerr( message );
5602e5b6d6dSopenharmony_ci}
5612e5b6d6dSopenharmony_ci
5622e5b6d6dSopenharmony_civoid it_dataerrln( UnicodeString message )
5632e5b6d6dSopenharmony_ci{
5642e5b6d6dSopenharmony_ci    if (IntlTest::gTest)
5652e5b6d6dSopenharmony_ci        IntlTest::gTest->dataerrln( message );
5662e5b6d6dSopenharmony_ci}
5672e5b6d6dSopenharmony_ci
5682e5b6d6dSopenharmony_ciIntlTest::IntlTest()
5692e5b6d6dSopenharmony_ci{
5702e5b6d6dSopenharmony_ci    caller = NULL;
5712e5b6d6dSopenharmony_ci    testPath = NULL;
5722e5b6d6dSopenharmony_ci    LL_linestart = true;
5732e5b6d6dSopenharmony_ci    errorCount = 0;
5742e5b6d6dSopenharmony_ci    dataErrorCount = 0;
5752e5b6d6dSopenharmony_ci    verbose = false;
5762e5b6d6dSopenharmony_ci    no_time = false;
5772e5b6d6dSopenharmony_ci    no_err_msg = false;
5782e5b6d6dSopenharmony_ci    warn_on_missing_data = false;
5792e5b6d6dSopenharmony_ci    quick = false;
5802e5b6d6dSopenharmony_ci    leaks = false;
5812e5b6d6dSopenharmony_ci    threadCount = 12;
5822e5b6d6dSopenharmony_ci    testoutfp = stdout;
5832e5b6d6dSopenharmony_ci    LL_indentlevel = indentLevel_offset;
5842e5b6d6dSopenharmony_ci    numProps = 0;
5852e5b6d6dSopenharmony_ci    strcpy(basePath, "/");
5862e5b6d6dSopenharmony_ci    currName[0]=0;
5872e5b6d6dSopenharmony_ci}
5882e5b6d6dSopenharmony_ci
5892e5b6d6dSopenharmony_civoid IntlTest::setCaller( IntlTest* callingTest )
5902e5b6d6dSopenharmony_ci{
5912e5b6d6dSopenharmony_ci    caller = callingTest;
5922e5b6d6dSopenharmony_ci    if (caller) {
5932e5b6d6dSopenharmony_ci        warn_on_missing_data = caller->warn_on_missing_data;
5942e5b6d6dSopenharmony_ci        verbose = caller->verbose;
5952e5b6d6dSopenharmony_ci        no_err_msg = caller->no_err_msg;
5962e5b6d6dSopenharmony_ci        quick = caller->quick;
5972e5b6d6dSopenharmony_ci        threadCount = caller->threadCount;
5982e5b6d6dSopenharmony_ci        testoutfp = caller->testoutfp;
5992e5b6d6dSopenharmony_ci        write_golden_data = caller->write_golden_data;
6002e5b6d6dSopenharmony_ci        LL_indentlevel = caller->LL_indentlevel + indentLevel_offset;
6012e5b6d6dSopenharmony_ci        numProps = caller->numProps;
6022e5b6d6dSopenharmony_ci        for (int32_t i = 0; i < numProps; i++) {
6032e5b6d6dSopenharmony_ci            proplines[i] = caller->proplines[i];
6042e5b6d6dSopenharmony_ci        }
6052e5b6d6dSopenharmony_ci    }
6062e5b6d6dSopenharmony_ci}
6072e5b6d6dSopenharmony_ci
6082e5b6d6dSopenharmony_ciUBool IntlTest::callTest( IntlTest& testToBeCalled, char* par )
6092e5b6d6dSopenharmony_ci{
6102e5b6d6dSopenharmony_ci    execCount--; // correct a previously assumed test-exec, as this only calls a subtest
6112e5b6d6dSopenharmony_ci    testToBeCalled.setCaller( this );
6122e5b6d6dSopenharmony_ci    strcpy(testToBeCalled.basePath, this->basePath );
6132e5b6d6dSopenharmony_ci    UBool result = testToBeCalled.runTest( testPath, par, testToBeCalled.basePath );
6142e5b6d6dSopenharmony_ci    strcpy(testToBeCalled.basePath, this->basePath ); // reset it.
6152e5b6d6dSopenharmony_ci    return result;
6162e5b6d6dSopenharmony_ci}
6172e5b6d6dSopenharmony_ci
6182e5b6d6dSopenharmony_civoid IntlTest::setPath( char* pathVal )
6192e5b6d6dSopenharmony_ci{
6202e5b6d6dSopenharmony_ci    this->testPath = pathVal;
6212e5b6d6dSopenharmony_ci}
6222e5b6d6dSopenharmony_ci
6232e5b6d6dSopenharmony_ciUBool IntlTest::setVerbose( UBool verboseVal )
6242e5b6d6dSopenharmony_ci{
6252e5b6d6dSopenharmony_ci    UBool rval = this->verbose;
6262e5b6d6dSopenharmony_ci    this->verbose = verboseVal;
6272e5b6d6dSopenharmony_ci    return rval;
6282e5b6d6dSopenharmony_ci}
6292e5b6d6dSopenharmony_ci
6302e5b6d6dSopenharmony_ciUBool IntlTest::setNotime( UBool no_time )
6312e5b6d6dSopenharmony_ci{
6322e5b6d6dSopenharmony_ci    UBool rval = this->no_time;
6332e5b6d6dSopenharmony_ci    this->no_time = no_time;
6342e5b6d6dSopenharmony_ci    return rval;
6352e5b6d6dSopenharmony_ci}
6362e5b6d6dSopenharmony_ci
6372e5b6d6dSopenharmony_ciUBool IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal )
6382e5b6d6dSopenharmony_ci{
6392e5b6d6dSopenharmony_ci    UBool rval = this->warn_on_missing_data;
6402e5b6d6dSopenharmony_ci    this->warn_on_missing_data = warn_on_missing_dataVal;
6412e5b6d6dSopenharmony_ci    return rval;
6422e5b6d6dSopenharmony_ci}
6432e5b6d6dSopenharmony_ci
6442e5b6d6dSopenharmony_ciUBool IntlTest::setWriteGoldenData( UBool write_golden_data )
6452e5b6d6dSopenharmony_ci{
6462e5b6d6dSopenharmony_ci    UBool rval = this->write_golden_data;
6472e5b6d6dSopenharmony_ci    this->write_golden_data = write_golden_data;
6482e5b6d6dSopenharmony_ci    return rval;
6492e5b6d6dSopenharmony_ci}
6502e5b6d6dSopenharmony_ci
6512e5b6d6dSopenharmony_ciUBool IntlTest::setNoErrMsg( UBool no_err_msgVal )
6522e5b6d6dSopenharmony_ci{
6532e5b6d6dSopenharmony_ci    UBool rval = this->no_err_msg;
6542e5b6d6dSopenharmony_ci    this->no_err_msg = no_err_msgVal;
6552e5b6d6dSopenharmony_ci    return rval;
6562e5b6d6dSopenharmony_ci}
6572e5b6d6dSopenharmony_ci
6582e5b6d6dSopenharmony_ciUBool IntlTest::setQuick( UBool quickVal )
6592e5b6d6dSopenharmony_ci{
6602e5b6d6dSopenharmony_ci    UBool rval = this->quick;
6612e5b6d6dSopenharmony_ci    this->quick = quickVal;
6622e5b6d6dSopenharmony_ci    return rval;
6632e5b6d6dSopenharmony_ci}
6642e5b6d6dSopenharmony_ci
6652e5b6d6dSopenharmony_ciUBool IntlTest::setLeaks( UBool leaksVal )
6662e5b6d6dSopenharmony_ci{
6672e5b6d6dSopenharmony_ci    UBool rval = this->leaks;
6682e5b6d6dSopenharmony_ci    this->leaks = leaksVal;
6692e5b6d6dSopenharmony_ci    return rval;
6702e5b6d6dSopenharmony_ci}
6712e5b6d6dSopenharmony_ci
6722e5b6d6dSopenharmony_ciint32_t IntlTest::setThreadCount( int32_t count )
6732e5b6d6dSopenharmony_ci{
6742e5b6d6dSopenharmony_ci    int32_t rval = this->threadCount;
6752e5b6d6dSopenharmony_ci    this->threadCount = count;
6762e5b6d6dSopenharmony_ci    return rval;
6772e5b6d6dSopenharmony_ci}
6782e5b6d6dSopenharmony_ci
6792e5b6d6dSopenharmony_ciint32_t IntlTest::getErrors( void )
6802e5b6d6dSopenharmony_ci{
6812e5b6d6dSopenharmony_ci    return errorCount;
6822e5b6d6dSopenharmony_ci}
6832e5b6d6dSopenharmony_ci
6842e5b6d6dSopenharmony_ciint32_t IntlTest::getDataErrors( void )
6852e5b6d6dSopenharmony_ci{
6862e5b6d6dSopenharmony_ci    return dataErrorCount;
6872e5b6d6dSopenharmony_ci}
6882e5b6d6dSopenharmony_ci
6892e5b6d6dSopenharmony_ciUBool IntlTest::runTest( char* name, char* par, char *baseName )
6902e5b6d6dSopenharmony_ci{
6912e5b6d6dSopenharmony_ci    UBool rval;
6922e5b6d6dSopenharmony_ci    char* pos = NULL;
6932e5b6d6dSopenharmony_ci
6942e5b6d6dSopenharmony_ci    char* baseNameBuffer = NULL;
6952e5b6d6dSopenharmony_ci
6962e5b6d6dSopenharmony_ci    if(baseName == NULL) {
6972e5b6d6dSopenharmony_ci      baseNameBuffer = (char*)malloc(1024);
6982e5b6d6dSopenharmony_ci      baseName=baseNameBuffer;
6992e5b6d6dSopenharmony_ci      strcpy(baseName, "/");
7002e5b6d6dSopenharmony_ci    }
7012e5b6d6dSopenharmony_ci
7022e5b6d6dSopenharmony_ci    if (name)
7032e5b6d6dSopenharmony_ci        pos = strchr( name, delim ); // check if name contains path (by looking for '/')
7042e5b6d6dSopenharmony_ci    if (pos) {
7052e5b6d6dSopenharmony_ci        testPath = pos+1;   // store subpath for calling subtest
7062e5b6d6dSopenharmony_ci        *pos = 0;       // split into two strings
7072e5b6d6dSopenharmony_ci    }else{
7082e5b6d6dSopenharmony_ci        testPath = NULL;
7092e5b6d6dSopenharmony_ci    }
7102e5b6d6dSopenharmony_ci
7112e5b6d6dSopenharmony_ci    if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
7122e5b6d6dSopenharmony_ci      rval = runTestLoop( NULL, par, baseName );
7132e5b6d6dSopenharmony_ci
7142e5b6d6dSopenharmony_ci    }else if (strcmp( name, "LIST" ) == 0) {
7152e5b6d6dSopenharmony_ci        this->usage();
7162e5b6d6dSopenharmony_ci        rval = true;
7172e5b6d6dSopenharmony_ci
7182e5b6d6dSopenharmony_ci    }else{
7192e5b6d6dSopenharmony_ci      rval = runTestLoop( name, par, baseName );
7202e5b6d6dSopenharmony_ci    }
7212e5b6d6dSopenharmony_ci
7222e5b6d6dSopenharmony_ci    if (pos)
7232e5b6d6dSopenharmony_ci        *pos = delim;  // restore original value at pos
7242e5b6d6dSopenharmony_ci    if(baseNameBuffer!=NULL) {
7252e5b6d6dSopenharmony_ci      free(baseNameBuffer);
7262e5b6d6dSopenharmony_ci    }
7272e5b6d6dSopenharmony_ci    return rval;
7282e5b6d6dSopenharmony_ci}
7292e5b6d6dSopenharmony_ci
7302e5b6d6dSopenharmony_ci// call individual tests, to be overridden to call implementations
7312e5b6d6dSopenharmony_civoid IntlTest::runIndexedTest( int32_t /*index*/, UBool /*exec*/, const char* & /*name*/, char* /*par*/ )
7322e5b6d6dSopenharmony_ci{
7332e5b6d6dSopenharmony_ci    // to be overridden by a method like:
7342e5b6d6dSopenharmony_ci    /*
7352e5b6d6dSopenharmony_ci    switch (index) {
7362e5b6d6dSopenharmony_ci        case 0: name = "First Test"; if (exec) FirstTest( par ); break;
7372e5b6d6dSopenharmony_ci        case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
7382e5b6d6dSopenharmony_ci        default: name = ""; break;
7392e5b6d6dSopenharmony_ci    }
7402e5b6d6dSopenharmony_ci    */
7412e5b6d6dSopenharmony_ci    this->errln("*** runIndexedTest needs to be overridden! ***");
7422e5b6d6dSopenharmony_ci}
7432e5b6d6dSopenharmony_ci
7442e5b6d6dSopenharmony_ci
7452e5b6d6dSopenharmony_ciUBool IntlTest::runTestLoop( char* testname, char* par, char *baseName )
7462e5b6d6dSopenharmony_ci{
7472e5b6d6dSopenharmony_ci    int32_t    index = 0;
7482e5b6d6dSopenharmony_ci    const char*   name;
7492e5b6d6dSopenharmony_ci    UBool  run_this_test;
7502e5b6d6dSopenharmony_ci    int32_t    lastErrorCount;
7512e5b6d6dSopenharmony_ci    UBool  rval = false;
7522e5b6d6dSopenharmony_ci    UBool   lastTestFailed;
7532e5b6d6dSopenharmony_ci
7542e5b6d6dSopenharmony_ci    if(baseName == NULL) {
7552e5b6d6dSopenharmony_ci      printf("ERROR: baseName can't be null.\n");
7562e5b6d6dSopenharmony_ci      return false;
7572e5b6d6dSopenharmony_ci    } else {
7582e5b6d6dSopenharmony_ci      if ((char *)this->basePath != baseName) {
7592e5b6d6dSopenharmony_ci        strcpy(this->basePath, baseName);
7602e5b6d6dSopenharmony_ci      }
7612e5b6d6dSopenharmony_ci    }
7622e5b6d6dSopenharmony_ci
7632e5b6d6dSopenharmony_ci    char * saveBaseLoc = baseName+strlen(baseName);
7642e5b6d6dSopenharmony_ci
7652e5b6d6dSopenharmony_ci    IntlTest* saveTest = gTest;
7662e5b6d6dSopenharmony_ci    gTest = this;
7672e5b6d6dSopenharmony_ci    do {
7682e5b6d6dSopenharmony_ci        this->runIndexedTest( index, false, name, par );
7692e5b6d6dSopenharmony_ci        if (strcmp(name,"skip") == 0) {
7702e5b6d6dSopenharmony_ci            run_this_test = false;
7712e5b6d6dSopenharmony_ci        } else {
7722e5b6d6dSopenharmony_ci            if (!name || (name[0] == 0))
7732e5b6d6dSopenharmony_ci                break;
7742e5b6d6dSopenharmony_ci            if (!testname) {
7752e5b6d6dSopenharmony_ci                run_this_test = true;
7762e5b6d6dSopenharmony_ci            }else{
7772e5b6d6dSopenharmony_ci                run_this_test = (UBool) (strcmp( name, testname ) == 0);
7782e5b6d6dSopenharmony_ci            }
7792e5b6d6dSopenharmony_ci        }
7802e5b6d6dSopenharmony_ci        if (run_this_test) {
7812e5b6d6dSopenharmony_ci            lastErrorCount = errorCount;
7822e5b6d6dSopenharmony_ci            execCount++;
7832e5b6d6dSopenharmony_ci            char msg[256];
7842e5b6d6dSopenharmony_ci            sprintf(msg, "%s {", name);
7852e5b6d6dSopenharmony_ci            LL_message(msg, true);
7862e5b6d6dSopenharmony_ci            UDate timeStart = uprv_getRawUTCtime();
7872e5b6d6dSopenharmony_ci            strcpy(saveBaseLoc,name);
7882e5b6d6dSopenharmony_ci            strcat(saveBaseLoc,"/");
7892e5b6d6dSopenharmony_ci
7902e5b6d6dSopenharmony_ci            strcpy(currName, name); // set
7912e5b6d6dSopenharmony_ci            this->runIndexedTest( index, true, name, par );
7922e5b6d6dSopenharmony_ci            currName[0]=0; // reset
7932e5b6d6dSopenharmony_ci
7942e5b6d6dSopenharmony_ci            UDate timeStop = uprv_getRawUTCtime();
7952e5b6d6dSopenharmony_ci            rval = true; // at least one test has been called
7962e5b6d6dSopenharmony_ci            char secs[256];
7972e5b6d6dSopenharmony_ci            if(!no_time) {
7982e5b6d6dSopenharmony_ci              sprintf(secs, "%f", (timeStop-timeStart)/1000.0);
7992e5b6d6dSopenharmony_ci            } else {
8002e5b6d6dSopenharmony_ci              secs[0]=0;
8012e5b6d6dSopenharmony_ci            }
8022e5b6d6dSopenharmony_ci
8032e5b6d6dSopenharmony_ci
8042e5b6d6dSopenharmony_ci            strcpy(saveBaseLoc,name);
8052e5b6d6dSopenharmony_ci
8062e5b6d6dSopenharmony_ci
8072e5b6d6dSopenharmony_ci            ctest_xml_testcase(baseName, name, secs, (lastErrorCount!=errorCount)?"err":NULL);
8082e5b6d6dSopenharmony_ci
8092e5b6d6dSopenharmony_ci
8102e5b6d6dSopenharmony_ci            saveBaseLoc[0]=0; /* reset path */
8112e5b6d6dSopenharmony_ci
8122e5b6d6dSopenharmony_ci            if (lastErrorCount == errorCount) {
8132e5b6d6dSopenharmony_ci                sprintf( msg, "   } OK:   %s ", name );
8142e5b6d6dSopenharmony_ci                if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
8152e5b6d6dSopenharmony_ci                lastTestFailed = false;
8162e5b6d6dSopenharmony_ci            }else{
8172e5b6d6dSopenharmony_ci                sprintf(msg,  "   } ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name);
8182e5b6d6dSopenharmony_ci                if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
8192e5b6d6dSopenharmony_ci
8202e5b6d6dSopenharmony_ci                for(int i=0;i<LL_indentlevel;i++) {
8212e5b6d6dSopenharmony_ci                    errorList += " ";
8222e5b6d6dSopenharmony_ci                }
8232e5b6d6dSopenharmony_ci                errorList += name;
8242e5b6d6dSopenharmony_ci                errorList += "\n";
8252e5b6d6dSopenharmony_ci                lastTestFailed = true;
8262e5b6d6dSopenharmony_ci            }
8272e5b6d6dSopenharmony_ci            LL_indentlevel -= 3;
8282e5b6d6dSopenharmony_ci            if (lastTestFailed) {
8292e5b6d6dSopenharmony_ci                LL_message( "", true);
8302e5b6d6dSopenharmony_ci            }
8312e5b6d6dSopenharmony_ci            LL_message( msg, true);
8322e5b6d6dSopenharmony_ci            if (lastTestFailed) {
8332e5b6d6dSopenharmony_ci                LL_message( "", true);
8342e5b6d6dSopenharmony_ci            }
8352e5b6d6dSopenharmony_ci            LL_indentlevel += 3;
8362e5b6d6dSopenharmony_ci        }
8372e5b6d6dSopenharmony_ci        index++;
8382e5b6d6dSopenharmony_ci    }while(name);
8392e5b6d6dSopenharmony_ci
8402e5b6d6dSopenharmony_ci    *saveBaseLoc = 0;
8412e5b6d6dSopenharmony_ci
8422e5b6d6dSopenharmony_ci    gTest = saveTest;
8432e5b6d6dSopenharmony_ci    return rval;
8442e5b6d6dSopenharmony_ci}
8452e5b6d6dSopenharmony_ci
8462e5b6d6dSopenharmony_ci
8472e5b6d6dSopenharmony_ci/**
8482e5b6d6dSopenharmony_ci* Adds given string to the log if we are in verbose mode.
8492e5b6d6dSopenharmony_ci*/
8502e5b6d6dSopenharmony_civoid IntlTest::log( const UnicodeString &message )
8512e5b6d6dSopenharmony_ci{
8522e5b6d6dSopenharmony_ci    if( verbose ) {
8532e5b6d6dSopenharmony_ci        LL_message( message, false );
8542e5b6d6dSopenharmony_ci    }
8552e5b6d6dSopenharmony_ci}
8562e5b6d6dSopenharmony_ci
8572e5b6d6dSopenharmony_ci/**
8582e5b6d6dSopenharmony_ci* Adds given string to the log if we are in verbose mode. Adds a new line to
8592e5b6d6dSopenharmony_ci* the given message.
8602e5b6d6dSopenharmony_ci*/
8612e5b6d6dSopenharmony_civoid IntlTest::logln( const UnicodeString &message )
8622e5b6d6dSopenharmony_ci{
8632e5b6d6dSopenharmony_ci    if( verbose ) {
8642e5b6d6dSopenharmony_ci        LL_message( message, true );
8652e5b6d6dSopenharmony_ci    }
8662e5b6d6dSopenharmony_ci}
8672e5b6d6dSopenharmony_ci
8682e5b6d6dSopenharmony_civoid IntlTest::logln( void )
8692e5b6d6dSopenharmony_ci{
8702e5b6d6dSopenharmony_ci    if( verbose ) {
8712e5b6d6dSopenharmony_ci        LL_message( "", true );
8722e5b6d6dSopenharmony_ci    }
8732e5b6d6dSopenharmony_ci}
8742e5b6d6dSopenharmony_ci
8752e5b6d6dSopenharmony_ci/**
8762e5b6d6dSopenharmony_ci* Unconditionally adds given string to the log.
8772e5b6d6dSopenharmony_ci*/
8782e5b6d6dSopenharmony_civoid IntlTest::info( const UnicodeString &message )
8792e5b6d6dSopenharmony_ci{
8802e5b6d6dSopenharmony_ci  LL_message( message, false );
8812e5b6d6dSopenharmony_ci}
8822e5b6d6dSopenharmony_ci
8832e5b6d6dSopenharmony_ci/**
8842e5b6d6dSopenharmony_ci* Unconditionally adds given string to the log. Adds a new line to
8852e5b6d6dSopenharmony_ci* the given message.
8862e5b6d6dSopenharmony_ci*/
8872e5b6d6dSopenharmony_civoid IntlTest::infoln( const UnicodeString &message )
8882e5b6d6dSopenharmony_ci{
8892e5b6d6dSopenharmony_ci  LL_message( message, true );
8902e5b6d6dSopenharmony_ci}
8912e5b6d6dSopenharmony_ci
8922e5b6d6dSopenharmony_civoid IntlTest::infoln( void )
8932e5b6d6dSopenharmony_ci{
8942e5b6d6dSopenharmony_ci  LL_message( "", true );
8952e5b6d6dSopenharmony_ci}
8962e5b6d6dSopenharmony_ci
8972e5b6d6dSopenharmony_ciint32_t IntlTest::IncErrorCount( void )
8982e5b6d6dSopenharmony_ci{
8992e5b6d6dSopenharmony_ci    errorCount++;
9002e5b6d6dSopenharmony_ci    if (caller) caller->IncErrorCount();
9012e5b6d6dSopenharmony_ci    return errorCount;
9022e5b6d6dSopenharmony_ci}
9032e5b6d6dSopenharmony_ci
9042e5b6d6dSopenharmony_ciint32_t IntlTest::IncDataErrorCount( void )
9052e5b6d6dSopenharmony_ci{
9062e5b6d6dSopenharmony_ci    dataErrorCount++;
9072e5b6d6dSopenharmony_ci    if (caller) caller->IncDataErrorCount();
9082e5b6d6dSopenharmony_ci    return dataErrorCount;
9092e5b6d6dSopenharmony_ci}
9102e5b6d6dSopenharmony_ci
9112e5b6d6dSopenharmony_civoid IntlTest::err()
9122e5b6d6dSopenharmony_ci{
9132e5b6d6dSopenharmony_ci    IncErrorCount();
9142e5b6d6dSopenharmony_ci}
9152e5b6d6dSopenharmony_ci
9162e5b6d6dSopenharmony_civoid IntlTest::err( const UnicodeString &message )
9172e5b6d6dSopenharmony_ci{
9182e5b6d6dSopenharmony_ci    IncErrorCount();
9192e5b6d6dSopenharmony_ci    if (!no_err_msg) LL_message( message, false );
9202e5b6d6dSopenharmony_ci}
9212e5b6d6dSopenharmony_ci
9222e5b6d6dSopenharmony_civoid IntlTest::errln( const UnicodeString &message )
9232e5b6d6dSopenharmony_ci{
9242e5b6d6dSopenharmony_ci    IncErrorCount();
9252e5b6d6dSopenharmony_ci    if (!no_err_msg) LL_message( message, true );
9262e5b6d6dSopenharmony_ci}
9272e5b6d6dSopenharmony_ci
9282e5b6d6dSopenharmony_civoid IntlTest::dataerr( const UnicodeString &message )
9292e5b6d6dSopenharmony_ci{
9302e5b6d6dSopenharmony_ci    IncDataErrorCount();
9312e5b6d6dSopenharmony_ci
9322e5b6d6dSopenharmony_ci    if (!warn_on_missing_data) {
9332e5b6d6dSopenharmony_ci        IncErrorCount();
9342e5b6d6dSopenharmony_ci    }
9352e5b6d6dSopenharmony_ci
9362e5b6d6dSopenharmony_ci    if (!no_err_msg) LL_message( message, false );
9372e5b6d6dSopenharmony_ci}
9382e5b6d6dSopenharmony_ci
9392e5b6d6dSopenharmony_civoid IntlTest::dataerrln( const UnicodeString &message )
9402e5b6d6dSopenharmony_ci{
9412e5b6d6dSopenharmony_ci    int32_t errCount = IncDataErrorCount();
9422e5b6d6dSopenharmony_ci    UnicodeString msg;
9432e5b6d6dSopenharmony_ci    if (!warn_on_missing_data) {
9442e5b6d6dSopenharmony_ci        IncErrorCount();
9452e5b6d6dSopenharmony_ci        msg = message;
9462e5b6d6dSopenharmony_ci    } else {
9472e5b6d6dSopenharmony_ci        msg = UnicodeString("[DATA] " + message);
9482e5b6d6dSopenharmony_ci    }
9492e5b6d6dSopenharmony_ci
9502e5b6d6dSopenharmony_ci    if (!no_err_msg) {
9512e5b6d6dSopenharmony_ci      if ( errCount == 1) {
9522e5b6d6dSopenharmony_ci          LL_message( msg + " - (Are you missing data?)", true ); // only show this message the first time
9532e5b6d6dSopenharmony_ci      } else {
9542e5b6d6dSopenharmony_ci          LL_message( msg , true );
9552e5b6d6dSopenharmony_ci      }
9562e5b6d6dSopenharmony_ci    }
9572e5b6d6dSopenharmony_ci}
9582e5b6d6dSopenharmony_ci
9592e5b6d6dSopenharmony_civoid IntlTest::errcheckln(UErrorCode status, const UnicodeString &message ) {
9602e5b6d6dSopenharmony_ci    if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
9612e5b6d6dSopenharmony_ci        dataerrln(message);
9622e5b6d6dSopenharmony_ci    } else {
9632e5b6d6dSopenharmony_ci        errln(message);
9642e5b6d6dSopenharmony_ci    }
9652e5b6d6dSopenharmony_ci}
9662e5b6d6dSopenharmony_ci
9672e5b6d6dSopenharmony_ci/* convenience functions that include sprintf formatting */
9682e5b6d6dSopenharmony_civoid IntlTest::log(const char *fmt, ...)
9692e5b6d6dSopenharmony_ci{
9702e5b6d6dSopenharmony_ci    char buffer[4000];
9712e5b6d6dSopenharmony_ci    va_list ap;
9722e5b6d6dSopenharmony_ci
9732e5b6d6dSopenharmony_ci    va_start(ap, fmt);
9742e5b6d6dSopenharmony_ci    /* sprintf it just to make sure that the information is valid */
9752e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
9762e5b6d6dSopenharmony_ci    va_end(ap);
9772e5b6d6dSopenharmony_ci    if( verbose ) {
9782e5b6d6dSopenharmony_ci        log(UnicodeString(buffer, (const char *)NULL));
9792e5b6d6dSopenharmony_ci    }
9802e5b6d6dSopenharmony_ci}
9812e5b6d6dSopenharmony_ci
9822e5b6d6dSopenharmony_civoid IntlTest::logln(const char *fmt, ...)
9832e5b6d6dSopenharmony_ci{
9842e5b6d6dSopenharmony_ci    char buffer[4000];
9852e5b6d6dSopenharmony_ci    va_list ap;
9862e5b6d6dSopenharmony_ci
9872e5b6d6dSopenharmony_ci    va_start(ap, fmt);
9882e5b6d6dSopenharmony_ci    /* sprintf it just to make sure that the information is valid */
9892e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
9902e5b6d6dSopenharmony_ci    va_end(ap);
9912e5b6d6dSopenharmony_ci    if( verbose ) {
9922e5b6d6dSopenharmony_ci        logln(UnicodeString(buffer, (const char *)NULL));
9932e5b6d6dSopenharmony_ci    }
9942e5b6d6dSopenharmony_ci}
9952e5b6d6dSopenharmony_ci
9962e5b6d6dSopenharmony_ciUBool IntlTest::logKnownIssue(const char *ticket, const char *fmt, ...)
9972e5b6d6dSopenharmony_ci{
9982e5b6d6dSopenharmony_ci    char buffer[4000];
9992e5b6d6dSopenharmony_ci    va_list ap;
10002e5b6d6dSopenharmony_ci
10012e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10022e5b6d6dSopenharmony_ci    /* sprintf it just to make sure that the information is valid */
10032e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10042e5b6d6dSopenharmony_ci    va_end(ap);
10052e5b6d6dSopenharmony_ci    return logKnownIssue(ticket, UnicodeString(buffer, (const char *)NULL));
10062e5b6d6dSopenharmony_ci}
10072e5b6d6dSopenharmony_ci
10082e5b6d6dSopenharmony_ciUBool IntlTest::logKnownIssue(const char *ticket) {
10092e5b6d6dSopenharmony_ci  return logKnownIssue(ticket, UnicodeString());
10102e5b6d6dSopenharmony_ci}
10112e5b6d6dSopenharmony_ci
10122e5b6d6dSopenharmony_ciUBool IntlTest::logKnownIssue(const char *ticket, const UnicodeString &msg) {
10132e5b6d6dSopenharmony_ci  if(noKnownIssues) return false;
10142e5b6d6dSopenharmony_ci
10152e5b6d6dSopenharmony_ci  char fullpath[2048];
10162e5b6d6dSopenharmony_ci  strcpy(fullpath, basePath);
10172e5b6d6dSopenharmony_ci  strcat(fullpath, currName);
10182e5b6d6dSopenharmony_ci  UnicodeString msg2 = msg;
10192e5b6d6dSopenharmony_ci  UBool firstForTicket = true, firstForWhere = true;
10202e5b6d6dSopenharmony_ci  knownList = udbg_knownIssue_openU(knownList, ticket, fullpath, msg2.getTerminatedBuffer(), &firstForTicket, &firstForWhere);
10212e5b6d6dSopenharmony_ci
10222e5b6d6dSopenharmony_ci  msg2 = UNICODE_STRING_SIMPLE("(Known issue ") +
10232e5b6d6dSopenharmony_ci      UnicodeString(ticket, -1, US_INV) + UNICODE_STRING_SIMPLE(") ") + msg;
10242e5b6d6dSopenharmony_ci  if(firstForTicket || firstForWhere) {
10252e5b6d6dSopenharmony_ci    infoln(msg2);
10262e5b6d6dSopenharmony_ci  } else {
10272e5b6d6dSopenharmony_ci    logln(msg2);
10282e5b6d6dSopenharmony_ci  }
10292e5b6d6dSopenharmony_ci
10302e5b6d6dSopenharmony_ci  return true;
10312e5b6d6dSopenharmony_ci}
10322e5b6d6dSopenharmony_ci
10332e5b6d6dSopenharmony_ci/* convenience functions that include sprintf formatting */
10342e5b6d6dSopenharmony_civoid IntlTest::info(const char *fmt, ...)
10352e5b6d6dSopenharmony_ci{
10362e5b6d6dSopenharmony_ci    char buffer[4000];
10372e5b6d6dSopenharmony_ci    va_list ap;
10382e5b6d6dSopenharmony_ci
10392e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10402e5b6d6dSopenharmony_ci    /* sprintf it just to make sure that the information is valid */
10412e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10422e5b6d6dSopenharmony_ci    va_end(ap);
10432e5b6d6dSopenharmony_ci    info(UnicodeString(buffer, (const char *)NULL));
10442e5b6d6dSopenharmony_ci}
10452e5b6d6dSopenharmony_ci
10462e5b6d6dSopenharmony_civoid IntlTest::infoln(const char *fmt, ...)
10472e5b6d6dSopenharmony_ci{
10482e5b6d6dSopenharmony_ci    char buffer[4000];
10492e5b6d6dSopenharmony_ci    va_list ap;
10502e5b6d6dSopenharmony_ci
10512e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10522e5b6d6dSopenharmony_ci    /* sprintf it just to make sure that the information is valid */
10532e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10542e5b6d6dSopenharmony_ci    va_end(ap);
10552e5b6d6dSopenharmony_ci    infoln(UnicodeString(buffer, (const char *)NULL));
10562e5b6d6dSopenharmony_ci}
10572e5b6d6dSopenharmony_ci
10582e5b6d6dSopenharmony_civoid IntlTest::err(const char *fmt, ...)
10592e5b6d6dSopenharmony_ci{
10602e5b6d6dSopenharmony_ci    char buffer[4000];
10612e5b6d6dSopenharmony_ci    va_list ap;
10622e5b6d6dSopenharmony_ci
10632e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10642e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10652e5b6d6dSopenharmony_ci    va_end(ap);
10662e5b6d6dSopenharmony_ci    err(UnicodeString(buffer, (const char *)NULL));
10672e5b6d6dSopenharmony_ci}
10682e5b6d6dSopenharmony_ci
10692e5b6d6dSopenharmony_civoid IntlTest::errln(const char *fmt, ...)
10702e5b6d6dSopenharmony_ci{
10712e5b6d6dSopenharmony_ci    char buffer[4000];
10722e5b6d6dSopenharmony_ci    va_list ap;
10732e5b6d6dSopenharmony_ci
10742e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10752e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10762e5b6d6dSopenharmony_ci    va_end(ap);
10772e5b6d6dSopenharmony_ci    errln(UnicodeString(buffer, (const char *)NULL));
10782e5b6d6dSopenharmony_ci}
10792e5b6d6dSopenharmony_ci
10802e5b6d6dSopenharmony_civoid IntlTest::dataerrln(const char *fmt, ...)
10812e5b6d6dSopenharmony_ci{
10822e5b6d6dSopenharmony_ci    char buffer[4000];
10832e5b6d6dSopenharmony_ci    va_list ap;
10842e5b6d6dSopenharmony_ci
10852e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10862e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10872e5b6d6dSopenharmony_ci    va_end(ap);
10882e5b6d6dSopenharmony_ci    dataerrln(UnicodeString(buffer, (const char *)NULL));
10892e5b6d6dSopenharmony_ci}
10902e5b6d6dSopenharmony_ci
10912e5b6d6dSopenharmony_civoid IntlTest::errcheckln(UErrorCode status, const char *fmt, ...)
10922e5b6d6dSopenharmony_ci{
10932e5b6d6dSopenharmony_ci    char buffer[4000];
10942e5b6d6dSopenharmony_ci    va_list ap;
10952e5b6d6dSopenharmony_ci
10962e5b6d6dSopenharmony_ci    va_start(ap, fmt);
10972e5b6d6dSopenharmony_ci    vsprintf(buffer, fmt, ap);
10982e5b6d6dSopenharmony_ci    va_end(ap);
10992e5b6d6dSopenharmony_ci
11002e5b6d6dSopenharmony_ci    if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
11012e5b6d6dSopenharmony_ci        dataerrln(UnicodeString(buffer, (const char *)NULL));
11022e5b6d6dSopenharmony_ci    } else {
11032e5b6d6dSopenharmony_ci        errln(UnicodeString(buffer, (const char *)NULL));
11042e5b6d6dSopenharmony_ci    }
11052e5b6d6dSopenharmony_ci}
11062e5b6d6dSopenharmony_ci
11072e5b6d6dSopenharmony_civoid IntlTest::printErrors()
11082e5b6d6dSopenharmony_ci{
11092e5b6d6dSopenharmony_ci     IntlTest::LL_message(errorList, true);
11102e5b6d6dSopenharmony_ci}
11112e5b6d6dSopenharmony_ci
11122e5b6d6dSopenharmony_ciUBool IntlTest::printKnownIssues()
11132e5b6d6dSopenharmony_ci{
11142e5b6d6dSopenharmony_ci  if(knownList != NULL) {
11152e5b6d6dSopenharmony_ci    udbg_knownIssue_print(knownList);
11162e5b6d6dSopenharmony_ci    udbg_knownIssue_close(knownList);
11172e5b6d6dSopenharmony_ci    return true;
11182e5b6d6dSopenharmony_ci  } else {
11192e5b6d6dSopenharmony_ci    return false;
11202e5b6d6dSopenharmony_ci  }
11212e5b6d6dSopenharmony_ci}
11222e5b6d6dSopenharmony_ci
11232e5b6d6dSopenharmony_ci
11242e5b6d6dSopenharmony_civoid IntlTest::LL_message( UnicodeString message, UBool newline )
11252e5b6d6dSopenharmony_ci{
11262e5b6d6dSopenharmony_ci    // Synchronize this function.
11272e5b6d6dSopenharmony_ci    // All error messages generated by tests funnel through here.
11282e5b6d6dSopenharmony_ci    // Multithreaded tests can concurrently generate errors, requiring synchronization
11292e5b6d6dSopenharmony_ci    // to keep each message together.
11302e5b6d6dSopenharmony_ci    static UMutex messageMutex;
11312e5b6d6dSopenharmony_ci    Mutex lock(&messageMutex);
11322e5b6d6dSopenharmony_ci
11332e5b6d6dSopenharmony_ci    // string that starts with a LineFeed character and continues
11342e5b6d6dSopenharmony_ci    // with spaces according to the current indentation
11352e5b6d6dSopenharmony_ci    static const UChar indentUChars[] = {
11362e5b6d6dSopenharmony_ci        '\n',
11372e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11382e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11392e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11402e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11412e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11422e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11432e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11442e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11452e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
11462e5b6d6dSopenharmony_ci        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
11472e5b6d6dSopenharmony_ci    };
11482e5b6d6dSopenharmony_ci    U_ASSERT(1 + LL_indentlevel <= UPRV_LENGTHOF(indentUChars));
11492e5b6d6dSopenharmony_ci    UnicodeString indent(false, indentUChars, 1 + LL_indentlevel);
11502e5b6d6dSopenharmony_ci
11512e5b6d6dSopenharmony_ci    char buffer[30000];
11522e5b6d6dSopenharmony_ci    int32_t length;
11532e5b6d6dSopenharmony_ci
11542e5b6d6dSopenharmony_ci    // stream out the indentation string first if necessary
11552e5b6d6dSopenharmony_ci    length = indent.extract(1, indent.length(), buffer, sizeof(buffer));
11562e5b6d6dSopenharmony_ci    if (length > 0) {
11572e5b6d6dSopenharmony_ci        fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
11582e5b6d6dSopenharmony_ci    }
11592e5b6d6dSopenharmony_ci
11602e5b6d6dSopenharmony_ci    // replace each LineFeed by the indentation string
11612e5b6d6dSopenharmony_ci    message.findAndReplace(UnicodeString((UChar)'\n'), indent);
11622e5b6d6dSopenharmony_ci
11632e5b6d6dSopenharmony_ci    // stream out the message
11642e5b6d6dSopenharmony_ci    length = message.extract(0, message.length(), buffer, sizeof(buffer));
11652e5b6d6dSopenharmony_ci    if (length > 0) {
11662e5b6d6dSopenharmony_ci        length = length > 30000 ? 30000 : length;
11672e5b6d6dSopenharmony_ci        fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
11682e5b6d6dSopenharmony_ci    }
11692e5b6d6dSopenharmony_ci
11702e5b6d6dSopenharmony_ci    if (newline) {
11712e5b6d6dSopenharmony_ci        char newLine = '\n';
11722e5b6d6dSopenharmony_ci        fwrite(&newLine, sizeof(newLine), 1, (FILE *)testoutfp);
11732e5b6d6dSopenharmony_ci    }
11742e5b6d6dSopenharmony_ci
11752e5b6d6dSopenharmony_ci    // A newline usually flushes the buffer, but
11762e5b6d6dSopenharmony_ci    // flush the message just in case of a core dump.
11772e5b6d6dSopenharmony_ci    fflush((FILE *)testoutfp);
11782e5b6d6dSopenharmony_ci}
11792e5b6d6dSopenharmony_ci
11802e5b6d6dSopenharmony_ci/**
11812e5b6d6dSopenharmony_ci* Print a usage message for this test class.
11822e5b6d6dSopenharmony_ci*/
11832e5b6d6dSopenharmony_civoid IntlTest::usage( void )
11842e5b6d6dSopenharmony_ci{
11852e5b6d6dSopenharmony_ci    UBool save_verbose = setVerbose( true );
11862e5b6d6dSopenharmony_ci    logln("Test names:");
11872e5b6d6dSopenharmony_ci    logln("-----------");
11882e5b6d6dSopenharmony_ci
11892e5b6d6dSopenharmony_ci    int32_t index = 0;
11902e5b6d6dSopenharmony_ci    const char* name = NULL;
11912e5b6d6dSopenharmony_ci    do{
11922e5b6d6dSopenharmony_ci        this->runIndexedTest( index, false, name );
11932e5b6d6dSopenharmony_ci        if (!name) break;
11942e5b6d6dSopenharmony_ci        logln(name);
11952e5b6d6dSopenharmony_ci        index++;
11962e5b6d6dSopenharmony_ci    }while (name && (name[0] != 0));
11972e5b6d6dSopenharmony_ci    setVerbose( save_verbose );
11982e5b6d6dSopenharmony_ci}
11992e5b6d6dSopenharmony_ci
12002e5b6d6dSopenharmony_ci
12012e5b6d6dSopenharmony_ci// memory leak reporting software will be able to take advantage of the testsuite
12022e5b6d6dSopenharmony_ci// being run a second time local to a specific method in order to report only actual leaks
12032e5b6d6dSopenharmony_ciUBool
12042e5b6d6dSopenharmony_ciIntlTest::run_phase2( char* name, char* par ) // supports reporting memory leaks
12052e5b6d6dSopenharmony_ci{
12062e5b6d6dSopenharmony_ci    UnicodeString* strLeak = new UnicodeString("forced leak"); // for verifying purify filter
12072e5b6d6dSopenharmony_ci    strLeak->append(" for verifying purify filter");
12082e5b6d6dSopenharmony_ci    return this->runTest( name, par );
12092e5b6d6dSopenharmony_ci}
12102e5b6d6dSopenharmony_ci
12112e5b6d6dSopenharmony_ci
12122e5b6d6dSopenharmony_ci#if UCONFIG_NO_LEGACY_CONVERSION
12132e5b6d6dSopenharmony_ci#   define TRY_CNV_1 "iso-8859-1"
12142e5b6d6dSopenharmony_ci#   define TRY_CNV_2 "ibm-1208"
12152e5b6d6dSopenharmony_ci#else
12162e5b6d6dSopenharmony_ci#   define TRY_CNV_1 "iso-8859-7"
12172e5b6d6dSopenharmony_ci#   define TRY_CNV_2 "sjis"
12182e5b6d6dSopenharmony_ci#endif
12192e5b6d6dSopenharmony_ci
12202e5b6d6dSopenharmony_ci#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
12212e5b6d6dSopenharmony_ciU_CAPI void unistr_printLengths();
12222e5b6d6dSopenharmony_ci#endif
12232e5b6d6dSopenharmony_ci
12242e5b6d6dSopenharmony_ciint
12252e5b6d6dSopenharmony_cimain(int argc, char* argv[])
12262e5b6d6dSopenharmony_ci{
12272e5b6d6dSopenharmony_ci    UBool syntax = false;
12282e5b6d6dSopenharmony_ci    UBool all = false;
12292e5b6d6dSopenharmony_ci    UBool verbose = false;
12302e5b6d6dSopenharmony_ci    UBool no_err_msg = false;
12312e5b6d6dSopenharmony_ci    UBool no_time = false;
12322e5b6d6dSopenharmony_ci    UBool quick = true;
12332e5b6d6dSopenharmony_ci    UBool name = false;
12342e5b6d6dSopenharmony_ci    UBool leaks = false;
12352e5b6d6dSopenharmony_ci    UBool utf8 = false;
12362e5b6d6dSopenharmony_ci    const char *summary_file = NULL;
12372e5b6d6dSopenharmony_ci    UBool warnOnMissingData = false;
12382e5b6d6dSopenharmony_ci    UBool writeGoldenData = false;
12392e5b6d6dSopenharmony_ci    UBool defaultDataFound = false;
12402e5b6d6dSopenharmony_ci    int32_t threadCount = 12;
12412e5b6d6dSopenharmony_ci    UErrorCode errorCode = U_ZERO_ERROR;
12422e5b6d6dSopenharmony_ci    UConverter *cnv = NULL;
12432e5b6d6dSopenharmony_ci    const char *warnOrErr = "Failure";
12442e5b6d6dSopenharmony_ci    UDate startTime, endTime;
12452e5b6d6dSopenharmony_ci    int32_t diffTime;
12462e5b6d6dSopenharmony_ci    const char *props[IntlTest::kMaxProps];
12472e5b6d6dSopenharmony_ci    int32_t nProps = 0;
12482e5b6d6dSopenharmony_ci
12492e5b6d6dSopenharmony_ci    U_MAIN_INIT_ARGS(argc, argv);
12502e5b6d6dSopenharmony_ci
12512e5b6d6dSopenharmony_ci    startTime = uprv_getRawUTCtime();
12522e5b6d6dSopenharmony_ci
12532e5b6d6dSopenharmony_ci    for (int i = 1; i < argc; ++i) {
12542e5b6d6dSopenharmony_ci        if (argv[i][0] == '-') {
12552e5b6d6dSopenharmony_ci            const char* str = argv[i] + 1;
12562e5b6d6dSopenharmony_ci            if (strcmp("verbose", str) == 0 ||
12572e5b6d6dSopenharmony_ci                strcmp("v", str) == 0)
12582e5b6d6dSopenharmony_ci                verbose = true;
12592e5b6d6dSopenharmony_ci            else if (strcmp("noerrormsg", str) == 0 ||
12602e5b6d6dSopenharmony_ci                     strcmp("n", str) == 0)
12612e5b6d6dSopenharmony_ci                no_err_msg = true;
12622e5b6d6dSopenharmony_ci            else if (strcmp("exhaustive", str) == 0 ||
12632e5b6d6dSopenharmony_ci                     strcmp("e", str) == 0)
12642e5b6d6dSopenharmony_ci                quick = false;
12652e5b6d6dSopenharmony_ci            else if (strcmp("all", str) == 0 ||
12662e5b6d6dSopenharmony_ci                     strcmp("a", str) == 0)
12672e5b6d6dSopenharmony_ci                all = true;
12682e5b6d6dSopenharmony_ci            else if (strcmp("utf-8", str) == 0 ||
12692e5b6d6dSopenharmony_ci                     strcmp("u", str) == 0)
12702e5b6d6dSopenharmony_ci                utf8 = true;
12712e5b6d6dSopenharmony_ci            else if (strcmp("noknownissues", str) == 0 ||
12722e5b6d6dSopenharmony_ci                     strcmp("K", str) == 0)
12732e5b6d6dSopenharmony_ci                noKnownIssues = true;
12742e5b6d6dSopenharmony_ci            else if (strcmp("leaks", str) == 0 ||
12752e5b6d6dSopenharmony_ci                     strcmp("l", str) == 0)
12762e5b6d6dSopenharmony_ci                leaks = true;
12772e5b6d6dSopenharmony_ci            else if (strcmp("notime", str) == 0 ||
12782e5b6d6dSopenharmony_ci                     strcmp("T", str) == 0)
12792e5b6d6dSopenharmony_ci                no_time = true;
12802e5b6d6dSopenharmony_ci            else if (strcmp("goldens", str) == 0 ||
12812e5b6d6dSopenharmony_ci                     strcmp("G", str) == 0)
12822e5b6d6dSopenharmony_ci                writeGoldenData = true;
12832e5b6d6dSopenharmony_ci            else if (strncmp("E", str, 1) == 0)
12842e5b6d6dSopenharmony_ci                summary_file = str+1;
12852e5b6d6dSopenharmony_ci            else if (strcmp("x", str)==0) {
12862e5b6d6dSopenharmony_ci              if(++i>=argc) {
12872e5b6d6dSopenharmony_ci                printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
12882e5b6d6dSopenharmony_ci                syntax = true;
12892e5b6d6dSopenharmony_ci              }
12902e5b6d6dSopenharmony_ci              if(ctest_xml_setFileName(argv[i])) { /* set the name */
12912e5b6d6dSopenharmony_ci                return 1; /* error */
12922e5b6d6dSopenharmony_ci              }
12932e5b6d6dSopenharmony_ci            } else if (strcmp("w", str) == 0) {
12942e5b6d6dSopenharmony_ci              warnOnMissingData = true;
12952e5b6d6dSopenharmony_ci              warnOrErr = "WARNING";
12962e5b6d6dSopenharmony_ci            }
12972e5b6d6dSopenharmony_ci            else if (strncmp("threads:", str, 8) == 0) {
12982e5b6d6dSopenharmony_ci                threadCount = atoi(str + 8);
12992e5b6d6dSopenharmony_ci            }
13002e5b6d6dSopenharmony_ci            else if (strncmp("prop:", str, 5) == 0) {
13012e5b6d6dSopenharmony_ci                if (nProps < IntlTest::kMaxProps) {
13022e5b6d6dSopenharmony_ci                    props[nProps] = str + 5;
13032e5b6d6dSopenharmony_ci                }
13042e5b6d6dSopenharmony_ci                nProps++;
13052e5b6d6dSopenharmony_ci            }
13062e5b6d6dSopenharmony_ci            else {
13072e5b6d6dSopenharmony_ci                syntax = true;
13082e5b6d6dSopenharmony_ci            }
13092e5b6d6dSopenharmony_ci        }else{
13102e5b6d6dSopenharmony_ci            name = true;
13112e5b6d6dSopenharmony_ci        }
13122e5b6d6dSopenharmony_ci    }
13132e5b6d6dSopenharmony_ci
13142e5b6d6dSopenharmony_ci    if (!all && !name) {
13152e5b6d6dSopenharmony_ci        all = true;
13162e5b6d6dSopenharmony_ci    } else if (all && name) {
13172e5b6d6dSopenharmony_ci        syntax = true;
13182e5b6d6dSopenharmony_ci    }
13192e5b6d6dSopenharmony_ci
13202e5b6d6dSopenharmony_ci    if (syntax) {
13212e5b6d6dSopenharmony_ci        fprintf(stdout,
13222e5b6d6dSopenharmony_ci                "### Syntax:\n"
13232e5b6d6dSopenharmony_ci                "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
13242e5b6d6dSopenharmony_ci                "### \n"
13252e5b6d6dSopenharmony_ci                "### Options are: verbose (v), all (a), noerrormsg (n), \n"
13262e5b6d6dSopenharmony_ci                "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<property>=<value>, \n"
13272e5b6d6dSopenharmony_ci                "### notime (T), \n"
13282e5b6d6dSopenharmony_ci                "### threads:<threadCount>\n"
13292e5b6d6dSopenharmony_ci                "###     (The default thread count is 12.),\n"
13302e5b6d6dSopenharmony_ci                "### (Specify either -all (shortcut -a) or a test name). \n"
13312e5b6d6dSopenharmony_ci                "### -all will run all of the tests.\n"
13322e5b6d6dSopenharmony_ci                "### \n"
13332e5b6d6dSopenharmony_ci                "### To get a list of the test names type: intltest LIST \n"
13342e5b6d6dSopenharmony_ci                "### To run just the utility tests type: intltest utility \n"
13352e5b6d6dSopenharmony_ci                "### \n"
13362e5b6d6dSopenharmony_ci                "### Test names can be nested using slashes (\"testA/subtest1\") \n"
13372e5b6d6dSopenharmony_ci                "### For example to list the utility tests type: intltest utility/LIST \n"
13382e5b6d6dSopenharmony_ci                "### To run just the Locale test type: intltest utility/LocaleTest \n"
13392e5b6d6dSopenharmony_ci                "### \n"
13402e5b6d6dSopenharmony_ci                "### A parameter can be specified for a test by appending '@' and the value \n"
13412e5b6d6dSopenharmony_ci                "### to the testname. \n\n");
13422e5b6d6dSopenharmony_ci        return 1;
13432e5b6d6dSopenharmony_ci    }
13442e5b6d6dSopenharmony_ci
13452e5b6d6dSopenharmony_ci    if (nProps > IntlTest::kMaxProps) {
13462e5b6d6dSopenharmony_ci        fprintf(stdout, "### Too many properties.  Exiting.\n");
13472e5b6d6dSopenharmony_ci    }
13482e5b6d6dSopenharmony_ci
13492e5b6d6dSopenharmony_ci    MajorTestLevel major;
13502e5b6d6dSopenharmony_ci    major.setVerbose( verbose );
13512e5b6d6dSopenharmony_ci    major.setNoErrMsg( no_err_msg );
13522e5b6d6dSopenharmony_ci    major.setQuick( quick );
13532e5b6d6dSopenharmony_ci    major.setLeaks( leaks );
13542e5b6d6dSopenharmony_ci    major.setThreadCount( threadCount );
13552e5b6d6dSopenharmony_ci    major.setWarnOnMissingData( warnOnMissingData );
13562e5b6d6dSopenharmony_ci    major.setWriteGoldenData( writeGoldenData );
13572e5b6d6dSopenharmony_ci    major.setNotime (no_time);
13582e5b6d6dSopenharmony_ci    for (int32_t i = 0; i < nProps; i++) {
13592e5b6d6dSopenharmony_ci        major.setProperty(props[i]);
13602e5b6d6dSopenharmony_ci    }
13612e5b6d6dSopenharmony_ci
13622e5b6d6dSopenharmony_ci
13632e5b6d6dSopenharmony_ci    fprintf(stdout, "-----------------------------------------------\n");
13642e5b6d6dSopenharmony_ci    fprintf(stdout, " IntlTest (C++) Test Suite for                 \n");
13652e5b6d6dSopenharmony_ci    fprintf(stdout, "   International Components for Unicode %s\n", U_ICU_VERSION);
13662e5b6d6dSopenharmony_ci
13672e5b6d6dSopenharmony_ci
13682e5b6d6dSopenharmony_ci    {
13692e5b6d6dSopenharmony_ci	const char *charsetFamily = "Unknown";
13702e5b6d6dSopenharmony_ci        int32_t voidSize = (int32_t)sizeof(void*);
13712e5b6d6dSopenharmony_ci        int32_t bits = voidSize * 8;
13722e5b6d6dSopenharmony_ci        if(U_CHARSET_FAMILY==U_ASCII_FAMILY) {
13732e5b6d6dSopenharmony_ci           charsetFamily="ASCII";
13742e5b6d6dSopenharmony_ci        } else if(U_CHARSET_FAMILY==U_EBCDIC_FAMILY) {
13752e5b6d6dSopenharmony_ci           charsetFamily="EBCDIC";
13762e5b6d6dSopenharmony_ci        }
13772e5b6d6dSopenharmony_ci        fprintf(stdout,
13782e5b6d6dSopenharmony_ci                    "   Bits: %d, Byte order: %s, Chars: %s\n",
13792e5b6d6dSopenharmony_ci                     bits, U_IS_BIG_ENDIAN?"Big endian":"Little endian",
13802e5b6d6dSopenharmony_ci                     charsetFamily);
13812e5b6d6dSopenharmony_ci    }
13822e5b6d6dSopenharmony_ci    fprintf(stdout, "-----------------------------------------------\n");
13832e5b6d6dSopenharmony_ci    fprintf(stdout, " Options:                                       \n");
13842e5b6d6dSopenharmony_ci    fprintf(stdout, "   all (a)                  : %s\n", (all?               "On" : "Off"));
13852e5b6d6dSopenharmony_ci    fprintf(stdout, "   Verbose (v)              : %s\n", (verbose?           "On" : "Off"));
13862e5b6d6dSopenharmony_ci    fprintf(stdout, "   No error messages (n)    : %s\n", (no_err_msg?        "On" : "Off"));
13872e5b6d6dSopenharmony_ci    fprintf(stdout, "   Exhaustive (e)           : %s\n", (!quick?            "On" : "Off"));
13882e5b6d6dSopenharmony_ci    fprintf(stdout, "   Leaks (l)                : %s\n", (leaks?             "On" : "Off"));
13892e5b6d6dSopenharmony_ci    fprintf(stdout, "   utf-8 (u)                : %s\n", (utf8?              "On" : "Off"));
13902e5b6d6dSopenharmony_ci    fprintf(stdout, "   notime (T)               : %s\n", (no_time?           "On" : "Off"));
13912e5b6d6dSopenharmony_ci    fprintf(stdout, "   noknownissues (K)        : %s\n", (noKnownIssues?     "On" : "Off"));
13922e5b6d6dSopenharmony_ci    fprintf(stdout, "   Warn on missing data (w) : %s\n", (warnOnMissingData? "On" : "Off"));
13932e5b6d6dSopenharmony_ci    fprintf(stdout, "   Write golden data (G)    : %s\n", (writeGoldenData?   "On" : "Off"));
13942e5b6d6dSopenharmony_ci    fprintf(stdout, "   Threads                  : %d\n", threadCount);
13952e5b6d6dSopenharmony_ci    for (int32_t i = 0; i < nProps; i++) {
13962e5b6d6dSopenharmony_ci        fprintf(stdout, "   Custom property (prop:)  : %s\n", props[i]);
13972e5b6d6dSopenharmony_ci    }
13982e5b6d6dSopenharmony_ci    fprintf(stdout, "-----------------------------------------------\n");
13992e5b6d6dSopenharmony_ci
14002e5b6d6dSopenharmony_ci    if(utf8) {
14012e5b6d6dSopenharmony_ci      ucnv_setDefaultName("utf-8");
14022e5b6d6dSopenharmony_ci    }
14032e5b6d6dSopenharmony_ci    /* Check whether ICU will initialize without forcing the build data directory into
14042e5b6d6dSopenharmony_ci     *  the ICU_DATA path.  Success here means either the data dll contains data, or that
14052e5b6d6dSopenharmony_ci     *  this test program was run with ICU_DATA set externally.  Failure of this check
14062e5b6d6dSopenharmony_ci     *  is normal when ICU data is not packaged into a shared library.
14072e5b6d6dSopenharmony_ci     *
14082e5b6d6dSopenharmony_ci     *  Whether or not this test succeeds, we want to cleanup and reinitialize
14092e5b6d6dSopenharmony_ci     *  with a data path so that data loading from individual files can be tested.
14102e5b6d6dSopenharmony_ci     */
14112e5b6d6dSopenharmony_ci    u_init(&errorCode);
14122e5b6d6dSopenharmony_ci    if (U_FAILURE(errorCode)) {
14132e5b6d6dSopenharmony_ci        fprintf(stderr,
14142e5b6d6dSopenharmony_ci            "#### Note:  ICU Init without build-specific setDataDirectory() failed.\n");
14152e5b6d6dSopenharmony_ci        defaultDataFound = false;
14162e5b6d6dSopenharmony_ci    }
14172e5b6d6dSopenharmony_ci    else {
14182e5b6d6dSopenharmony_ci        defaultDataFound = true;
14192e5b6d6dSopenharmony_ci    }
14202e5b6d6dSopenharmony_ci    u_cleanup();
14212e5b6d6dSopenharmony_ci    if(utf8) {
14222e5b6d6dSopenharmony_ci      ucnv_setDefaultName("utf-8");
14232e5b6d6dSopenharmony_ci    }
14242e5b6d6dSopenharmony_ci    errorCode = U_ZERO_ERROR;
14252e5b6d6dSopenharmony_ci
14262e5b6d6dSopenharmony_ci    /* Initialize ICU */
14272e5b6d6dSopenharmony_ci    if (!defaultDataFound) {
14282e5b6d6dSopenharmony_ci        IntlTest::setICU_DATA();   // Must set data directory before u_init() is called.
14292e5b6d6dSopenharmony_ci    }
14302e5b6d6dSopenharmony_ci    u_init(&errorCode);
14312e5b6d6dSopenharmony_ci    if (U_FAILURE(errorCode)) {
14322e5b6d6dSopenharmony_ci        fprintf(stderr,
14332e5b6d6dSopenharmony_ci            "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
14342e5b6d6dSopenharmony_ci            "*** Check the ICU_DATA environment variable and \n"
14352e5b6d6dSopenharmony_ci            "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
14362e5b6d6dSopenharmony_ci            if(warnOnMissingData == 0) {
14372e5b6d6dSopenharmony_ci                fprintf(stderr, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
14382e5b6d6dSopenharmony_ci                u_cleanup();
14392e5b6d6dSopenharmony_ci                return 1;
14402e5b6d6dSopenharmony_ci            }
14412e5b6d6dSopenharmony_ci    }
14422e5b6d6dSopenharmony_ci
14432e5b6d6dSopenharmony_ci    // initial check for the default converter
14442e5b6d6dSopenharmony_ci    errorCode = U_ZERO_ERROR;
14452e5b6d6dSopenharmony_ci    cnv = ucnv_open(0, &errorCode);
14462e5b6d6dSopenharmony_ci    if(cnv != 0) {
14472e5b6d6dSopenharmony_ci        // ok
14482e5b6d6dSopenharmony_ci        ucnv_close(cnv);
14492e5b6d6dSopenharmony_ci    } else {
14502e5b6d6dSopenharmony_ci        fprintf(stdout,
14512e5b6d6dSopenharmony_ci                "*** %s! The default converter [%s] cannot be opened.\n"
14522e5b6d6dSopenharmony_ci                "*** Check the ICU_DATA environment variable and\n"
14532e5b6d6dSopenharmony_ci                "*** check that the data files are present.\n",
14542e5b6d6dSopenharmony_ci                warnOrErr, ucnv_getDefaultName());
14552e5b6d6dSopenharmony_ci        if(!warnOnMissingData) {
14562e5b6d6dSopenharmony_ci          fprintf(stdout, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
14572e5b6d6dSopenharmony_ci          return 1;
14582e5b6d6dSopenharmony_ci        }
14592e5b6d6dSopenharmony_ci    }
14602e5b6d6dSopenharmony_ci
14612e5b6d6dSopenharmony_ci    // try more data
14622e5b6d6dSopenharmony_ci    cnv = ucnv_open(TRY_CNV_2, &errorCode);
14632e5b6d6dSopenharmony_ci    if(cnv != 0) {
14642e5b6d6dSopenharmony_ci        // ok
14652e5b6d6dSopenharmony_ci        ucnv_close(cnv);
14662e5b6d6dSopenharmony_ci    } else {
14672e5b6d6dSopenharmony_ci        fprintf(stdout,
14682e5b6d6dSopenharmony_ci                "*** %s! The converter for " TRY_CNV_2 " cannot be opened.\n"
14692e5b6d6dSopenharmony_ci                "*** Check the ICU_DATA environment variable and \n"
14702e5b6d6dSopenharmony_ci                "*** check that the data files are present.\n", warnOrErr);
14712e5b6d6dSopenharmony_ci        if(!warnOnMissingData) {
14722e5b6d6dSopenharmony_ci          fprintf(stdout, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
14732e5b6d6dSopenharmony_ci          return 1;
14742e5b6d6dSopenharmony_ci        }
14752e5b6d6dSopenharmony_ci    }
14762e5b6d6dSopenharmony_ci
14772e5b6d6dSopenharmony_ci    UResourceBundle *rb = ures_open(0, "en", &errorCode);
14782e5b6d6dSopenharmony_ci    ures_close(rb);
14792e5b6d6dSopenharmony_ci    if(U_FAILURE(errorCode)) {
14802e5b6d6dSopenharmony_ci        fprintf(stdout,
14812e5b6d6dSopenharmony_ci                "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
14822e5b6d6dSopenharmony_ci                "*** Check the ICU_DATA environment variable and \n"
14832e5b6d6dSopenharmony_ci                "*** check that the data files are present.\n", warnOrErr);
14842e5b6d6dSopenharmony_ci        if(!warnOnMissingData) {
14852e5b6d6dSopenharmony_ci          fprintf(stdout, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
14862e5b6d6dSopenharmony_ci          return 1;
14872e5b6d6dSopenharmony_ci        }
14882e5b6d6dSopenharmony_ci    }
14892e5b6d6dSopenharmony_ci
14902e5b6d6dSopenharmony_ci    Locale originalLocale;  // Save the default locale for comparison later on.
14912e5b6d6dSopenharmony_ci
14922e5b6d6dSopenharmony_ci    if(ctest_xml_init("intltest"))
14932e5b6d6dSopenharmony_ci      return 1;
14942e5b6d6dSopenharmony_ci
14952e5b6d6dSopenharmony_ci
14962e5b6d6dSopenharmony_ci    /* TODO: Add option to call u_cleanup and rerun tests. */
14972e5b6d6dSopenharmony_ci    if (all) {
14982e5b6d6dSopenharmony_ci        major.runTest();
14992e5b6d6dSopenharmony_ci        if (leaks) {
15002e5b6d6dSopenharmony_ci            major.run_phase2( NULL, NULL );
15012e5b6d6dSopenharmony_ci        }
15022e5b6d6dSopenharmony_ci    }else{
15032e5b6d6dSopenharmony_ci        for (int i = 1; i < argc; ++i) {
15042e5b6d6dSopenharmony_ci            if (argv[i][0] != '-') {
15052e5b6d6dSopenharmony_ci                char* name = argv[i];
15062e5b6d6dSopenharmony_ci                fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
15072e5b6d6dSopenharmony_ci
15082e5b6d6dSopenharmony_ci                char baseName[1024];
15092e5b6d6dSopenharmony_ci                sprintf(baseName, "/%s/", name);
15102e5b6d6dSopenharmony_ci
15112e5b6d6dSopenharmony_ci                char* parameter = strchr( name, '@' );
15122e5b6d6dSopenharmony_ci                if (parameter) {
15132e5b6d6dSopenharmony_ci                    *parameter = 0;
15142e5b6d6dSopenharmony_ci                    parameter += 1;
15152e5b6d6dSopenharmony_ci                }
15162e5b6d6dSopenharmony_ci                execCount = 0;
15172e5b6d6dSopenharmony_ci                UBool res = major.runTest( name, parameter, baseName );
15182e5b6d6dSopenharmony_ci                if (leaks && res) {
15192e5b6d6dSopenharmony_ci                    major.run_phase2( name, parameter );
15202e5b6d6dSopenharmony_ci                }
15212e5b6d6dSopenharmony_ci                if (!res || (execCount <= 0)) {
15222e5b6d6dSopenharmony_ci                    fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
15232e5b6d6dSopenharmony_ci                }
15242e5b6d6dSopenharmony_ci            } else if(!strcmp(argv[i],"-x")) {
15252e5b6d6dSopenharmony_ci              i++;
15262e5b6d6dSopenharmony_ci            }
15272e5b6d6dSopenharmony_ci        }
15282e5b6d6dSopenharmony_ci    }
15292e5b6d6dSopenharmony_ci
15302e5b6d6dSopenharmony_ci
15312e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
15322e5b6d6dSopenharmony_ci    CalendarTimeZoneTest::cleanup();
15332e5b6d6dSopenharmony_ci#endif
15342e5b6d6dSopenharmony_ci
15352e5b6d6dSopenharmony_ci    free(_testDataPath);
15362e5b6d6dSopenharmony_ci    _testDataPath = 0;
15372e5b6d6dSopenharmony_ci
15382e5b6d6dSopenharmony_ci    Locale lastDefaultLocale;
15392e5b6d6dSopenharmony_ci    if (originalLocale != lastDefaultLocale) {
15402e5b6d6dSopenharmony_ci        major.errln("FAILURE: A test changed the default locale without resetting it.");
15412e5b6d6dSopenharmony_ci    }
15422e5b6d6dSopenharmony_ci
15432e5b6d6dSopenharmony_ci    fprintf(stdout, "\n--------------------------------------\n");
15442e5b6d6dSopenharmony_ci    if( major.printKnownIssues() ) {
15452e5b6d6dSopenharmony_ci      fprintf(stdout, " To run suppressed tests, use the -K option. \n");
15462e5b6d6dSopenharmony_ci    }
15472e5b6d6dSopenharmony_ci    if (major.getErrors() == 0) {
15482e5b6d6dSopenharmony_ci        /* Call it twice to make sure that the defaults were reset. */
15492e5b6d6dSopenharmony_ci        /* Call it before the OK message to verify proper cleanup. */
15502e5b6d6dSopenharmony_ci        u_cleanup();
15512e5b6d6dSopenharmony_ci        u_cleanup();
15522e5b6d6dSopenharmony_ci
15532e5b6d6dSopenharmony_ci        fprintf(stdout, "OK: All tests passed without error.\n");
15542e5b6d6dSopenharmony_ci
15552e5b6d6dSopenharmony_ci        if (major.getDataErrors() != 0) {
15562e5b6d6dSopenharmony_ci            fprintf(stdout, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
15572e5b6d6dSopenharmony_ci        }
15582e5b6d6dSopenharmony_ci    }else{
15592e5b6d6dSopenharmony_ci        fprintf(stdout, "Errors in total: %ld.\n", (long)major.getErrors());
15602e5b6d6dSopenharmony_ci        major.printErrors();
15612e5b6d6dSopenharmony_ci
15622e5b6d6dSopenharmony_ci        if(summary_file != NULL) {
15632e5b6d6dSopenharmony_ci          FILE *summf = fopen(summary_file, "w");
15642e5b6d6dSopenharmony_ci          if( summf != NULL) {
15652e5b6d6dSopenharmony_ci            char buf[10000];
15662e5b6d6dSopenharmony_ci            int32_t length = errorList.extract(0, errorList.length(), buf, sizeof(buf));
15672e5b6d6dSopenharmony_ci            fwrite(buf, sizeof(*buf), length, (FILE*)summf);
15682e5b6d6dSopenharmony_ci            fclose(summf);
15692e5b6d6dSopenharmony_ci          }
15702e5b6d6dSopenharmony_ci        }
15712e5b6d6dSopenharmony_ci
15722e5b6d6dSopenharmony_ci
15732e5b6d6dSopenharmony_ci        if (major.getDataErrors() != 0) {
15742e5b6d6dSopenharmony_ci            fprintf(stdout, "\t*Note* some errors are data-loading related. If the data used is not the \n"
15752e5b6d6dSopenharmony_ci                    "\tstock ICU data (i.e some have been added or removed), consider using\n"
15762e5b6d6dSopenharmony_ci                    "\tthe '-w' option to turn these errors into warnings.\n");
15772e5b6d6dSopenharmony_ci        }
15782e5b6d6dSopenharmony_ci
15792e5b6d6dSopenharmony_ci        /* Call afterwards to display errors. */
15802e5b6d6dSopenharmony_ci        u_cleanup();
15812e5b6d6dSopenharmony_ci    }
15822e5b6d6dSopenharmony_ci
15832e5b6d6dSopenharmony_ci#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
15842e5b6d6dSopenharmony_ci    unistr_printLengths();
15852e5b6d6dSopenharmony_ci#endif
15862e5b6d6dSopenharmony_ci
15872e5b6d6dSopenharmony_ci    fprintf(stdout, "--------------------------------------\n");
15882e5b6d6dSopenharmony_ci
15892e5b6d6dSopenharmony_ci    if (execCount <= 0) {
15902e5b6d6dSopenharmony_ci        fprintf(stdout, "***** Not all called tests actually exist! *****\n");
15912e5b6d6dSopenharmony_ci    }
15922e5b6d6dSopenharmony_ci    if(!no_time) {
15932e5b6d6dSopenharmony_ci      endTime = uprv_getRawUTCtime();
15942e5b6d6dSopenharmony_ci      diffTime = (int32_t)(endTime - startTime);
15952e5b6d6dSopenharmony_ci      printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
15962e5b6d6dSopenharmony_ci             (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
15972e5b6d6dSopenharmony_ci             (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
15982e5b6d6dSopenharmony_ci             (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
15992e5b6d6dSopenharmony_ci             (int)(diffTime%U_MILLIS_PER_SECOND));
16002e5b6d6dSopenharmony_ci    }
16012e5b6d6dSopenharmony_ci
16022e5b6d6dSopenharmony_ci    if(ctest_xml_fini())
16032e5b6d6dSopenharmony_ci      return 1;
16042e5b6d6dSopenharmony_ci
16052e5b6d6dSopenharmony_ci    return major.getErrors();
16062e5b6d6dSopenharmony_ci}
16072e5b6d6dSopenharmony_ci
16082e5b6d6dSopenharmony_ciconst char* IntlTest::loadTestData(UErrorCode& err){
16092e5b6d6dSopenharmony_ci    if ( _testDataPath == NULL){
16102e5b6d6dSopenharmony_ci        const char*      directory=NULL;
16112e5b6d6dSopenharmony_ci        UResourceBundle* test =NULL;
16122e5b6d6dSopenharmony_ci        char* tdpath=NULL;
16132e5b6d6dSopenharmony_ci        const char* tdrelativepath;
16142e5b6d6dSopenharmony_ci
16152e5b6d6dSopenharmony_ci#if defined (U_TOPBUILDDIR)
16162e5b6d6dSopenharmony_ci        tdrelativepath = "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
16172e5b6d6dSopenharmony_ci        directory = U_TOPBUILDDIR;
16182e5b6d6dSopenharmony_ci#else
16192e5b6d6dSopenharmony_ci        tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
16202e5b6d6dSopenharmony_ci        directory = pathToDataDirectory();
16212e5b6d6dSopenharmony_ci#endif
16222e5b6d6dSopenharmony_ci
16232e5b6d6dSopenharmony_ci        tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
16242e5b6d6dSopenharmony_ci
16252e5b6d6dSopenharmony_ci        if (tdpath == NULL) {
16262e5b6d6dSopenharmony_ci            err = U_MEMORY_ALLOCATION_ERROR;
16272e5b6d6dSopenharmony_ci            it_dataerrln((UnicodeString) "Could not allocate memory for _testDataPath " + u_errorName(err));
16282e5b6d6dSopenharmony_ci            return "";
16292e5b6d6dSopenharmony_ci        }
16302e5b6d6dSopenharmony_ci
16312e5b6d6dSopenharmony_ci        /* u_getDataDirectory shoul return \source\data ... set the
16322e5b6d6dSopenharmony_ci         * directory to ..\source\data\..\test\testdata\out\testdata
16332e5b6d6dSopenharmony_ci         */
16342e5b6d6dSopenharmony_ci        strcpy(tdpath, directory);
16352e5b6d6dSopenharmony_ci        strcat(tdpath, tdrelativepath);
16362e5b6d6dSopenharmony_ci        strcat(tdpath,"testdata");
16372e5b6d6dSopenharmony_ci
16382e5b6d6dSopenharmony_ci        test=ures_open(tdpath, "testtypes", &err);
16392e5b6d6dSopenharmony_ci
16402e5b6d6dSopenharmony_ci        if (U_FAILURE(err)) {
16412e5b6d6dSopenharmony_ci            err = U_FILE_ACCESS_ERROR;
16422e5b6d6dSopenharmony_ci            it_dataerrln((UnicodeString)"Could not load testtypes.res in testdata bundle with path " + tdpath + (UnicodeString)" - " + u_errorName(err));
16432e5b6d6dSopenharmony_ci            return "";
16442e5b6d6dSopenharmony_ci        }
16452e5b6d6dSopenharmony_ci        ures_close(test);
16462e5b6d6dSopenharmony_ci        _testDataPath = tdpath;
16472e5b6d6dSopenharmony_ci        return _testDataPath;
16482e5b6d6dSopenharmony_ci    }
16492e5b6d6dSopenharmony_ci    return _testDataPath;
16502e5b6d6dSopenharmony_ci}
16512e5b6d6dSopenharmony_ci
16522e5b6d6dSopenharmony_ciconst char* IntlTest::getTestDataPath(UErrorCode& err) {
16532e5b6d6dSopenharmony_ci    return loadTestData(err);
16542e5b6d6dSopenharmony_ci}
16552e5b6d6dSopenharmony_ci
16562e5b6d6dSopenharmony_ci/**
16572e5b6d6dSopenharmony_ci * Returns the path to icu/source/test/testdata/
16582e5b6d6dSopenharmony_ci * Note: this function is parallel with C loadSourceTestData in cintltst.c
16592e5b6d6dSopenharmony_ci */
16602e5b6d6dSopenharmony_ciconst char *IntlTest::getSourceTestData(UErrorCode& /*err*/) {
16612e5b6d6dSopenharmony_ci    const char *srcDataDir = NULL;
16622e5b6d6dSopenharmony_ci#ifdef U_TOPSRCDIR
16632e5b6d6dSopenharmony_ci    srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
16642e5b6d6dSopenharmony_ci#else
16652e5b6d6dSopenharmony_ci    srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
16662e5b6d6dSopenharmony_ci    FILE *f = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "rbbitst.txt", "r");
16672e5b6d6dSopenharmony_ci    if (f) {
16682e5b6d6dSopenharmony_ci        /* We're in icu/source/test/intltest/ */
16692e5b6d6dSopenharmony_ci        fclose(f);
16702e5b6d6dSopenharmony_ci    }
16712e5b6d6dSopenharmony_ci    else {
16722e5b6d6dSopenharmony_ci        /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
16732e5b6d6dSopenharmony_ci        srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING
16742e5b6d6dSopenharmony_ci                     "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
16752e5b6d6dSopenharmony_ci    }
16762e5b6d6dSopenharmony_ci#endif
16772e5b6d6dSopenharmony_ci    return srcDataDir;
16782e5b6d6dSopenharmony_ci}
16792e5b6d6dSopenharmony_ci
16802e5b6d6dSopenharmony_cichar *IntlTest::getUnidataPath(char path[]) {
16812e5b6d6dSopenharmony_ci    const int kUnicodeDataTxtLength = 15;  // strlen("UnicodeData.txt")
16822e5b6d6dSopenharmony_ci
16832e5b6d6dSopenharmony_ci    // Look inside ICU_DATA first.
16842e5b6d6dSopenharmony_ci    strcpy(path, pathToDataDirectory());
16852e5b6d6dSopenharmony_ci    strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
16862e5b6d6dSopenharmony_ci    FILE *f = fopen(path, "r");
16872e5b6d6dSopenharmony_ci    if(f != NULL) {
16882e5b6d6dSopenharmony_ci        fclose(f);
16892e5b6d6dSopenharmony_ci        *(strchr(path, 0) - kUnicodeDataTxtLength) = 0;  // Remove the basename.
16902e5b6d6dSopenharmony_ci        return path;
16912e5b6d6dSopenharmony_ci    }
16922e5b6d6dSopenharmony_ci
16932e5b6d6dSopenharmony_ci    // As a fallback, try to guess where the source data was located
16942e5b6d6dSopenharmony_ci    // at the time ICU was built, and look there.
16952e5b6d6dSopenharmony_ci#   ifdef U_TOPSRCDIR
16962e5b6d6dSopenharmony_ci        strcpy(path, U_TOPSRCDIR  U_FILE_SEP_STRING "data");
16972e5b6d6dSopenharmony_ci#   else
16982e5b6d6dSopenharmony_ci        UErrorCode errorCode = U_ZERO_ERROR;
16992e5b6d6dSopenharmony_ci        const char *testDataPath = loadTestData(errorCode);
17002e5b6d6dSopenharmony_ci        if(U_FAILURE(errorCode)) {
17012e5b6d6dSopenharmony_ci            it_errln(UnicodeString(
17022e5b6d6dSopenharmony_ci                        "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
17032e5b6d6dSopenharmony_ci                    u_errorName(errorCode));
17042e5b6d6dSopenharmony_ci            return NULL;
17052e5b6d6dSopenharmony_ci        }
17062e5b6d6dSopenharmony_ci        strcpy(path, testDataPath);
17072e5b6d6dSopenharmony_ci        strcat(path, U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
17082e5b6d6dSopenharmony_ci                     U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
17092e5b6d6dSopenharmony_ci                     U_FILE_SEP_STRING "data");
17102e5b6d6dSopenharmony_ci#   endif
17112e5b6d6dSopenharmony_ci    strcat(path, U_FILE_SEP_STRING);
17122e5b6d6dSopenharmony_ci    strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
17132e5b6d6dSopenharmony_ci    f = fopen(path, "r");
17142e5b6d6dSopenharmony_ci    if(f != NULL) {
17152e5b6d6dSopenharmony_ci        fclose(f);
17162e5b6d6dSopenharmony_ci        *(strchr(path, 0) - kUnicodeDataTxtLength) = 0;  // Remove the basename.
17172e5b6d6dSopenharmony_ci        return path;
17182e5b6d6dSopenharmony_ci    }
17192e5b6d6dSopenharmony_ci    return NULL;
17202e5b6d6dSopenharmony_ci}
17212e5b6d6dSopenharmony_ci
17222e5b6d6dSopenharmony_ciconst char* IntlTest::fgDataDir = NULL;
17232e5b6d6dSopenharmony_ci
17242e5b6d6dSopenharmony_ci/* returns the path to icu/source/data */
17252e5b6d6dSopenharmony_ciconst char *  IntlTest::pathToDataDirectory()
17262e5b6d6dSopenharmony_ci{
17272e5b6d6dSopenharmony_ci
17282e5b6d6dSopenharmony_ci    if(fgDataDir != NULL) {
17292e5b6d6dSopenharmony_ci        return fgDataDir;
17302e5b6d6dSopenharmony_ci    }
17312e5b6d6dSopenharmony_ci
17322e5b6d6dSopenharmony_ci    /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
17332e5b6d6dSopenharmony_ci    //              to point to the top of the build hierarchy, which may or
17342e5b6d6dSopenharmony_ci    //              may not be the same as the source directory, depending on
17352e5b6d6dSopenharmony_ci    //              the configure options used.  At any rate,
17362e5b6d6dSopenharmony_ci    //              set the data path to the built data from this directory.
17372e5b6d6dSopenharmony_ci    //              The value is complete with quotes, so it can be used
17382e5b6d6dSopenharmony_ci    //              as-is as a string constant.
17392e5b6d6dSopenharmony_ci    */
17402e5b6d6dSopenharmony_ci#if defined (U_TOPSRCDIR)
17412e5b6d6dSopenharmony_ci    {
17422e5b6d6dSopenharmony_ci        fgDataDir = U_TOPSRCDIR  U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
17432e5b6d6dSopenharmony_ci    }
17442e5b6d6dSopenharmony_ci#else
17452e5b6d6dSopenharmony_ci
17462e5b6d6dSopenharmony_ci    /* On Windows, the file name obtained from __FILE__ includes a full path.
17472e5b6d6dSopenharmony_ci     *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
17482e5b6d6dSopenharmony_ci     *             Change to    "wherever\icu\source\data"
17492e5b6d6dSopenharmony_ci     */
17502e5b6d6dSopenharmony_ci    {
17512e5b6d6dSopenharmony_ci        static char p[sizeof(__FILE__) + 10];
17522e5b6d6dSopenharmony_ci        char *pBackSlash;
17532e5b6d6dSopenharmony_ci        int i;
17542e5b6d6dSopenharmony_ci
17552e5b6d6dSopenharmony_ci        strcpy(p, __FILE__);
17562e5b6d6dSopenharmony_ci        /* We want to back over three '\' chars.                            */
17572e5b6d6dSopenharmony_ci        /*   Only Windows should end up here, so looking for '\' is safe.   */
17582e5b6d6dSopenharmony_ci        for (i=1; i<=3; i++) {
17592e5b6d6dSopenharmony_ci            pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
17602e5b6d6dSopenharmony_ci            if (pBackSlash != NULL) {
17612e5b6d6dSopenharmony_ci                *pBackSlash = 0;        /* Truncate the string at the '\'   */
17622e5b6d6dSopenharmony_ci            }
17632e5b6d6dSopenharmony_ci        }
17642e5b6d6dSopenharmony_ci
17652e5b6d6dSopenharmony_ci        if (pBackSlash != NULL) {
17662e5b6d6dSopenharmony_ci            /* We found and truncated three names from the path.
17672e5b6d6dSopenharmony_ci            *  Now append "source\data" and set the environment
17682e5b6d6dSopenharmony_ci            */
17692e5b6d6dSopenharmony_ci            strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
17702e5b6d6dSopenharmony_ci            fgDataDir = p;
17712e5b6d6dSopenharmony_ci        }
17722e5b6d6dSopenharmony_ci        else {
17732e5b6d6dSopenharmony_ci            /* __FILE__ on MSVC7 does not contain the directory */
17742e5b6d6dSopenharmony_ci            FILE *file = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
17752e5b6d6dSopenharmony_ci            if (file) {
17762e5b6d6dSopenharmony_ci                fclose(file);
17772e5b6d6dSopenharmony_ci                fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
17782e5b6d6dSopenharmony_ci            }
17792e5b6d6dSopenharmony_ci            else {
17802e5b6d6dSopenharmony_ci                fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
17812e5b6d6dSopenharmony_ci            }
17822e5b6d6dSopenharmony_ci        }
17832e5b6d6dSopenharmony_ci    }
17842e5b6d6dSopenharmony_ci#endif
17852e5b6d6dSopenharmony_ci
17862e5b6d6dSopenharmony_ci    return fgDataDir;
17872e5b6d6dSopenharmony_ci
17882e5b6d6dSopenharmony_ci}
17892e5b6d6dSopenharmony_ci
17902e5b6d6dSopenharmony_ci/*
17912e5b6d6dSopenharmony_ci * This is a variant of cintltst/ccolltst.c:CharsToUChars().
17922e5b6d6dSopenharmony_ci * It converts an invariant-character string into a UnicodeString, with
17932e5b6d6dSopenharmony_ci * unescaping \u sequences.
17942e5b6d6dSopenharmony_ci */
17952e5b6d6dSopenharmony_ciUnicodeString CharsToUnicodeString(const char* chars){
17962e5b6d6dSopenharmony_ci    return UnicodeString(chars, -1, US_INV).unescape();
17972e5b6d6dSopenharmony_ci}
17982e5b6d6dSopenharmony_ci
17992e5b6d6dSopenharmony_ciUnicodeString ctou(const char* chars) {
18002e5b6d6dSopenharmony_ci    return CharsToUnicodeString(chars);
18012e5b6d6dSopenharmony_ci}
18022e5b6d6dSopenharmony_ci
18032e5b6d6dSopenharmony_ci#define RAND_M  (714025)
18042e5b6d6dSopenharmony_ci#define RAND_IA (1366)
18052e5b6d6dSopenharmony_ci#define RAND_IC (150889)
18062e5b6d6dSopenharmony_ci
18072e5b6d6dSopenharmony_cistatic int32_t RAND_SEED;
18082e5b6d6dSopenharmony_ci
18092e5b6d6dSopenharmony_ci/**
18102e5b6d6dSopenharmony_ci * Returns a uniform random value x, with 0.0 <= x < 1.0.  Use
18112e5b6d6dSopenharmony_ci * with care: Does not return all possible values; returns one of
18122e5b6d6dSopenharmony_ci * 714,025 values, uniformly spaced.  However, the period is
18132e5b6d6dSopenharmony_ci * effectively infinite.  See: Numerical Recipes, section 7.1.
18142e5b6d6dSopenharmony_ci *
18152e5b6d6dSopenharmony_ci * @param seedp pointer to seed. Set *seedp to any negative value
18162e5b6d6dSopenharmony_ci * to restart the sequence.
18172e5b6d6dSopenharmony_ci */
18182e5b6d6dSopenharmony_cifloat IntlTest::random(int32_t* seedp) {
18192e5b6d6dSopenharmony_ci    static int32_t iy, ir[98];
18202e5b6d6dSopenharmony_ci    static UBool first=true;
18212e5b6d6dSopenharmony_ci    int32_t j;
18222e5b6d6dSopenharmony_ci    if (*seedp < 0 || first) {
18232e5b6d6dSopenharmony_ci        first = false;
18242e5b6d6dSopenharmony_ci        if ((*seedp=(RAND_IC-(*seedp)) % RAND_M) < 0) *seedp = -(*seedp);
18252e5b6d6dSopenharmony_ci        for (j=1;j<=97;++j) {
18262e5b6d6dSopenharmony_ci            *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
18272e5b6d6dSopenharmony_ci            ir[j]=(*seedp);
18282e5b6d6dSopenharmony_ci        }
18292e5b6d6dSopenharmony_ci        *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
18302e5b6d6dSopenharmony_ci        iy=(*seedp);
18312e5b6d6dSopenharmony_ci    }
18322e5b6d6dSopenharmony_ci    j=(int32_t)(1 + 97.0*iy/RAND_M);
18332e5b6d6dSopenharmony_ci    U_ASSERT(j>=1 && j<=97);
18342e5b6d6dSopenharmony_ci    iy=ir[j];
18352e5b6d6dSopenharmony_ci    *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
18362e5b6d6dSopenharmony_ci    ir[j]=(*seedp);
18372e5b6d6dSopenharmony_ci    return (float) iy/RAND_M;
18382e5b6d6dSopenharmony_ci}
18392e5b6d6dSopenharmony_ci
18402e5b6d6dSopenharmony_ci/**
18412e5b6d6dSopenharmony_ci * Convenience method using a global seed.
18422e5b6d6dSopenharmony_ci */
18432e5b6d6dSopenharmony_cifloat IntlTest::random() {
18442e5b6d6dSopenharmony_ci    return random(&RAND_SEED);
18452e5b6d6dSopenharmony_ci}
18462e5b6d6dSopenharmony_ci
18472e5b6d6dSopenharmony_ci
18482e5b6d6dSopenharmony_ci/*
18492e5b6d6dSopenharmony_ci * Integer random number class implementation.
18502e5b6d6dSopenharmony_ci * Similar to C++ std::minstd_rand, with the same algorithm & constants.
18512e5b6d6dSopenharmony_ci */
18522e5b6d6dSopenharmony_ciIntlTest::icu_rand::icu_rand(uint32_t seed) {
18532e5b6d6dSopenharmony_ci    seed = seed % 2147483647UL;
18542e5b6d6dSopenharmony_ci    if (seed == 0) {
18552e5b6d6dSopenharmony_ci        seed = 1;
18562e5b6d6dSopenharmony_ci    }
18572e5b6d6dSopenharmony_ci    fLast = seed;
18582e5b6d6dSopenharmony_ci}
18592e5b6d6dSopenharmony_ci
18602e5b6d6dSopenharmony_ciIntlTest::icu_rand::~icu_rand() {}
18612e5b6d6dSopenharmony_ci
18622e5b6d6dSopenharmony_civoid IntlTest::icu_rand::seed(uint32_t seed) {
18632e5b6d6dSopenharmony_ci    if (seed == 0) {
18642e5b6d6dSopenharmony_ci        seed = 1;
18652e5b6d6dSopenharmony_ci    }
18662e5b6d6dSopenharmony_ci    fLast = seed;
18672e5b6d6dSopenharmony_ci}
18682e5b6d6dSopenharmony_ci
18692e5b6d6dSopenharmony_ciuint32_t IntlTest::icu_rand::operator() () {
18702e5b6d6dSopenharmony_ci    fLast = ((uint64_t)fLast * 48271UL) % 2147483647UL;
18712e5b6d6dSopenharmony_ci    return fLast;
18722e5b6d6dSopenharmony_ci}
18732e5b6d6dSopenharmony_ci
18742e5b6d6dSopenharmony_ciuint32_t IntlTest::icu_rand::getSeed() {
18752e5b6d6dSopenharmony_ci    return (uint32_t) fLast;
18762e5b6d6dSopenharmony_ci}
18772e5b6d6dSopenharmony_ci
18782e5b6d6dSopenharmony_ci
18792e5b6d6dSopenharmony_ci
18802e5b6d6dSopenharmony_cistatic inline UChar toHex(int32_t i) {
18812e5b6d6dSopenharmony_ci    return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10)));
18822e5b6d6dSopenharmony_ci}
18832e5b6d6dSopenharmony_ci
18842e5b6d6dSopenharmony_cistatic UnicodeString& escape(const UnicodeString& s, UnicodeString& result) {
18852e5b6d6dSopenharmony_ci    for (int32_t i=0; i<s.length(); ++i) {
18862e5b6d6dSopenharmony_ci        UChar c = s[i];
18872e5b6d6dSopenharmony_ci        if (c <= (UChar)0x7F) {
18882e5b6d6dSopenharmony_ci            result += c;
18892e5b6d6dSopenharmony_ci        } else {
18902e5b6d6dSopenharmony_ci            result += (UChar)0x5c;
18912e5b6d6dSopenharmony_ci            result += (UChar)0x75;
18922e5b6d6dSopenharmony_ci            result += toHex((c >> 12) & 0xF);
18932e5b6d6dSopenharmony_ci            result += toHex((c >>  8) & 0xF);
18942e5b6d6dSopenharmony_ci            result += toHex((c >>  4) & 0xF);
18952e5b6d6dSopenharmony_ci            result += toHex( c        & 0xF);
18962e5b6d6dSopenharmony_ci        }
18972e5b6d6dSopenharmony_ci    }
18982e5b6d6dSopenharmony_ci    return result;
18992e5b6d6dSopenharmony_ci}
19002e5b6d6dSopenharmony_ci
19012e5b6d6dSopenharmony_ci#define VERBOSE_ASSERTIONS
19022e5b6d6dSopenharmony_ci
19032e5b6d6dSopenharmony_ciUBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError, const char *file, int line) {
19042e5b6d6dSopenharmony_ci    if (file != NULL) {
19052e5b6d6dSopenharmony_ci        if (!condition) {
19062e5b6d6dSopenharmony_ci            if (possibleDataError) {
19072e5b6d6dSopenharmony_ci                dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
19082e5b6d6dSopenharmony_ci            } else {
19092e5b6d6dSopenharmony_ci                errln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
19102e5b6d6dSopenharmony_ci            }
19112e5b6d6dSopenharmony_ci        } else if (!quiet) {
19122e5b6d6dSopenharmony_ci            logln("%s:%d: Ok: %s", file, line, message);
19132e5b6d6dSopenharmony_ci        }
19142e5b6d6dSopenharmony_ci    } else {
19152e5b6d6dSopenharmony_ci        if (!condition) {
19162e5b6d6dSopenharmony_ci            if (possibleDataError) {
19172e5b6d6dSopenharmony_ci                dataerrln("FAIL: assertTrue() failed: %s", message);
19182e5b6d6dSopenharmony_ci            } else {
19192e5b6d6dSopenharmony_ci                errln("FAIL: assertTrue() failed: %s", message);
19202e5b6d6dSopenharmony_ci            }
19212e5b6d6dSopenharmony_ci        } else if (!quiet) {
19222e5b6d6dSopenharmony_ci            logln("Ok: %s", message);
19232e5b6d6dSopenharmony_ci        }
19242e5b6d6dSopenharmony_ci
19252e5b6d6dSopenharmony_ci    }
19262e5b6d6dSopenharmony_ci    return condition;
19272e5b6d6dSopenharmony_ci}
19282e5b6d6dSopenharmony_ci
19292e5b6d6dSopenharmony_ciUBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet, UBool possibleDataError) {
19302e5b6d6dSopenharmony_ci    if (condition) {
19312e5b6d6dSopenharmony_ci        if (possibleDataError) {
19322e5b6d6dSopenharmony_ci            dataerrln("FAIL: assertFalse() failed: %s", message);
19332e5b6d6dSopenharmony_ci        } else {
19342e5b6d6dSopenharmony_ci            errln("FAIL: assertFalse() failed: %s", message);
19352e5b6d6dSopenharmony_ci        }
19362e5b6d6dSopenharmony_ci    } else if (!quiet) {
19372e5b6d6dSopenharmony_ci        logln("Ok: %s", message);
19382e5b6d6dSopenharmony_ci    }
19392e5b6d6dSopenharmony_ci    return !condition;
19402e5b6d6dSopenharmony_ci}
19412e5b6d6dSopenharmony_ci
19422e5b6d6dSopenharmony_ciUBool IntlTest::assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError, const char *file, int line) {
19432e5b6d6dSopenharmony_ci    if( file==NULL ) {
19442e5b6d6dSopenharmony_ci      file = ""; // prevent failure if no file given
19452e5b6d6dSopenharmony_ci    }
19462e5b6d6dSopenharmony_ci    if (U_FAILURE(ec)) {
19472e5b6d6dSopenharmony_ci        if (possibleDataError) {
19482e5b6d6dSopenharmony_ci          dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
19492e5b6d6dSopenharmony_ci        } else {
19502e5b6d6dSopenharmony_ci          errcheckln(ec, "FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
19512e5b6d6dSopenharmony_ci        }
19522e5b6d6dSopenharmony_ci        return false;
19532e5b6d6dSopenharmony_ci    } else {
19542e5b6d6dSopenharmony_ci      logln("OK: %s:%d: %s - (%s)", file, line, message, u_errorName(ec));
19552e5b6d6dSopenharmony_ci    }
19562e5b6d6dSopenharmony_ci    return true;
19572e5b6d6dSopenharmony_ci}
19582e5b6d6dSopenharmony_ci
19592e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
19602e5b6d6dSopenharmony_ci                             const UnicodeString& expected,
19612e5b6d6dSopenharmony_ci                             const UnicodeString& actual,
19622e5b6d6dSopenharmony_ci                             UBool possibleDataError) {
19632e5b6d6dSopenharmony_ci    if (expected != actual) {
19642e5b6d6dSopenharmony_ci        if (possibleDataError) {
19652e5b6d6dSopenharmony_ci            dataerrln((UnicodeString)"FAIL: " + message + "; got " +
19662e5b6d6dSopenharmony_ci                  prettify(actual) +
19672e5b6d6dSopenharmony_ci                  "; expected " + prettify(expected));
19682e5b6d6dSopenharmony_ci        } else {
19692e5b6d6dSopenharmony_ci            errln((UnicodeString)"FAIL: " + message + "; got " +
19702e5b6d6dSopenharmony_ci                  prettify(actual) +
19712e5b6d6dSopenharmony_ci                  "; expected " + prettify(expected));
19722e5b6d6dSopenharmony_ci        }
19732e5b6d6dSopenharmony_ci        return false;
19742e5b6d6dSopenharmony_ci    }
19752e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
19762e5b6d6dSopenharmony_ci    else {
19772e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + prettify(actual));
19782e5b6d6dSopenharmony_ci    }
19792e5b6d6dSopenharmony_ci#endif
19802e5b6d6dSopenharmony_ci    return true;
19812e5b6d6dSopenharmony_ci}
19822e5b6d6dSopenharmony_ci
19832e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
19842e5b6d6dSopenharmony_ci                             const char* expected,
19852e5b6d6dSopenharmony_ci                             const char* actual) {
19862e5b6d6dSopenharmony_ci    U_ASSERT(expected != nullptr);
19872e5b6d6dSopenharmony_ci    U_ASSERT(actual != nullptr);
19882e5b6d6dSopenharmony_ci    if (uprv_strcmp(expected, actual) != 0) {
19892e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got \"" +
19902e5b6d6dSopenharmony_ci              actual +
19912e5b6d6dSopenharmony_ci              "\"; expected \"" + expected + "\"");
19922e5b6d6dSopenharmony_ci        return false;
19932e5b6d6dSopenharmony_ci    }
19942e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
19952e5b6d6dSopenharmony_ci    else {
19962e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got \"" + actual + "\"");
19972e5b6d6dSopenharmony_ci    }
19982e5b6d6dSopenharmony_ci#endif
19992e5b6d6dSopenharmony_ci    return true;
20002e5b6d6dSopenharmony_ci}
20012e5b6d6dSopenharmony_ci
20022e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
20032e5b6d6dSopenharmony_ci                             int32_t expected,
20042e5b6d6dSopenharmony_ci                             int32_t actual) {
20052e5b6d6dSopenharmony_ci    if (expected != actual) {
20062e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got " +
20072e5b6d6dSopenharmony_ci              actual + "=0x" + toHex(actual) +
20082e5b6d6dSopenharmony_ci              "; expected " + expected + "=0x" + toHex(expected));
20092e5b6d6dSopenharmony_ci        return false;
20102e5b6d6dSopenharmony_ci    }
20112e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
20122e5b6d6dSopenharmony_ci    else {
20132e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + actual + "=0x" + toHex(actual));
20142e5b6d6dSopenharmony_ci    }
20152e5b6d6dSopenharmony_ci#endif
20162e5b6d6dSopenharmony_ci    return true;
20172e5b6d6dSopenharmony_ci}
20182e5b6d6dSopenharmony_ci
20192e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
20202e5b6d6dSopenharmony_ci                             int64_t expected,
20212e5b6d6dSopenharmony_ci                             int64_t actual) {
20222e5b6d6dSopenharmony_ci    if (expected != actual) {
20232e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got int64 " +
20242e5b6d6dSopenharmony_ci              Int64ToUnicodeString(actual) +
20252e5b6d6dSopenharmony_ci              "; expected " + Int64ToUnicodeString(expected) );
20262e5b6d6dSopenharmony_ci        return false;
20272e5b6d6dSopenharmony_ci    }
20282e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
20292e5b6d6dSopenharmony_ci    else {
20302e5b6d6dSopenharmony_ci      logln((UnicodeString)"Ok: " + message + "; got int64 " + Int64ToUnicodeString(actual));
20312e5b6d6dSopenharmony_ci    }
20322e5b6d6dSopenharmony_ci#endif
20332e5b6d6dSopenharmony_ci    return true;
20342e5b6d6dSopenharmony_ci}
20352e5b6d6dSopenharmony_ci
20362e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
20372e5b6d6dSopenharmony_ci                             double expected,
20382e5b6d6dSopenharmony_ci                             double actual) {
20392e5b6d6dSopenharmony_ci    bool bothNaN = std::isnan(expected) && std::isnan(actual);
20402e5b6d6dSopenharmony_ci    if (expected != actual && !bothNaN) {
20412e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got " +
20422e5b6d6dSopenharmony_ci              actual +
20432e5b6d6dSopenharmony_ci              "; expected " + expected);
20442e5b6d6dSopenharmony_ci        return false;
20452e5b6d6dSopenharmony_ci    }
20462e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
20472e5b6d6dSopenharmony_ci    else {
20482e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + actual);
20492e5b6d6dSopenharmony_ci    }
20502e5b6d6dSopenharmony_ci#endif
20512e5b6d6dSopenharmony_ci    return true;
20522e5b6d6dSopenharmony_ci}
20532e5b6d6dSopenharmony_ci
20542e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
20552e5b6d6dSopenharmony_ci                             UBool expected,
20562e5b6d6dSopenharmony_ci                             UBool actual) {
20572e5b6d6dSopenharmony_ci    if (expected != actual) {
20582e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got " +
20592e5b6d6dSopenharmony_ci              toString(actual) +
20602e5b6d6dSopenharmony_ci              "; expected " + toString(expected));
20612e5b6d6dSopenharmony_ci        return false;
20622e5b6d6dSopenharmony_ci    }
20632e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
20642e5b6d6dSopenharmony_ci    else {
20652e5b6d6dSopenharmony_ci      logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
20662e5b6d6dSopenharmony_ci    }
20672e5b6d6dSopenharmony_ci#endif
20682e5b6d6dSopenharmony_ci    return true;
20692e5b6d6dSopenharmony_ci}
20702e5b6d6dSopenharmony_ci
20712e5b6d6dSopenharmony_ci
20722e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
20732e5b6d6dSopenharmony_ci                             UErrorCode expected,
20742e5b6d6dSopenharmony_ci                             UErrorCode actual) {
20752e5b6d6dSopenharmony_ci    if (expected != actual) {
20762e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got " +
20772e5b6d6dSopenharmony_ci              u_errorName(actual) +
20782e5b6d6dSopenharmony_ci              "; expected " + u_errorName(expected));
20792e5b6d6dSopenharmony_ci        return false;
20802e5b6d6dSopenharmony_ci    }
20812e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
20822e5b6d6dSopenharmony_ci    else {
20832e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + u_errorName(actual));
20842e5b6d6dSopenharmony_ci    }
20852e5b6d6dSopenharmony_ci#endif
20862e5b6d6dSopenharmony_ci    return true;
20872e5b6d6dSopenharmony_ci}
20882e5b6d6dSopenharmony_ci
20892e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
20902e5b6d6dSopenharmony_ci                             const UnicodeSet& expected,
20912e5b6d6dSopenharmony_ci                             const UnicodeSet& actual) {
20922e5b6d6dSopenharmony_ci    IcuTestErrorCode status(*this, "assertEqualsUniSet");
20932e5b6d6dSopenharmony_ci    if (expected != actual) {
20942e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message + "; got " +
20952e5b6d6dSopenharmony_ci              toString(actual, status) +
20962e5b6d6dSopenharmony_ci              "; expected " + toString(expected, status));
20972e5b6d6dSopenharmony_ci        return false;
20982e5b6d6dSopenharmony_ci    }
20992e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
21002e5b6d6dSopenharmony_ci    else {
21012e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + toString(actual, status));
21022e5b6d6dSopenharmony_ci    }
21032e5b6d6dSopenharmony_ci#endif
21042e5b6d6dSopenharmony_ci    return true;
21052e5b6d6dSopenharmony_ci}
21062e5b6d6dSopenharmony_ci
21072e5b6d6dSopenharmony_ci
21082e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
21092e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
21102e5b6d6dSopenharmony_ci                             const Formattable& expected,
21112e5b6d6dSopenharmony_ci                             const Formattable& actual,
21122e5b6d6dSopenharmony_ci                             UBool possibleDataError) {
21132e5b6d6dSopenharmony_ci    if (expected != actual) {
21142e5b6d6dSopenharmony_ci        if (possibleDataError) {
21152e5b6d6dSopenharmony_ci            dataerrln((UnicodeString)"FAIL: " + message + "; got " +
21162e5b6d6dSopenharmony_ci                  toString(actual) +
21172e5b6d6dSopenharmony_ci                  "; expected " + toString(expected));
21182e5b6d6dSopenharmony_ci        } else {
21192e5b6d6dSopenharmony_ci            errln((UnicodeString)"FAIL: " + message + "; got " +
21202e5b6d6dSopenharmony_ci                  toString(actual) +
21212e5b6d6dSopenharmony_ci                  "; expected " + toString(expected));
21222e5b6d6dSopenharmony_ci        }
21232e5b6d6dSopenharmony_ci        return false;
21242e5b6d6dSopenharmony_ci    }
21252e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
21262e5b6d6dSopenharmony_ci    else {
21272e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
21282e5b6d6dSopenharmony_ci    }
21292e5b6d6dSopenharmony_ci#endif
21302e5b6d6dSopenharmony_ci    return true;
21312e5b6d6dSopenharmony_ci}
21322e5b6d6dSopenharmony_ci#endif
21332e5b6d6dSopenharmony_ci
21342e5b6d6dSopenharmony_cistd::string vectorToString(const std::vector<std::string>& strings) {
21352e5b6d6dSopenharmony_ci    std::string result = "{";
21362e5b6d6dSopenharmony_ci    bool first = true;
21372e5b6d6dSopenharmony_ci    for (auto element : strings) {
21382e5b6d6dSopenharmony_ci        if (first) {
21392e5b6d6dSopenharmony_ci            first = false;
21402e5b6d6dSopenharmony_ci        } else {
21412e5b6d6dSopenharmony_ci            result += ", ";
21422e5b6d6dSopenharmony_ci        }
21432e5b6d6dSopenharmony_ci        result += "\"";
21442e5b6d6dSopenharmony_ci        result += element;
21452e5b6d6dSopenharmony_ci        result += "\"";
21462e5b6d6dSopenharmony_ci    }
21472e5b6d6dSopenharmony_ci    result += "}";
21482e5b6d6dSopenharmony_ci    return result;
21492e5b6d6dSopenharmony_ci}
21502e5b6d6dSopenharmony_ci
21512e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const char* message,
21522e5b6d6dSopenharmony_ci                             const std::vector<std::string>& expected,
21532e5b6d6dSopenharmony_ci                             const std::vector<std::string>& actual) {
21542e5b6d6dSopenharmony_ci    if (expected != actual) {
21552e5b6d6dSopenharmony_ci        std::string expectedAsString = vectorToString(expected);
21562e5b6d6dSopenharmony_ci        std::string actualAsString = vectorToString(actual);
21572e5b6d6dSopenharmony_ci        errln((UnicodeString)"FAIL: " + message +
21582e5b6d6dSopenharmony_ci            "; got " + actualAsString.c_str() +
21592e5b6d6dSopenharmony_ci            "; expected " + expectedAsString.c_str());
21602e5b6d6dSopenharmony_ci        return false;
21612e5b6d6dSopenharmony_ci    }
21622e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
21632e5b6d6dSopenharmony_ci    else {
21642e5b6d6dSopenharmony_ci        logln((UnicodeString)"Ok: " + message + "; got " + vectorToString(actual).c_str());
21652e5b6d6dSopenharmony_ci    }
21662e5b6d6dSopenharmony_ci#endif
21672e5b6d6dSopenharmony_ci    return true;
21682e5b6d6dSopenharmony_ci}
21692e5b6d6dSopenharmony_ci
21702e5b6d6dSopenharmony_ciUBool IntlTest::assertNotEquals(const char* message,
21712e5b6d6dSopenharmony_ci                                int32_t expectedNot,
21722e5b6d6dSopenharmony_ci                                int32_t actual) {
21732e5b6d6dSopenharmony_ci    if (expectedNot == actual) {
21742e5b6d6dSopenharmony_ci        errln((UnicodeString)("FAIL: ") + message + "; got " + actual + "=0x" + toHex(actual) +
21752e5b6d6dSopenharmony_ci              "; expected != " + expectedNot);
21762e5b6d6dSopenharmony_ci        return false;
21772e5b6d6dSopenharmony_ci    }
21782e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
21792e5b6d6dSopenharmony_ci    else {
21802e5b6d6dSopenharmony_ci        logln((UnicodeString)("Ok: ") + message + "; got " + actual + "=0x" + toHex(actual) +
21812e5b6d6dSopenharmony_ci              " != " + expectedNot);
21822e5b6d6dSopenharmony_ci    }
21832e5b6d6dSopenharmony_ci#endif
21842e5b6d6dSopenharmony_ci    return true;
21852e5b6d6dSopenharmony_ci}
21862e5b6d6dSopenharmony_ci
21872e5b6d6dSopenharmony_ciUBool IntlTest::assertEqualsNear(const char* message,
21882e5b6d6dSopenharmony_ci                                 double expected,
21892e5b6d6dSopenharmony_ci                                 double actual,
21902e5b6d6dSopenharmony_ci                                 double delta) {
21912e5b6d6dSopenharmony_ci    bool bothNaN = std::isnan(expected) && std::isnan(actual);
21922e5b6d6dSopenharmony_ci    bool bothPosInf = uprv_isPositiveInfinity(expected) && uprv_isPositiveInfinity(actual);
21932e5b6d6dSopenharmony_ci    bool bothNegInf = uprv_isNegativeInfinity(expected) && uprv_isNegativeInfinity(actual);
21942e5b6d6dSopenharmony_ci    if (bothPosInf || bothNegInf || bothNaN) {
21952e5b6d6dSopenharmony_ci        // We don't care about delta in these cases
21962e5b6d6dSopenharmony_ci        return true;
21972e5b6d6dSopenharmony_ci    }
21982e5b6d6dSopenharmony_ci    if (std::isnan(delta) || std::isinf(delta)) {
21992e5b6d6dSopenharmony_ci        errln((UnicodeString)("FAIL: ") + message + "; nonsensical delta " + delta +
22002e5b6d6dSopenharmony_ci              " - delta may not be NaN or Inf. (Got " + actual + "; expected " + expected + ".)");
22012e5b6d6dSopenharmony_ci        return false;
22022e5b6d6dSopenharmony_ci    }
22032e5b6d6dSopenharmony_ci    double difference = std::abs(expected - actual);
22042e5b6d6dSopenharmony_ci    if (expected != actual && (difference > delta || std::isnan(difference))) {
22052e5b6d6dSopenharmony_ci        errln((UnicodeString)("FAIL: ") + message + "; got " + actual + "; expected " + expected +
22062e5b6d6dSopenharmony_ci              "; acceptable delta " + delta);
22072e5b6d6dSopenharmony_ci        return false;
22082e5b6d6dSopenharmony_ci    }
22092e5b6d6dSopenharmony_ci#ifdef VERBOSE_ASSERTIONS
22102e5b6d6dSopenharmony_ci    else {
22112e5b6d6dSopenharmony_ci        logln((UnicodeString)("Ok: ") + message + "; got " + actual);
22122e5b6d6dSopenharmony_ci    }
22132e5b6d6dSopenharmony_ci#endif
22142e5b6d6dSopenharmony_ci    return true;
22152e5b6d6dSopenharmony_ci}
22162e5b6d6dSopenharmony_ci
22172e5b6d6dSopenharmony_cistatic char ASSERT_BUF[256];
22182e5b6d6dSopenharmony_ci
22192e5b6d6dSopenharmony_cistatic const char* extractToAssertBuf(const UnicodeString& message) {
22202e5b6d6dSopenharmony_ci    UnicodeString buf;
22212e5b6d6dSopenharmony_ci    escape(message, buf);
22222e5b6d6dSopenharmony_ci    buf.extract(0, 0x7FFFFFFF, ASSERT_BUF, sizeof(ASSERT_BUF)-1, 0);
22232e5b6d6dSopenharmony_ci    ASSERT_BUF[sizeof(ASSERT_BUF)-1] = 0;
22242e5b6d6dSopenharmony_ci    return ASSERT_BUF;
22252e5b6d6dSopenharmony_ci}
22262e5b6d6dSopenharmony_ci
22272e5b6d6dSopenharmony_ciUBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
22282e5b6d6dSopenharmony_ci    return assertTrue(extractToAssertBuf(message), condition, quiet, possibleDataError);
22292e5b6d6dSopenharmony_ci}
22302e5b6d6dSopenharmony_ci
22312e5b6d6dSopenharmony_ciUBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
22322e5b6d6dSopenharmony_ci    return assertFalse(extractToAssertBuf(message), condition, quiet, possibleDataError);
22332e5b6d6dSopenharmony_ci}
22342e5b6d6dSopenharmony_ci
22352e5b6d6dSopenharmony_ciUBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) {
22362e5b6d6dSopenharmony_ci    return assertSuccess(extractToAssertBuf(message), ec);
22372e5b6d6dSopenharmony_ci}
22382e5b6d6dSopenharmony_ci
22392e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22402e5b6d6dSopenharmony_ci                             const UnicodeString& expected,
22412e5b6d6dSopenharmony_ci                             const UnicodeString& actual,
22422e5b6d6dSopenharmony_ci                             UBool possibleDataError) {
22432e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual, possibleDataError);
22442e5b6d6dSopenharmony_ci}
22452e5b6d6dSopenharmony_ci
22462e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22472e5b6d6dSopenharmony_ci                             const char* expected,
22482e5b6d6dSopenharmony_ci                             const char* actual) {
22492e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22502e5b6d6dSopenharmony_ci}
22512e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22522e5b6d6dSopenharmony_ci                             UBool expected,
22532e5b6d6dSopenharmony_ci                             UBool actual) {
22542e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22552e5b6d6dSopenharmony_ci}
22562e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22572e5b6d6dSopenharmony_ci                             int32_t expected,
22582e5b6d6dSopenharmony_ci                             int32_t actual) {
22592e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22602e5b6d6dSopenharmony_ci}
22612e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22622e5b6d6dSopenharmony_ci                             int64_t expected,
22632e5b6d6dSopenharmony_ci                             int64_t actual) {
22642e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22652e5b6d6dSopenharmony_ci}
22662e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22672e5b6d6dSopenharmony_ci                             double expected,
22682e5b6d6dSopenharmony_ci                             double actual) {
22692e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22702e5b6d6dSopenharmony_ci}
22712e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22722e5b6d6dSopenharmony_ci                             UErrorCode expected,
22732e5b6d6dSopenharmony_ci                             UErrorCode actual) {
22742e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22752e5b6d6dSopenharmony_ci}
22762e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22772e5b6d6dSopenharmony_ci                             const UnicodeSet& expected,
22782e5b6d6dSopenharmony_ci                             const UnicodeSet& actual) {
22792e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22802e5b6d6dSopenharmony_ci}
22812e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
22822e5b6d6dSopenharmony_ci                             const std::vector<std::string>& expected,
22832e5b6d6dSopenharmony_ci                             const std::vector<std::string>& actual) {
22842e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
22852e5b6d6dSopenharmony_ci}
22862e5b6d6dSopenharmony_ciUBool IntlTest::assertNotEquals(const UnicodeString &message,
22872e5b6d6dSopenharmony_ci                                int32_t expectedNot,
22882e5b6d6dSopenharmony_ci                                int32_t actual) {
22892e5b6d6dSopenharmony_ci    return assertNotEquals(extractToAssertBuf(message), expectedNot, actual);
22902e5b6d6dSopenharmony_ci}
22912e5b6d6dSopenharmony_ciUBool IntlTest::assertEqualsNear(const UnicodeString& message,
22922e5b6d6dSopenharmony_ci                                 double expected,
22932e5b6d6dSopenharmony_ci                                 double actual,
22942e5b6d6dSopenharmony_ci                                 double delta) {
22952e5b6d6dSopenharmony_ci    return assertEqualsNear(extractToAssertBuf(message), expected, actual, delta);
22962e5b6d6dSopenharmony_ci}
22972e5b6d6dSopenharmony_ci
22982e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
22992e5b6d6dSopenharmony_ciUBool IntlTest::assertEquals(const UnicodeString& message,
23002e5b6d6dSopenharmony_ci                             const Formattable& expected,
23012e5b6d6dSopenharmony_ci                             const Formattable& actual) {
23022e5b6d6dSopenharmony_ci    return assertEquals(extractToAssertBuf(message), expected, actual);
23032e5b6d6dSopenharmony_ci}
23042e5b6d6dSopenharmony_ci#endif
23052e5b6d6dSopenharmony_ci
23062e5b6d6dSopenharmony_civoid IntlTest::setProperty(const char* propline) {
23072e5b6d6dSopenharmony_ci    if (numProps < kMaxProps) {
23082e5b6d6dSopenharmony_ci        proplines[numProps] = propline;
23092e5b6d6dSopenharmony_ci    }
23102e5b6d6dSopenharmony_ci    numProps++;
23112e5b6d6dSopenharmony_ci}
23122e5b6d6dSopenharmony_ci
23132e5b6d6dSopenharmony_ciconst char* IntlTest::getProperty(const char* prop) {
23142e5b6d6dSopenharmony_ci    const char* val = NULL;
23152e5b6d6dSopenharmony_ci    for (int32_t i = 0; i < numProps; i++) {
23162e5b6d6dSopenharmony_ci        int32_t plen = static_cast<int32_t>(uprv_strlen(prop));
23172e5b6d6dSopenharmony_ci        if ((int32_t)uprv_strlen(proplines[i]) > plen + 1
23182e5b6d6dSopenharmony_ci                && proplines[i][plen] == '='
23192e5b6d6dSopenharmony_ci                && uprv_strncmp(proplines[i], prop, plen) == 0) {
23202e5b6d6dSopenharmony_ci            val = &(proplines[i][plen+1]);
23212e5b6d6dSopenharmony_ci            break;
23222e5b6d6dSopenharmony_ci        }
23232e5b6d6dSopenharmony_ci    }
23242e5b6d6dSopenharmony_ci    return val;
23252e5b6d6dSopenharmony_ci}
23262e5b6d6dSopenharmony_ci
23272e5b6d6dSopenharmony_ci//-------------------------------------------------------------------------------
23282e5b6d6dSopenharmony_ci//
23292e5b6d6dSopenharmony_ci//    ReadAndConvertFile   Read a text data file, convert it to UChars, and
23302e5b6d6dSopenharmony_ci//    return the data in one big UChar * buffer, which the caller must delete.
23312e5b6d6dSopenharmony_ci//
23322e5b6d6dSopenharmony_ci//    parameters:
23332e5b6d6dSopenharmony_ci//          fileName:   the name of the file, with no directory part.  The test data directory
23342e5b6d6dSopenharmony_ci//                      is assumed.
23352e5b6d6dSopenharmony_ci//          ulen        an out parameter, receives the actual length (in UChars) of the file data.
23362e5b6d6dSopenharmony_ci//          encoding    The file encoding.  If the file contains a BOM, that will override the encoding
23372e5b6d6dSopenharmony_ci//                      specified here.  The BOM, if it exists, will be stripped from the returned data.
23382e5b6d6dSopenharmony_ci//                      Pass NULL for the system default encoding.
23392e5b6d6dSopenharmony_ci//          status
23402e5b6d6dSopenharmony_ci//    returns:
23412e5b6d6dSopenharmony_ci//                      The file data, converted to UChar.
23422e5b6d6dSopenharmony_ci//                      The caller must delete this when done with
23432e5b6d6dSopenharmony_ci//                           delete [] theBuffer;
23442e5b6d6dSopenharmony_ci//
23452e5b6d6dSopenharmony_ci//
23462e5b6d6dSopenharmony_ci//--------------------------------------------------------------------------------
23472e5b6d6dSopenharmony_ciUChar *IntlTest::ReadAndConvertFile(const char *fileName, int &ulen, const char *encoding, UErrorCode &status) {
23482e5b6d6dSopenharmony_ci    UChar       *retPtr  = NULL;
23492e5b6d6dSopenharmony_ci    char        *fileBuf = NULL;
23502e5b6d6dSopenharmony_ci    UConverter* conv     = NULL;
23512e5b6d6dSopenharmony_ci    FILE        *f       = NULL;
23522e5b6d6dSopenharmony_ci
23532e5b6d6dSopenharmony_ci    ulen = 0;
23542e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
23552e5b6d6dSopenharmony_ci        return retPtr;
23562e5b6d6dSopenharmony_ci    }
23572e5b6d6dSopenharmony_ci
23582e5b6d6dSopenharmony_ci    //
23592e5b6d6dSopenharmony_ci    //  Open the file.
23602e5b6d6dSopenharmony_ci    //
23612e5b6d6dSopenharmony_ci    f = fopen(fileName, "rb");
23622e5b6d6dSopenharmony_ci    if (f == 0) {
23632e5b6d6dSopenharmony_ci        dataerrln("Error opening test data file %s\n", fileName);
23642e5b6d6dSopenharmony_ci        status = U_FILE_ACCESS_ERROR;
23652e5b6d6dSopenharmony_ci        return NULL;
23662e5b6d6dSopenharmony_ci    }
23672e5b6d6dSopenharmony_ci    //
23682e5b6d6dSopenharmony_ci    //  Read it in
23692e5b6d6dSopenharmony_ci    //
23702e5b6d6dSopenharmony_ci    int   fileSize;
23712e5b6d6dSopenharmony_ci    int   amt_read;
23722e5b6d6dSopenharmony_ci
23732e5b6d6dSopenharmony_ci    fseek( f, 0, SEEK_END);
23742e5b6d6dSopenharmony_ci    fileSize = ftell(f);
23752e5b6d6dSopenharmony_ci    fileBuf = new char[fileSize];
23762e5b6d6dSopenharmony_ci    fseek(f, 0, SEEK_SET);
23772e5b6d6dSopenharmony_ci    amt_read = static_cast<int>(fread(fileBuf, 1, fileSize, f));
23782e5b6d6dSopenharmony_ci    if (amt_read != fileSize || fileSize <= 0) {
23792e5b6d6dSopenharmony_ci        errln("Error reading test data file.");
23802e5b6d6dSopenharmony_ci        goto cleanUpAndReturn;
23812e5b6d6dSopenharmony_ci    }
23822e5b6d6dSopenharmony_ci
23832e5b6d6dSopenharmony_ci    //
23842e5b6d6dSopenharmony_ci    // Look for a Unicode Signature (BOM) on the data just read
23852e5b6d6dSopenharmony_ci    //
23862e5b6d6dSopenharmony_ci    int32_t        signatureLength;
23872e5b6d6dSopenharmony_ci    const char *   fileBufC;
23882e5b6d6dSopenharmony_ci    const char*    bomEncoding;
23892e5b6d6dSopenharmony_ci
23902e5b6d6dSopenharmony_ci    fileBufC = fileBuf;
23912e5b6d6dSopenharmony_ci    bomEncoding = ucnv_detectUnicodeSignature(
23922e5b6d6dSopenharmony_ci        fileBuf, fileSize, &signatureLength, &status);
23932e5b6d6dSopenharmony_ci    if(bomEncoding!=NULL ){
23942e5b6d6dSopenharmony_ci        fileBufC  += signatureLength;
23952e5b6d6dSopenharmony_ci        fileSize  -= signatureLength;
23962e5b6d6dSopenharmony_ci        encoding = bomEncoding;
23972e5b6d6dSopenharmony_ci    }
23982e5b6d6dSopenharmony_ci
23992e5b6d6dSopenharmony_ci    //
24002e5b6d6dSopenharmony_ci    // Open a converter to take the rule file to UTF-16
24012e5b6d6dSopenharmony_ci    //
24022e5b6d6dSopenharmony_ci    conv = ucnv_open(encoding, &status);
24032e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
24042e5b6d6dSopenharmony_ci        goto cleanUpAndReturn;
24052e5b6d6dSopenharmony_ci    }
24062e5b6d6dSopenharmony_ci
24072e5b6d6dSopenharmony_ci    //
24082e5b6d6dSopenharmony_ci    // Convert the rules to UChar.
24092e5b6d6dSopenharmony_ci    //  Preflight first to determine required buffer size.
24102e5b6d6dSopenharmony_ci    //
24112e5b6d6dSopenharmony_ci    ulen = ucnv_toUChars(conv,
24122e5b6d6dSopenharmony_ci        NULL,           //  dest,
24132e5b6d6dSopenharmony_ci        0,              //  destCapacity,
24142e5b6d6dSopenharmony_ci        fileBufC,
24152e5b6d6dSopenharmony_ci        fileSize,
24162e5b6d6dSopenharmony_ci        &status);
24172e5b6d6dSopenharmony_ci    if (status == U_BUFFER_OVERFLOW_ERROR) {
24182e5b6d6dSopenharmony_ci        // Buffer Overflow is expected from the preflight operation.
24192e5b6d6dSopenharmony_ci        status = U_ZERO_ERROR;
24202e5b6d6dSopenharmony_ci
24212e5b6d6dSopenharmony_ci        retPtr = new UChar[ulen+1];
24222e5b6d6dSopenharmony_ci        ucnv_toUChars(conv,
24232e5b6d6dSopenharmony_ci            retPtr,       //  dest,
24242e5b6d6dSopenharmony_ci            ulen+1,
24252e5b6d6dSopenharmony_ci            fileBufC,
24262e5b6d6dSopenharmony_ci            fileSize,
24272e5b6d6dSopenharmony_ci            &status);
24282e5b6d6dSopenharmony_ci    }
24292e5b6d6dSopenharmony_ci
24302e5b6d6dSopenharmony_cicleanUpAndReturn:
24312e5b6d6dSopenharmony_ci    fclose(f);
24322e5b6d6dSopenharmony_ci    delete []fileBuf;
24332e5b6d6dSopenharmony_ci    ucnv_close(conv);
24342e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
24352e5b6d6dSopenharmony_ci        errln("ucnv_toUChars: ICU Error \"%s\"\n", u_errorName(status));
24362e5b6d6dSopenharmony_ci        delete []retPtr;
24372e5b6d6dSopenharmony_ci        retPtr = 0;
24382e5b6d6dSopenharmony_ci        ulen   = 0;
24392e5b6d6dSopenharmony_ci    }
24402e5b6d6dSopenharmony_ci    return retPtr;
24412e5b6d6dSopenharmony_ci}
24422e5b6d6dSopenharmony_ci
24432e5b6d6dSopenharmony_ci#if !UCONFIG_NO_BREAK_ITERATION
24442e5b6d6dSopenharmony_ciUBool LSTMDataIsBuilt() {
24452e5b6d6dSopenharmony_ci  // If we can find the LSTM data, the RBBI will use the LSTM engine.
24462e5b6d6dSopenharmony_ci  // So we skip the test which depending on the dictionary data.
24472e5b6d6dSopenharmony_ci  UErrorCode status = U_ZERO_ERROR;
24482e5b6d6dSopenharmony_ci  DeleteLSTMData(CreateLSTMDataForScript(USCRIPT_THAI, status));
24492e5b6d6dSopenharmony_ci  UBool thaiDataIsBuilt = U_SUCCESS(status);
24502e5b6d6dSopenharmony_ci  status = U_ZERO_ERROR;
24512e5b6d6dSopenharmony_ci  DeleteLSTMData(CreateLSTMDataForScript(USCRIPT_MYANMAR, status));
24522e5b6d6dSopenharmony_ci  UBool burmeseDataIsBuilt = U_SUCCESS(status);
24532e5b6d6dSopenharmony_ci  return thaiDataIsBuilt | burmeseDataIsBuilt;
24542e5b6d6dSopenharmony_ci}
24552e5b6d6dSopenharmony_ci
24562e5b6d6dSopenharmony_ciUBool IntlTest::skipLSTMTest() {
24572e5b6d6dSopenharmony_ci   return ! LSTMDataIsBuilt();
24582e5b6d6dSopenharmony_ci}
24592e5b6d6dSopenharmony_ciUBool IntlTest::skipDictionaryTest() {
24602e5b6d6dSopenharmony_ci   return LSTMDataIsBuilt();
24612e5b6d6dSopenharmony_ci}
24622e5b6d6dSopenharmony_ci#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
24632e5b6d6dSopenharmony_ci
24642e5b6d6dSopenharmony_ci/*
24652e5b6d6dSopenharmony_ci * Hey, Emacs, please set the following:
24662e5b6d6dSopenharmony_ci *
24672e5b6d6dSopenharmony_ci * Local Variables:
24682e5b6d6dSopenharmony_ci * indent-tabs-mode: nil
24692e5b6d6dSopenharmony_ci * End:
24702e5b6d6dSopenharmony_ci *
24712e5b6d6dSopenharmony_ci */
2472