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