Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2014, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 
      7 
      8 #include "unicode/utypes.h"
      9 
     10 /**
     11  * IntlTest is a base class for tests.
     12  */
     13 
     14 #include <stdio.h>
     15 #include <string.h>
     16 #include <assert.h>
     17 #include <stdarg.h>
     18 #include <stdlib.h>
     19 
     20 #include "unicode/unistr.h"
     21 #include "unicode/ures.h"
     22 #include "unicode/smpdtfmt.h"
     23 #include "unicode/ucnv.h"
     24 #include "unicode/uclean.h"
     25 #include "unicode/timezone.h"
     26 #include "unicode/curramt.h"
     27 #include "unicode/putil.h"
     28 
     29 #include "intltest.h"
     30 #include "caltztst.h"
     31 #include "itmajor.h"
     32 #include "cstring.h"
     33 #include "umutex.h"
     34 #include "uassert.h"
     35 #include "cmemory.h"
     36 #include "uoptions.h"
     37 
     38 #include "putilimp.h" // for uprv_getRawUTCtime()
     39 #include "unicode/locid.h"
     40 #include "unicode/ctest.h" // for str_timeDelta
     41 #include "udbgutil.h"
     42 
     43 #ifdef XP_MAC_CONSOLE
     44 #include <console.h>
     45 #include "Files.h"
     46 #endif
     47 
     48 
     49 static char* _testDataPath=NULL;
     50 
     51 // Static list of errors found
     52 static UnicodeString errorList;
     53 static void *knownList = NULL; // known issues
     54 static UBool noKnownIssues = FALSE; // if TRUE, don't emit known issues
     55 
     56 //-----------------------------------------------------------------------------
     57 //convenience classes to ease porting code that uses the Java
     58 //string-concatenation operator (moved from findword test by rtg)
     59 
     60 // [LIU] Just to get things working
     61 UnicodeString
     62 UCharToUnicodeString(UChar c)
     63 { return UnicodeString(c); }
     64 
     65 // [rtg] Just to get things working
     66 UnicodeString
     67 operator+(const UnicodeString& left,
     68       long num)
     69 {
     70     char buffer[64];    // nos changed from 10 to 64
     71     char danger = 'p';  // guard against overrunning the buffer (rtg)
     72 
     73     sprintf(buffer, "%ld", num);
     74     assert(danger == 'p');
     75 
     76     return left + buffer;
     77 }
     78 
     79 UnicodeString
     80 operator+(const UnicodeString& left,
     81       unsigned long num)
     82 {
     83     char buffer[64];    // nos changed from 10 to 64
     84     char danger = 'p';  // guard against overrunning the buffer (rtg)
     85 
     86     sprintf(buffer, "%lu", num);
     87     assert(danger == 'p');
     88 
     89     return left + buffer;
     90 }
     91 
     92 UnicodeString
     93 Int64ToUnicodeString(int64_t num)
     94 {
     95     char buffer[64];    // nos changed from 10 to 64
     96     char danger = 'p';  // guard against overrunning the buffer (rtg)
     97 
     98 #if defined(_MSC_VER)
     99     sprintf(buffer, "%I64d", num);
    100 #else
    101     sprintf(buffer, "%lld", (long long)num);
    102 #endif
    103     assert(danger == 'p');
    104 
    105     return buffer;
    106 }
    107 
    108 // [LIU] Just to get things working
    109 UnicodeString
    110 operator+(const UnicodeString& left,
    111       double num)
    112 {
    113     char buffer[64];   // was 32, made it arbitrarily bigger (rtg)
    114     char danger = 'p'; // guard against overrunning the buffer (rtg)
    115 
    116     // IEEE floating point has 52 bits of mantissa, plus one assumed bit
    117     //  53*log(2)/log(10) = 15.95
    118     // so there is no need to show more than 16 digits. [alan]
    119 
    120     sprintf(buffer, "%.17g", num);
    121     assert(danger == 'p');
    122 
    123     return left + buffer;
    124 }
    125 
    126 #if 0
    127 UnicodeString
    128 operator+(const UnicodeString& left,
    129           int64_t num) {
    130   return left + Int64ToUnicodeString(num);
    131 }
    132 #endif
    133 
    134 #if !UCONFIG_NO_FORMATTING
    135 
    136 /**
    137  * Return a string display for this, without surrounding braces.
    138  */
    139 UnicodeString _toString(const Formattable& f) {
    140     UnicodeString s;
    141     switch (f.getType()) {
    142     case Formattable::kDate:
    143         {
    144             UErrorCode status = U_ZERO_ERROR;
    145             SimpleDateFormat fmt(status);
    146             if (U_SUCCESS(status)) {
    147                 FieldPosition pos;
    148                 fmt.format(f.getDate(), s, pos);
    149                 s.insert(0, "Date:");
    150             } else {
    151                 s = UnicodeString("Error creating date format]");
    152             }
    153         }
    154         break;
    155     case Formattable::kDouble:
    156         s = UnicodeString("double:") + f.getDouble();
    157         break;
    158     case Formattable::kLong:
    159         s = UnicodeString("long:") + f.getLong();
    160         break;
    161 
    162     case Formattable::kInt64:
    163         s = UnicodeString("int64:") + Int64ToUnicodeString(f.getInt64());
    164         break;
    165 
    166     case Formattable::kString:
    167         f.getString(s);
    168         s.insert(0, "String:");
    169         break;
    170     case Formattable::kArray:
    171         {
    172             int32_t i, n;
    173             const Formattable* array = f.getArray(n);
    174             s.insert(0, UnicodeString("Array:"));
    175             UnicodeString delim(", ");
    176             for (i=0; i<n; ++i) {
    177                 if (i > 0) {
    178                     s.append(delim);
    179                 }
    180                 s = s + _toString(array[i]);
    181             }
    182         }
    183         break;
    184     case Formattable::kObject: {
    185         const CurrencyAmount* c = dynamic_cast<const CurrencyAmount*>(f.getObject());
    186         if (c != NULL) {
    187             s = _toString(c->getNumber()) + " " + UnicodeString(c->getISOCurrency());
    188         } else {
    189             s = UnicodeString("Unknown UObject");
    190         }
    191         break;
    192     }
    193     default:
    194         s = UnicodeString("Unknown Formattable type=") + (int32_t)f.getType();
    195         break;
    196     }
    197     return s;
    198 }
    199 
    200 /**
    201  * Originally coded this as operator+, but that makes the expression
    202  * + char* ambiguous. - liu
    203  */
    204 UnicodeString toString(const Formattable& f) {
    205     UnicodeString s((UChar)91/*[*/);
    206     s.append(_toString(f));
    207     s.append((UChar)0x5d/*]*/);
    208     return s;
    209 }
    210 
    211 #endif
    212 
    213 // useful when operator+ won't cooperate
    214 UnicodeString toString(int32_t n) {
    215     return UnicodeString() + (long)n;
    216 }
    217 
    218 
    219 
    220 UnicodeString toString(UBool b) {
    221   return b ? UnicodeString("TRUE"):UnicodeString("FALSE");
    222 }
    223 
    224 // stephen - cleaned up 05/05/99
    225 UnicodeString operator+(const UnicodeString& left, char num)
    226 { return left + (long)num; }
    227 UnicodeString operator+(const UnicodeString& left, short num)
    228 { return left + (long)num; }
    229 UnicodeString operator+(const UnicodeString& left, int num)
    230 { return left + (long)num; }
    231 UnicodeString operator+(const UnicodeString& left, unsigned char num)
    232 { return left + (unsigned long)num; }
    233 UnicodeString operator+(const UnicodeString& left, unsigned short num)
    234 { return left + (unsigned long)num; }
    235 UnicodeString operator+(const UnicodeString& left, unsigned int num)
    236 { return left + (unsigned long)num; }
    237 UnicodeString operator+(const UnicodeString& left, float num)
    238 { return left + (double)num; }
    239 
    240 //------------------
    241 
    242 // Append a hex string to the target
    243 UnicodeString&
    244 IntlTest::appendHex(uint32_t number,
    245             int32_t digits,
    246             UnicodeString& target)
    247 {
    248     static const UChar digitString[] = {
    249         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
    250         0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
    251     }; /* "0123456789ABCDEF" */
    252 
    253     if (digits < 0) {  // auto-digits
    254         digits = 2;
    255         uint32_t max = 0xff;
    256         while (number > max) {
    257             digits += 2;
    258             max = (max << 8) | 0xff;
    259         }
    260     }
    261     switch (digits)
    262     {
    263     case 8:
    264         target += digitString[(number >> 28) & 0xF];
    265     case 7:
    266         target += digitString[(number >> 24) & 0xF];
    267     case 6:
    268         target += digitString[(number >> 20) & 0xF];
    269     case 5:
    270         target += digitString[(number >> 16) & 0xF];
    271     case 4:
    272         target += digitString[(number >> 12) & 0xF];
    273     case 3:
    274         target += digitString[(number >>  8) & 0xF];
    275     case 2:
    276         target += digitString[(number >>  4) & 0xF];
    277     case 1:
    278         target += digitString[(number >>  0) & 0xF];
    279         break;
    280     default:
    281         target += "**";
    282     }
    283     return target;
    284 }
    285 
    286 UnicodeString
    287 IntlTest::toHex(uint32_t number, int32_t digits) {
    288     UnicodeString result;
    289     appendHex(number, digits, result);
    290     return result;
    291 }
    292 
    293 static inline UBool isPrintable(UChar32 c) {
    294     return c <= 0x7E && (c >= 0x20 || c == 9 || c == 0xA || c == 0xD);
    295 }
    296 
    297 // Replace nonprintable characters with unicode escapes
    298 UnicodeString&
    299 IntlTest::prettify(const UnicodeString &source,
    300            UnicodeString &target)
    301 {
    302     int32_t i;
    303 
    304     target.remove();
    305     target += "\"";
    306 
    307     for (i = 0; i < source.length(); )
    308     {
    309         UChar32 ch = source.char32At(i);
    310         i += U16_LENGTH(ch);
    311 
    312         if (!isPrintable(ch))
    313         {
    314             if (ch <= 0xFFFF) {
    315                 target += "\\u";
    316                 appendHex(ch, 4, target);
    317             } else {
    318                 target += "\\U";
    319                 appendHex(ch, 8, target);
    320             }
    321         }
    322         else
    323         {
    324             target += ch;
    325         }
    326     }
    327 
    328     target += "\"";
    329 
    330     return target;
    331 }
    332 
    333 // Replace nonprintable characters with unicode escapes
    334 UnicodeString
    335 IntlTest::prettify(const UnicodeString &source, UBool parseBackslash)
    336 {
    337     int32_t i;
    338     UnicodeString target;
    339     target.remove();
    340     target += "\"";
    341 
    342     for (i = 0; i < source.length();)
    343     {
    344         UChar32 ch = source.char32At(i);
    345         i += U16_LENGTH(ch);
    346 
    347         if (!isPrintable(ch))
    348         {
    349             if (parseBackslash) {
    350                 // If we are preceded by an odd number of backslashes,
    351                 // then this character has already been backslash escaped.
    352                 // Delete a backslash.
    353                 int32_t backslashCount = 0;
    354                 for (int32_t j=target.length()-1; j>=0; --j) {
    355                     if (target.charAt(j) == (UChar)92) {
    356                         ++backslashCount;
    357                     } else {
    358                         break;
    359                     }
    360                 }
    361                 if ((backslashCount % 2) == 1) {
    362                     target.truncate(target.length() - 1);
    363                 }
    364             }
    365             if (ch <= 0xFFFF) {
    366                 target += "\\u";
    367                 appendHex(ch, 4, target);
    368             } else {
    369                 target += "\\U";
    370                 appendHex(ch, 8, target);
    371             }
    372         }
    373         else
    374         {
    375             target += ch;
    376         }
    377     }
    378 
    379     target += "\"";
    380 
    381     return target;
    382 }
    383 
    384 /*  IntlTest::setICU_DATA  - if the ICU_DATA environment variable is not already
    385  *                       set, try to deduce the directory in which ICU was built,
    386  *                       and set ICU_DATA to "icu/source/data" in that location.
    387  *                       The intent is to allow the tests to have a good chance
    388  *                       of running without requiring that the user manually set
    389  *                       ICU_DATA.  Common data isn't a problem, since it is
    390  *                       picked up via a static (build time) reference, but the
    391  *                       tests dynamically load some data.
    392  */
    393 void IntlTest::setICU_DATA() {
    394     const char *original_ICU_DATA = getenv("ICU_DATA");
    395 
    396     if (original_ICU_DATA != NULL && *original_ICU_DATA != 0) {
    397         /*  If the user set ICU_DATA, don't second-guess the person. */
    398         return;
    399     }
    400 
    401     // U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
    402     //              to point to the top of the build hierarchy, which may or
    403     //              may not be the same as the source directory, depending on
    404     //              the configure options used.  At any rate,
    405     //              set the data path to the built data from this directory.
    406     //              The value is complete with quotes, so it can be used
    407     //              as-is as a string constant.
    408 
    409 #if defined (U_TOPBUILDDIR)
    410     {
    411         static char env_string[] = U_TOPBUILDDIR "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
    412         u_setDataDirectory(env_string);
    413         return;
    414     }
    415 
    416 #else
    417     // Use #else so we don't get compiler warnings due to the return above.
    418 
    419     /* On Windows, the file name obtained from __FILE__ includes a full path.
    420      *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
    421      *             Change to    "wherever\icu\source\data"
    422      */
    423     {
    424         char p[sizeof(__FILE__) + 10];
    425         char *pBackSlash;
    426         int i;
    427 
    428         strcpy(p, __FILE__);
    429         /* We want to back over three '\' chars.                            */
    430         /*   Only Windows should end up here, so looking for '\' is safe.   */
    431         for (i=1; i<=3; i++) {
    432             pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
    433             if (pBackSlash != NULL) {
    434                 *pBackSlash = 0;        /* Truncate the string at the '\'   */
    435             }
    436         }
    437 
    438         if (pBackSlash != NULL) {
    439             /* We found and truncated three names from the path.
    440              *  Now append "source\data" and set the environment
    441              */
    442             strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
    443             u_setDataDirectory(p);     /*  p is "ICU_DATA=wherever\icu\source\data"    */
    444             return;
    445         }
    446         else {
    447             /* __FILE__ on MSVC7 does not contain the directory */
    448             u_setDataDirectory(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
    449             return;
    450         }
    451     }
    452 #endif
    453 
    454     /* No location for the data dir was identifiable.
    455      *   Add other fallbacks for the test data location here if the need arises
    456      */
    457 }
    458 
    459 
    460 //--------------------------------------------------------------------------------------
    461 
    462 static const int32_t indentLevel_offset = 3;
    463 static const char delim = '/';
    464 
    465 IntlTest* IntlTest::gTest = NULL;
    466 
    467 static int32_t execCount = 0;
    468 
    469 void it_log( UnicodeString message )
    470 {
    471     if (IntlTest::gTest)
    472         IntlTest::gTest->log( message );
    473 }
    474 
    475 void it_logln( UnicodeString message )
    476 {
    477     if (IntlTest::gTest)
    478         IntlTest::gTest->logln( message );
    479 }
    480 
    481 void it_logln( void )
    482 {
    483     if (IntlTest::gTest)
    484         IntlTest::gTest->logln();
    485 }
    486 
    487 void it_info( UnicodeString message )
    488 {
    489     if (IntlTest::gTest)
    490         IntlTest::gTest->info( message );
    491 }
    492 
    493 void it_infoln( UnicodeString message )
    494 {
    495     if (IntlTest::gTest)
    496         IntlTest::gTest->infoln( message );
    497 }
    498 
    499 void it_infoln( void )
    500 {
    501     if (IntlTest::gTest)
    502         IntlTest::gTest->infoln();
    503 }
    504 
    505 void it_err()
    506 {
    507     if (IntlTest::gTest)
    508         IntlTest::gTest->err();
    509 }
    510 
    511 void it_err( UnicodeString message )
    512 {
    513     if (IntlTest::gTest)
    514         IntlTest::gTest->err( message );
    515 }
    516 
    517 void it_errln( UnicodeString message )
    518 {
    519     if (IntlTest::gTest)
    520         IntlTest::gTest->errln( message );
    521 }
    522 
    523 void it_dataerr( UnicodeString message )
    524 {
    525     if (IntlTest::gTest)
    526         IntlTest::gTest->dataerr( message );
    527 }
    528 
    529 void it_dataerrln( UnicodeString message )
    530 {
    531     if (IntlTest::gTest)
    532         IntlTest::gTest->dataerrln( message );
    533 }
    534 
    535 IntlTest::IntlTest()
    536 {
    537     caller = NULL;
    538     testPath = NULL;
    539     LL_linestart = TRUE;
    540     errorCount = 0;
    541     dataErrorCount = 0;
    542     verbose = FALSE;
    543     no_time = FALSE;
    544     no_err_msg = FALSE;
    545     warn_on_missing_data = FALSE;
    546     quick = FALSE;
    547     leaks = FALSE;
    548     threadCount = 1;
    549     testoutfp = stdout;
    550     LL_indentlevel = indentLevel_offset;
    551     numProps = 0;
    552     strcpy(basePath, "/");
    553     currName[0]=0;
    554 }
    555 
    556 void IntlTest::setCaller( IntlTest* callingTest )
    557 {
    558     caller = callingTest;
    559     if (caller) {
    560         warn_on_missing_data = caller->warn_on_missing_data;
    561         verbose = caller->verbose;
    562         no_err_msg = caller->no_err_msg;
    563         quick = caller->quick;
    564         testoutfp = caller->testoutfp;
    565         LL_indentlevel = caller->LL_indentlevel + indentLevel_offset;
    566         numProps = caller->numProps;
    567         for (int32_t i = 0; i < numProps; i++) {
    568             proplines[i] = caller->proplines[i];
    569         }
    570     }
    571 }
    572 
    573 UBool IntlTest::callTest( IntlTest& testToBeCalled, char* par )
    574 {
    575     execCount--; // correct a previously assumed test-exec, as this only calls a subtest
    576     testToBeCalled.setCaller( this );
    577     strcpy(testToBeCalled.basePath, this->basePath );
    578     UBool result = testToBeCalled.runTest( testPath, par, testToBeCalled.basePath );
    579     strcpy(testToBeCalled.basePath, this->basePath ); // reset it.
    580     return result;
    581 }
    582 
    583 void IntlTest::setPath( char* pathVal )
    584 {
    585     this->testPath = pathVal;
    586 }
    587 
    588 UBool IntlTest::setVerbose( UBool verboseVal )
    589 {
    590     UBool rval = this->verbose;
    591     this->verbose = verboseVal;
    592     return rval;
    593 }
    594 
    595 UBool IntlTest::setNotime( UBool no_time )
    596 {
    597     UBool rval = this->no_time;
    598     this->no_time = no_time;
    599     return rval;
    600 }
    601 
    602 UBool IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal )
    603 {
    604     UBool rval = this->warn_on_missing_data;
    605     this->warn_on_missing_data = warn_on_missing_dataVal;
    606     return rval;
    607 }
    608 
    609 UBool IntlTest::setNoErrMsg( UBool no_err_msgVal )
    610 {
    611     UBool rval = this->no_err_msg;
    612     this->no_err_msg = no_err_msgVal;
    613     return rval;
    614 }
    615 
    616 UBool IntlTest::setQuick( UBool quickVal )
    617 {
    618     UBool rval = this->quick;
    619     this->quick = quickVal;
    620     return rval;
    621 }
    622 
    623 UBool IntlTest::setLeaks( UBool leaksVal )
    624 {
    625     UBool rval = this->leaks;
    626     this->leaks = leaksVal;
    627     return rval;
    628 }
    629 
    630 int32_t IntlTest::setThreadCount( int32_t count )
    631 {
    632     int32_t rval = this->threadCount;
    633     this->threadCount = count;
    634     return rval;
    635 }
    636 
    637 int32_t IntlTest::getErrors( void )
    638 {
    639     return errorCount;
    640 }
    641 
    642 int32_t IntlTest::getDataErrors( void )
    643 {
    644     return dataErrorCount;
    645 }
    646 
    647 UBool IntlTest::runTest( char* name, char* par, char *baseName )
    648 {
    649     UBool rval;
    650     char* pos = NULL;
    651 
    652     char* baseNameBuffer = NULL;
    653 
    654     if(baseName == NULL) {
    655       baseNameBuffer = (char*)malloc(1024);
    656       baseName=baseNameBuffer;
    657       strcpy(baseName, "/");
    658     }
    659 
    660     if (name)
    661         pos = strchr( name, delim ); // check if name contains path (by looking for '/')
    662     if (pos) {
    663         testPath = pos+1;   // store subpath for calling subtest
    664         *pos = 0;       // split into two strings
    665     }else{
    666         testPath = NULL;
    667     }
    668 
    669     if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
    670       rval = runTestLoop( NULL, par, baseName );
    671 
    672     }else if (strcmp( name, "LIST" ) == 0) {
    673         this->usage();
    674         rval = TRUE;
    675 
    676     }else{
    677       rval = runTestLoop( name, par, baseName );
    678     }
    679 
    680     if (pos)
    681         *pos = delim;  // restore original value at pos
    682     if(baseNameBuffer!=NULL) {
    683       free(baseNameBuffer);
    684     }
    685     return rval;
    686 }
    687 
    688 // call individual tests, to be overriden to call implementations
    689 void IntlTest::runIndexedTest( int32_t /*index*/, UBool /*exec*/, const char* & /*name*/, char* /*par*/ )
    690 {
    691     // to be overriden by a method like:
    692     /*
    693     switch (index) {
    694         case 0: name = "First Test"; if (exec) FirstTest( par ); break;
    695         case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
    696         default: name = ""; break;
    697     }
    698     */
    699     this->errln("*** runIndexedTest needs to be overriden! ***");
    700 }
    701 
    702 
    703 UBool IntlTest::runTestLoop( char* testname, char* par, char *baseName )
    704 {
    705     int32_t    index = 0;
    706     const char*   name;
    707     UBool  run_this_test;
    708     int32_t    lastErrorCount;
    709     UBool  rval = FALSE;
    710     UBool   lastTestFailed;
    711 
    712     if(baseName == NULL) {
    713       printf("ERROR: baseName can't be null.\n");
    714       return FALSE;
    715     } else {
    716       if ((char *)this->basePath != baseName) {
    717         strcpy(this->basePath, baseName);
    718       }
    719     }
    720 
    721     char * saveBaseLoc = baseName+strlen(baseName);
    722 
    723     IntlTest* saveTest = gTest;
    724     gTest = this;
    725     do {
    726         this->runIndexedTest( index, FALSE, name, par );
    727         if (strcmp(name,"skip") == 0) {
    728             run_this_test = FALSE;
    729         } else {
    730             if (!name || (name[0] == 0))
    731                 break;
    732             if (!testname) {
    733                 run_this_test = TRUE;
    734             }else{
    735                 run_this_test = (UBool) (strcmp( name, testname ) == 0);
    736             }
    737         }
    738         if (run_this_test) {
    739             lastErrorCount = errorCount;
    740             execCount++;
    741             char msg[256];
    742             sprintf(msg, "%s {", name);
    743             LL_message(msg, TRUE);
    744             UDate timeStart = uprv_getRawUTCtime();
    745             strcpy(saveBaseLoc,name);
    746             strcat(saveBaseLoc,"/");
    747 
    748             strcpy(currName, name); // set
    749             this->runIndexedTest( index, TRUE, name, par );
    750             currName[0]=0; // reset
    751 
    752             UDate timeStop = uprv_getRawUTCtime();
    753             rval = TRUE; // at least one test has been called
    754             char secs[256];
    755             if(!no_time) {
    756               sprintf(secs, "%f", (timeStop-timeStart)/1000.0);
    757             } else {
    758               secs[0]=0;
    759             }
    760 
    761 
    762             strcpy(saveBaseLoc,name);
    763 
    764 
    765             ctest_xml_testcase(baseName, name, secs, (lastErrorCount!=errorCount)?"err":NULL);
    766 
    767 
    768             saveBaseLoc[0]=0; /* reset path */
    769 
    770             if (lastErrorCount == errorCount) {
    771                 sprintf( msg, "   } OK:   %s ", name );
    772                 if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
    773                 lastTestFailed = FALSE;
    774             }else{
    775                 sprintf(msg,  "   } ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name);
    776                 if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
    777 
    778                 for(int i=0;i<LL_indentlevel;i++) {
    779                     errorList += " ";
    780                 }
    781                 errorList += name;
    782                 errorList += "\n";
    783                 lastTestFailed = TRUE;
    784             }
    785             LL_indentlevel -= 3;
    786             if (lastTestFailed) {
    787                 LL_message( "", TRUE);
    788             }
    789             LL_message( msg, TRUE);
    790             if (lastTestFailed) {
    791                 LL_message( "", TRUE);
    792             }
    793             LL_indentlevel += 3;
    794         }
    795         index++;
    796     }while(name);
    797 
    798     *saveBaseLoc = 0;
    799 
    800     gTest = saveTest;
    801     return rval;
    802 }
    803 
    804 
    805 /**
    806 * Adds given string to the log if we are in verbose mode.
    807 */
    808 void IntlTest::log( const UnicodeString &message )
    809 {
    810     if( verbose ) {
    811         LL_message( message, FALSE );
    812     }
    813 }
    814 
    815 /**
    816 * Adds given string to the log if we are in verbose mode. Adds a new line to
    817 * the given message.
    818 */
    819 void IntlTest::logln( const UnicodeString &message )
    820 {
    821     if( verbose ) {
    822         LL_message( message, TRUE );
    823     }
    824 }
    825 
    826 void IntlTest::logln( void )
    827 {
    828     if( verbose ) {
    829         LL_message( "", TRUE );
    830     }
    831 }
    832 
    833 /**
    834 * Unconditionally adds given string to the log.
    835 */
    836 void IntlTest::info( const UnicodeString &message )
    837 {
    838   LL_message( message, FALSE );
    839 }
    840 
    841 /**
    842 * Unconditionally adds given string to the log. Adds a new line to
    843 * the given message.
    844 */
    845 void IntlTest::infoln( const UnicodeString &message )
    846 {
    847   LL_message( message, TRUE );
    848 }
    849 
    850 void IntlTest::infoln( void )
    851 {
    852   LL_message( "", TRUE );
    853 }
    854 
    855 int32_t IntlTest::IncErrorCount( void )
    856 {
    857     errorCount++;
    858     if (caller) caller->IncErrorCount();
    859     return errorCount;
    860 }
    861 
    862 int32_t IntlTest::IncDataErrorCount( void )
    863 {
    864     dataErrorCount++;
    865     if (caller) caller->IncDataErrorCount();
    866     return dataErrorCount;
    867 }
    868 
    869 void IntlTest::err()
    870 {
    871     IncErrorCount();
    872 }
    873 
    874 void IntlTest::err( const UnicodeString &message )
    875 {
    876     IncErrorCount();
    877     if (!no_err_msg) LL_message( message, FALSE );
    878 }
    879 
    880 void IntlTest::errln( const UnicodeString &message )
    881 {
    882     IncErrorCount();
    883     if (!no_err_msg) LL_message( message, TRUE );
    884 }
    885 
    886 void IntlTest::dataerr( const UnicodeString &message )
    887 {
    888     IncDataErrorCount();
    889 
    890     if (!warn_on_missing_data) {
    891         IncErrorCount();
    892     }
    893 
    894     if (!no_err_msg) LL_message( message, FALSE );
    895 }
    896 
    897 void IntlTest::dataerrln( const UnicodeString &message )
    898 {
    899     int32_t errCount = IncDataErrorCount();
    900     UnicodeString msg;
    901     if (!warn_on_missing_data) {
    902         IncErrorCount();
    903         msg = message;
    904     } else {
    905         msg = UnicodeString("[DATA] " + message);
    906     }
    907 
    908     if (!no_err_msg) {
    909       if ( errCount == 1) {
    910           LL_message( msg + " - (Are you missing data?)", TRUE ); // only show this message the first time
    911       } else {
    912           LL_message( msg , TRUE );
    913       }
    914     }
    915 }
    916 
    917 void IntlTest::errcheckln(UErrorCode status, const UnicodeString &message ) {
    918     if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
    919         dataerrln(message);
    920     } else {
    921         errln(message);
    922     }
    923 }
    924 
    925 /* convenience functions that include sprintf formatting */
    926 void IntlTest::log(const char *fmt, ...)
    927 {
    928     char buffer[4000];
    929     va_list ap;
    930 
    931     va_start(ap, fmt);
    932     /* sprintf it just to make sure that the information is valid */
    933     vsprintf(buffer, fmt, ap);
    934     va_end(ap);
    935     if( verbose ) {
    936         log(UnicodeString(buffer, ""));
    937     }
    938 }
    939 
    940 void IntlTest::logln(const char *fmt, ...)
    941 {
    942     char buffer[4000];
    943     va_list ap;
    944 
    945     va_start(ap, fmt);
    946     /* sprintf it just to make sure that the information is valid */
    947     vsprintf(buffer, fmt, ap);
    948     va_end(ap);
    949     if( verbose ) {
    950         logln(UnicodeString(buffer, ""));
    951     }
    952 }
    953 
    954 UBool IntlTest::logKnownIssue(const char *ticket, const char *fmt, ...)
    955 {
    956     char buffer[4000];
    957     va_list ap;
    958 
    959     va_start(ap, fmt);
    960     /* sprintf it just to make sure that the information is valid */
    961     vsprintf(buffer, fmt, ap);
    962     va_end(ap);
    963     return logKnownIssue(ticket, UnicodeString(buffer, ""));
    964 }
    965 
    966 UBool IntlTest::logKnownIssue(const char *ticket) {
    967   return logKnownIssue(ticket, UnicodeString());
    968 }
    969 
    970 UBool IntlTest::logKnownIssue(const char *ticket, const UnicodeString &msg) {
    971   if(noKnownIssues) return FALSE;
    972 
    973   char fullpath[2048];
    974   strcpy(fullpath, basePath);
    975   strcat(fullpath, currName);
    976   UnicodeString msg2 =msg;
    977   UBool firstForTicket, firstForWhere;
    978   knownList = udbg_knownIssue_openU(knownList, ticket, fullpath, msg2.getTerminatedBuffer(), &firstForTicket, &firstForWhere);
    979 
    980   msg2 = UNICODE_STRING_SIMPLE("(Known issue #") +
    981       UnicodeString(ticket, -1, US_INV) + UNICODE_STRING_SIMPLE(") ") + msg;
    982   if(firstForTicket || firstForWhere) {
    983     infoln(msg2);
    984   } else {
    985     logln(msg2);
    986   }
    987 
    988   return TRUE;
    989 }
    990 
    991 /* convenience functions that include sprintf formatting */
    992 void IntlTest::info(const char *fmt, ...)
    993 {
    994     char buffer[4000];
    995     va_list ap;
    996 
    997     va_start(ap, fmt);
    998     /* sprintf it just to make sure that the information is valid */
    999     vsprintf(buffer, fmt, ap);
   1000     va_end(ap);
   1001     info(UnicodeString(buffer, ""));
   1002 }
   1003 
   1004 void IntlTest::infoln(const char *fmt, ...)
   1005 {
   1006     char buffer[4000];
   1007     va_list ap;
   1008 
   1009     va_start(ap, fmt);
   1010     /* sprintf it just to make sure that the information is valid */
   1011     vsprintf(buffer, fmt, ap);
   1012     va_end(ap);
   1013     infoln(UnicodeString(buffer, ""));
   1014 }
   1015 
   1016 void IntlTest::err(const char *fmt, ...)
   1017 {
   1018     char buffer[4000];
   1019     va_list ap;
   1020 
   1021     va_start(ap, fmt);
   1022     vsprintf(buffer, fmt, ap);
   1023     va_end(ap);
   1024     err(UnicodeString(buffer, ""));
   1025 }
   1026 
   1027 void IntlTest::errln(const char *fmt, ...)
   1028 {
   1029     char buffer[4000];
   1030     va_list ap;
   1031 
   1032     va_start(ap, fmt);
   1033     vsprintf(buffer, fmt, ap);
   1034     va_end(ap);
   1035     errln(UnicodeString(buffer, ""));
   1036 }
   1037 
   1038 void IntlTest::dataerrln(const char *fmt, ...)
   1039 {
   1040     char buffer[4000];
   1041     va_list ap;
   1042 
   1043     va_start(ap, fmt);
   1044     vsprintf(buffer, fmt, ap);
   1045     va_end(ap);
   1046     dataerrln(UnicodeString(buffer, ""));
   1047 }
   1048 
   1049 void IntlTest::errcheckln(UErrorCode status, const char *fmt, ...)
   1050 {
   1051     char buffer[4000];
   1052     va_list ap;
   1053 
   1054     va_start(ap, fmt);
   1055     vsprintf(buffer, fmt, ap);
   1056     va_end(ap);
   1057 
   1058     if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
   1059         dataerrln(UnicodeString(buffer, ""));
   1060     } else {
   1061         errln(UnicodeString(buffer, ""));
   1062     }
   1063 }
   1064 
   1065 void IntlTest::printErrors()
   1066 {
   1067      IntlTest::LL_message(errorList, TRUE);
   1068 }
   1069 
   1070 UBool IntlTest::printKnownIssues()
   1071 {
   1072   if(knownList != NULL) {
   1073     udbg_knownIssue_print(knownList);
   1074     udbg_knownIssue_close(knownList);
   1075     return TRUE;
   1076   } else {
   1077     return FALSE;
   1078   }
   1079 }
   1080 
   1081 void IntlTest::LL_message( UnicodeString message, UBool newline )
   1082 {
   1083     // string that starts with a LineFeed character and continues
   1084     // with spaces according to the current indentation
   1085     static const UChar indentUChars[] = {
   1086         '\n',
   1087         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1088         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1089         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1090         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1091         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1092         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1093         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1094         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1095         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
   1096         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
   1097     };
   1098     UnicodeString indent(FALSE, indentUChars, 1 + LL_indentlevel);
   1099 
   1100     char buffer[30000];
   1101     int32_t length;
   1102 
   1103     // stream out the indentation string first if necessary
   1104     length = indent.extract(1, indent.length(), buffer, sizeof(buffer));
   1105     if (length > 0) {
   1106         fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
   1107     }
   1108 
   1109     // replace each LineFeed by the indentation string
   1110     message.findAndReplace(UnicodeString((UChar)'\n'), indent);
   1111 
   1112     // stream out the message
   1113     length = message.extract(0, message.length(), buffer, sizeof(buffer));
   1114     if (length > 0) {
   1115         length = length > 30000 ? 30000 : length;
   1116         fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
   1117     }
   1118 
   1119     if (newline) {
   1120         char newLine = '\n';
   1121         fwrite(&newLine, sizeof(newLine), 1, (FILE *)testoutfp);
   1122     }
   1123 
   1124     // A newline usually flushes the buffer, but
   1125     // flush the message just in case of a core dump.
   1126     fflush((FILE *)testoutfp);
   1127 }
   1128 
   1129 /**
   1130 * Print a usage message for this test class.
   1131 */
   1132 void IntlTest::usage( void )
   1133 {
   1134     UBool save_verbose = setVerbose( TRUE );
   1135     logln("Test names:");
   1136     logln("-----------");
   1137 
   1138     int32_t index = 0;
   1139     const char* name = NULL;
   1140     do{
   1141         this->runIndexedTest( index, FALSE, name );
   1142         if (!name) break;
   1143         logln(name);
   1144         index++;
   1145     }while (name && (name[0] != 0));
   1146     setVerbose( save_verbose );
   1147 }
   1148 
   1149 
   1150 // memory leak reporting software will be able to take advantage of the testsuite
   1151 // being run a second time local to a specific method in order to report only actual leaks
   1152 UBool
   1153 IntlTest::run_phase2( char* name, char* par ) // supports reporting memory leaks
   1154 {
   1155     UnicodeString* strLeak = new UnicodeString("forced leak"); // for verifying purify filter
   1156     strLeak->append(" for verifying purify filter");
   1157     return this->runTest( name, par );
   1158 }
   1159 
   1160 
   1161 #if UCONFIG_NO_LEGACY_CONVERSION
   1162 #   define TRY_CNV_1 "iso-8859-1"
   1163 #   define TRY_CNV_2 "ibm-1208"
   1164 #else
   1165 #   define TRY_CNV_1 "iso-8859-7"
   1166 #   define TRY_CNV_2 "sjis"
   1167 #endif
   1168 
   1169 int
   1170 main(int argc, char* argv[])
   1171 {
   1172     UBool syntax = FALSE;
   1173     UBool all = FALSE;
   1174     UBool verbose = FALSE;
   1175     UBool no_err_msg = FALSE;
   1176     UBool no_time = FALSE;
   1177     UBool quick = TRUE;
   1178     UBool name = FALSE;
   1179     UBool leaks = FALSE;
   1180     UBool utf8 = FALSE;
   1181     const char *summary_file = NULL;
   1182     UBool warnOnMissingData = FALSE;
   1183     UBool defaultDataFound = FALSE;
   1184     int32_t threadCount = 1;
   1185     UErrorCode errorCode = U_ZERO_ERROR;
   1186     UConverter *cnv = NULL;
   1187     const char *warnOrErr = "Failure";
   1188     UDate startTime, endTime;
   1189     int32_t diffTime;
   1190     const char *props[IntlTest::kMaxProps];
   1191     int32_t nProps = 0;
   1192 
   1193     U_MAIN_INIT_ARGS(argc, argv);
   1194 
   1195     startTime = uprv_getRawUTCtime();
   1196 
   1197     for (int i = 1; i < argc; ++i) {
   1198         if (argv[i][0] == '-') {
   1199             const char* str = argv[i] + 1;
   1200             if (strcmp("verbose", str) == 0 ||
   1201                 strcmp("v", str) == 0)
   1202                 verbose = TRUE;
   1203             else if (strcmp("noerrormsg", str) == 0 ||
   1204                      strcmp("n", str) == 0)
   1205                 no_err_msg = TRUE;
   1206             else if (strcmp("exhaustive", str) == 0 ||
   1207                      strcmp("e", str) == 0)
   1208                 quick = FALSE;
   1209             else if (strcmp("all", str) == 0 ||
   1210                      strcmp("a", str) == 0)
   1211                 all = TRUE;
   1212             else if (strcmp("utf-8", str) == 0 ||
   1213                      strcmp("u", str) == 0)
   1214                 utf8 = TRUE;
   1215             else if (strcmp("noknownissues", str) == 0 ||
   1216                      strcmp("K", str) == 0)
   1217                 noKnownIssues = TRUE;
   1218             else if (strcmp("leaks", str) == 0 ||
   1219                      strcmp("l", str) == 0)
   1220                 leaks = TRUE;
   1221             else if (strcmp("notime", str) == 0 ||
   1222                      strcmp("T", str) == 0)
   1223                 no_time = TRUE;
   1224             else if (strncmp("E", str, 1) == 0)
   1225                 summary_file = str+1;
   1226             else if (strcmp("x", str)==0) {
   1227               if(++i>=argc) {
   1228                 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
   1229                 syntax = TRUE;
   1230               }
   1231               if(ctest_xml_setFileName(argv[i])) { /* set the name */
   1232                 return 1; /* error */
   1233               }
   1234             } else if (strcmp("w", str) == 0) {
   1235               warnOnMissingData = TRUE;
   1236               warnOrErr = "WARNING";
   1237             }
   1238             else if (strncmp("threads:", str, 8) == 0) {
   1239                 threadCount = atoi(str + 8);
   1240             }
   1241             else if (strncmp("prop:", str, 5) == 0) {
   1242                 if (nProps < IntlTest::kMaxProps) {
   1243                     props[nProps] = str + 5;
   1244                 }
   1245                 nProps++;
   1246             }
   1247             else {
   1248                 syntax = TRUE;
   1249             }
   1250         }else{
   1251             name = TRUE;
   1252         }
   1253     }
   1254 
   1255     if (!all && !name) {
   1256         all = TRUE;
   1257     } else if (all && name) {
   1258         syntax = TRUE;
   1259     }
   1260 
   1261     if (syntax) {
   1262         fprintf(stdout,
   1263                 "### Syntax:\n"
   1264                 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
   1265                 "### \n"
   1266                 "### Options are: verbose (v), all (a), noerrormsg (n), \n"
   1267                 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
   1268                 "### notime (T), \n"
   1269                 "### threads:<threadCount> (Mulithreading must first be \n"
   1270                 "###     enabled otherwise this will be ignored. \n"
   1271                 "###     The default thread count is 1.),\n"
   1272                 "### (Specify either -all (shortcut -a) or a test name). \n"
   1273                 "### -all will run all of the tests.\n"
   1274                 "### \n"
   1275                 "### To get a list of the test names type: intltest LIST \n"
   1276                 "### To run just the utility tests type: intltest utility \n"
   1277                 "### \n"
   1278                 "### Test names can be nested using slashes (\"testA/subtest1\") \n"
   1279                 "### For example to list the utility tests type: intltest utility/LIST \n"
   1280                 "### To run just the Locale test type: intltest utility/LocaleTest \n"
   1281                 "### \n"
   1282                 "### A parameter can be specified for a test by appending '@' and the value \n"
   1283                 "### to the testname. \n\n");
   1284         return 1;
   1285     }
   1286 
   1287     if (nProps > IntlTest::kMaxProps) {
   1288         fprintf(stdout, "### Too many properties.  Exiting.\n");
   1289     }
   1290 
   1291     MajorTestLevel major;
   1292     major.setVerbose( verbose );
   1293     major.setNoErrMsg( no_err_msg );
   1294     major.setQuick( quick );
   1295     major.setLeaks( leaks );
   1296     major.setThreadCount( threadCount );
   1297     major.setWarnOnMissingData( warnOnMissingData );
   1298     major.setNotime (no_time);
   1299     for (int32_t i = 0; i < nProps; i++) {
   1300         major.setProperty(props[i]);
   1301     }
   1302 
   1303 
   1304     fprintf(stdout, "-----------------------------------------------\n");
   1305     fprintf(stdout, " IntlTest (C++) Test Suite for                 \n");
   1306     fprintf(stdout, "   International Components for Unicode %s\n", U_ICU_VERSION);
   1307 
   1308 
   1309     {
   1310 	const char *charsetFamily = "Unknown";
   1311         int32_t voidSize = (int32_t)sizeof(void*);
   1312         int32_t bits = voidSize * 8;
   1313         if(U_CHARSET_FAMILY==U_ASCII_FAMILY) {
   1314            charsetFamily="ASCII";
   1315         } else if(U_CHARSET_FAMILY==U_EBCDIC_FAMILY) {
   1316            charsetFamily="EBCDIC";
   1317         }
   1318         fprintf(stdout,
   1319                     "   Bits: %d, Byte order: %s, Chars: %s\n",
   1320                      bits, U_IS_BIG_ENDIAN?"Big endian":"Little endian",
   1321                      charsetFamily);
   1322     }
   1323     fprintf(stdout, "-----------------------------------------------\n");
   1324     fprintf(stdout, " Options:                                       \n");
   1325     fprintf(stdout, "   all (a)                  : %s\n", (all?               "On" : "Off"));
   1326     fprintf(stdout, "   Verbose (v)              : %s\n", (verbose?           "On" : "Off"));
   1327     fprintf(stdout, "   No error messages (n)    : %s\n", (no_err_msg?        "On" : "Off"));
   1328     fprintf(stdout, "   Exhaustive (e)           : %s\n", (!quick?            "On" : "Off"));
   1329     fprintf(stdout, "   Leaks (l)                : %s\n", (leaks?             "On" : "Off"));
   1330     fprintf(stdout, "   utf-8 (u)                : %s\n", (utf8?              "On" : "Off"));
   1331     fprintf(stdout, "   notime (T)               : %s\n", (no_time?             "On" : "Off"));
   1332     fprintf(stdout, "   noknownissues (K)        : %s\n", (noKnownIssues?      "On" : "Off"));
   1333     fprintf(stdout, "   Warn on missing data (w) : %s\n", (warnOnMissingData? "On" : "Off"));
   1334 #if (ICU_USE_THREADS==0)
   1335     fprintf(stdout, "   Threads                  : Disabled\n");
   1336 #else
   1337     fprintf(stdout, "   Threads                  : %d\n", threadCount);
   1338 #endif
   1339     for (int32_t i = 0; i < nProps; i++) {
   1340         fprintf(stdout, "   Custom property (prop:)  : %s\n", props[i]);
   1341     }
   1342     fprintf(stdout, "-----------------------------------------------\n");
   1343 
   1344     if(utf8) {
   1345       ucnv_setDefaultName("utf-8");
   1346     }
   1347     /* Check whether ICU will initialize without forcing the build data directory into
   1348      *  the ICU_DATA path.  Success here means either the data dll contains data, or that
   1349      *  this test program was run with ICU_DATA set externally.  Failure of this check
   1350      *  is normal when ICU data is not packaged into a shared library.
   1351      *
   1352      *  Whether or not this test succeeds, we want to cleanup and reinitialize
   1353      *  with a data path so that data loading from individual files can be tested.
   1354      */
   1355     u_init(&errorCode);
   1356     if (U_FAILURE(errorCode)) {
   1357         fprintf(stderr,
   1358             "#### Note:  ICU Init without build-specific setDataDirectory() failed.\n");
   1359         defaultDataFound = FALSE;
   1360     }
   1361     else {
   1362         defaultDataFound = TRUE;
   1363     }
   1364     u_cleanup();
   1365     if(utf8) {
   1366       ucnv_setDefaultName("utf-8");
   1367     }
   1368     errorCode = U_ZERO_ERROR;
   1369 
   1370     /* Initialize ICU */
   1371     if (!defaultDataFound) {
   1372         IntlTest::setICU_DATA();   // Must set data directory before u_init() is called.
   1373     }
   1374     u_init(&errorCode);
   1375     if (U_FAILURE(errorCode)) {
   1376         fprintf(stderr,
   1377             "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
   1378             "*** Check the ICU_DATA environment variable and \n"
   1379             "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
   1380             if(warnOnMissingData == 0) {
   1381                 fprintf(stderr, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
   1382                 u_cleanup();
   1383                 return 1;
   1384             }
   1385     }
   1386 
   1387     // initial check for the default converter
   1388     errorCode = U_ZERO_ERROR;
   1389     cnv = ucnv_open(0, &errorCode);
   1390     if(cnv != 0) {
   1391         // ok
   1392         ucnv_close(cnv);
   1393     } else {
   1394         fprintf(stdout,
   1395                 "*** %s! The default converter [%s] cannot be opened.\n"
   1396                 "*** Check the ICU_DATA environment variable and\n"
   1397                 "*** check that the data files are present.\n",
   1398                 warnOrErr, ucnv_getDefaultName());
   1399         if(!warnOnMissingData) {
   1400           fprintf(stdout, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
   1401           return 1;
   1402         }
   1403     }
   1404 
   1405     // try more data
   1406     cnv = ucnv_open(TRY_CNV_2, &errorCode);
   1407     if(cnv != 0) {
   1408         // ok
   1409         ucnv_close(cnv);
   1410     } else {
   1411         fprintf(stdout,
   1412                 "*** %s! The converter for " TRY_CNV_2 " cannot be opened.\n"
   1413                 "*** Check the ICU_DATA environment variable and \n"
   1414                 "*** check that the data files are present.\n", warnOrErr);
   1415         if(!warnOnMissingData) {
   1416           fprintf(stdout, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
   1417           return 1;
   1418         }
   1419     }
   1420 
   1421     UResourceBundle *rb = ures_open(0, "en", &errorCode);
   1422     ures_close(rb);
   1423     if(U_FAILURE(errorCode)) {
   1424         fprintf(stdout,
   1425                 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
   1426                 "*** Check the ICU_DATA environment variable and \n"
   1427                 "*** check that the data files are present.\n", warnOrErr);
   1428         if(!warnOnMissingData) {
   1429           fprintf(stdout, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
   1430           return 1;
   1431         }
   1432     }
   1433 
   1434     Locale originalLocale;  // Save the default locale for comparison later on.
   1435 
   1436     if(ctest_xml_init("intltest"))
   1437       return 1;
   1438 
   1439 
   1440     /* TODO: Add option to call u_cleanup and rerun tests. */
   1441     if (all) {
   1442         major.runTest();
   1443         if (leaks) {
   1444             major.run_phase2( NULL, NULL );
   1445         }
   1446     }else{
   1447         for (int i = 1; i < argc; ++i) {
   1448             if (argv[i][0] != '-') {
   1449                 char* name = argv[i];
   1450                 fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
   1451 
   1452                 char baseName[1024];
   1453                 sprintf(baseName, "/%s/", name);
   1454 
   1455                 char* parameter = strchr( name, '@' );
   1456                 if (parameter) {
   1457                     *parameter = 0;
   1458                     parameter += 1;
   1459                 }
   1460                 execCount = 0;
   1461                 UBool res = major.runTest( name, parameter, baseName );
   1462                 if (leaks && res) {
   1463                     major.run_phase2( name, parameter );
   1464                 }
   1465                 if (!res || (execCount <= 0)) {
   1466                     fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
   1467                 }
   1468             } else if(!strcmp(argv[i],"-x")) {
   1469               i++;
   1470             }
   1471         }
   1472     }
   1473 
   1474 
   1475 #if !UCONFIG_NO_FORMATTING
   1476     CalendarTimeZoneTest::cleanup();
   1477 #endif
   1478 
   1479     free(_testDataPath);
   1480     _testDataPath = 0;
   1481 
   1482     Locale lastDefaultLocale;
   1483     if (originalLocale != lastDefaultLocale) {
   1484         major.errln("FAILURE: A test changed the default locale without resetting it.");
   1485     }
   1486 
   1487     fprintf(stdout, "\n--------------------------------------\n");
   1488     if( major.printKnownIssues() ) {
   1489       fprintf(stdout, " To run suppressed tests, use the -K option. \n");
   1490     }
   1491     if (major.getErrors() == 0) {
   1492         /* Call it twice to make sure that the defaults were reset. */
   1493         /* Call it before the OK message to verify proper cleanup. */
   1494         u_cleanup();
   1495         u_cleanup();
   1496 
   1497         fprintf(stdout, "OK: All tests passed without error.\n");
   1498 
   1499         if (major.getDataErrors() != 0) {
   1500             fprintf(stdout, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
   1501         }
   1502     }else{
   1503         fprintf(stdout, "Errors in total: %ld.\n", (long)major.getErrors());
   1504         major.printErrors();
   1505 
   1506         if(summary_file != NULL) {
   1507           FILE *summf = fopen(summary_file, "w");
   1508           if( summf != NULL) {
   1509             char buf[10000];
   1510             int32_t length = errorList.extract(0, errorList.length(), buf, sizeof(buf));
   1511             fwrite(buf, sizeof(*buf), length, (FILE*)summf);
   1512             fclose(summf);
   1513           }
   1514         }
   1515 
   1516 
   1517         if (major.getDataErrors() != 0) {
   1518             fprintf(stdout, "\t*Note* some errors are data-loading related. If the data used is not the \n"
   1519                     "\tstock ICU data (i.e some have been added or removed), consider using\n"
   1520                     "\tthe '-w' option to turn these errors into warnings.\n");
   1521         }
   1522 
   1523         /* Call afterwards to display errors. */
   1524         u_cleanup();
   1525     }
   1526 
   1527     fprintf(stdout, "--------------------------------------\n");
   1528 
   1529     if (execCount <= 0) {
   1530         fprintf(stdout, "***** Not all called tests actually exist! *****\n");
   1531     }
   1532     if(!no_time) {
   1533       endTime = uprv_getRawUTCtime();
   1534       diffTime = (int32_t)(endTime - startTime);
   1535       printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
   1536              (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
   1537              (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
   1538              (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
   1539              (int)(diffTime%U_MILLIS_PER_SECOND));
   1540     }
   1541 
   1542     if(ctest_xml_fini())
   1543       return 1;
   1544 
   1545     return major.getErrors();
   1546 }
   1547 
   1548 const char* IntlTest::loadTestData(UErrorCode& err){
   1549     if( _testDataPath == NULL){
   1550         const char*      directory=NULL;
   1551         UResourceBundle* test =NULL;
   1552         char* tdpath=NULL;
   1553         const char* tdrelativepath;
   1554 
   1555 #if defined (U_TOPBUILDDIR)
   1556         tdrelativepath = "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
   1557         directory = U_TOPBUILDDIR;
   1558 #else
   1559         tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
   1560         directory = pathToDataDirectory();
   1561 #endif
   1562 
   1563         tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
   1564 
   1565 
   1566         /* u_getDataDirectory shoul return \source\data ... set the
   1567          * directory to ..\source\data\..\test\testdata\out\testdata
   1568          */
   1569         strcpy(tdpath, directory);
   1570         strcat(tdpath, tdrelativepath);
   1571         strcat(tdpath,"testdata");
   1572 
   1573         test=ures_open(tdpath, "testtypes", &err);
   1574 
   1575         if(U_FAILURE(err)){
   1576             err = U_FILE_ACCESS_ERROR;
   1577             it_dataerrln((UnicodeString)"Could not load testtypes.res in testdata bundle with path " + tdpath + (UnicodeString)" - " + u_errorName(err));
   1578             return "";
   1579         }
   1580         ures_close(test);
   1581         _testDataPath = tdpath;
   1582         return _testDataPath;
   1583     }
   1584     return _testDataPath;
   1585 }
   1586 
   1587 const char* IntlTest::getTestDataPath(UErrorCode& err) {
   1588     return loadTestData(err);
   1589 }
   1590 
   1591 /* Returns the path to icu/source/test/testdata/ */
   1592 const char *IntlTest::getSourceTestData(UErrorCode& /*err*/) {
   1593     const char *srcDataDir = NULL;
   1594 #ifdef U_TOPSRCDIR
   1595     srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
   1596 #else
   1597     srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
   1598     FILE *f = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "rbbitst.txt", "r");
   1599     if (f) {
   1600         /* We're in icu/source/test/intltest/ */
   1601         fclose(f);
   1602     }
   1603     else {
   1604         /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
   1605         srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata"U_FILE_SEP_STRING;
   1606     }
   1607 #endif
   1608     return srcDataDir;
   1609 }
   1610 
   1611 const char* IntlTest::fgDataDir = NULL;
   1612 
   1613 /* returns the path to icu/source/data */
   1614 const char *  IntlTest::pathToDataDirectory()
   1615 {
   1616 
   1617     if(fgDataDir != NULL) {
   1618         return fgDataDir;
   1619     }
   1620 
   1621     /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
   1622     //              to point to the top of the build hierarchy, which may or
   1623     //              may not be the same as the source directory, depending on
   1624     //              the configure options used.  At any rate,
   1625     //              set the data path to the built data from this directory.
   1626     //              The value is complete with quotes, so it can be used
   1627     //              as-is as a string constant.
   1628     */
   1629 #if defined (U_TOPSRCDIR)
   1630     {
   1631         fgDataDir = U_TOPSRCDIR  U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
   1632     }
   1633 #else
   1634 
   1635     /* On Windows, the file name obtained from __FILE__ includes a full path.
   1636      *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
   1637      *             Change to    "wherever\icu\source\data"
   1638      */
   1639     {
   1640         static char p[sizeof(__FILE__) + 10];
   1641         char *pBackSlash;
   1642         int i;
   1643 
   1644         strcpy(p, __FILE__);
   1645         /* We want to back over three '\' chars.                            */
   1646         /*   Only Windows should end up here, so looking for '\' is safe.   */
   1647         for (i=1; i<=3; i++) {
   1648             pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
   1649             if (pBackSlash != NULL) {
   1650                 *pBackSlash = 0;        /* Truncate the string at the '\'   */
   1651             }
   1652         }
   1653 
   1654         if (pBackSlash != NULL) {
   1655             /* We found and truncated three names from the path.
   1656             *  Now append "source\data" and set the environment
   1657             */
   1658             strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
   1659             fgDataDir = p;
   1660         }
   1661         else {
   1662             /* __FILE__ on MSVC7 does not contain the directory */
   1663             FILE *file = fopen(".." U_FILE_SEP_STRING ".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
   1664             if (file) {
   1665                 fclose(file);
   1666                 fgDataDir = ".." U_FILE_SEP_STRING ".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
   1667             }
   1668             else {
   1669                 fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
   1670             }
   1671         }
   1672     }
   1673 #endif
   1674 
   1675     return fgDataDir;
   1676 
   1677 }
   1678 
   1679 /*
   1680  * This is a variant of cintltst/ccolltst.c:CharsToUChars().
   1681  * It converts an invariant-character string into a UnicodeString, with
   1682  * unescaping \u sequences.
   1683  */
   1684 UnicodeString CharsToUnicodeString(const char* chars){
   1685     return UnicodeString(chars, -1, US_INV).unescape();
   1686 }
   1687 
   1688 UnicodeString ctou(const char* chars) {
   1689     return CharsToUnicodeString(chars);
   1690 }
   1691 
   1692 #define RAND_M  (714025)
   1693 #define RAND_IA (1366)
   1694 #define RAND_IC (150889)
   1695 
   1696 static int32_t RAND_SEED;
   1697 
   1698 /**
   1699  * Returns a uniform random value x, with 0.0 <= x < 1.0.  Use
   1700  * with care: Does not return all possible values; returns one of
   1701  * 714,025 values, uniformly spaced.  However, the period is
   1702  * effectively infinite.  See: Numerical Recipes, section 7.1.
   1703  *
   1704  * @param seedp pointer to seed. Set *seedp to any negative value
   1705  * to restart the sequence.
   1706  */
   1707 float IntlTest::random(int32_t* seedp) {
   1708     static int32_t iy, ir[98];
   1709     static UBool first=TRUE;
   1710     int32_t j;
   1711     if (*seedp < 0 || first) {
   1712         first = FALSE;
   1713         if ((*seedp=(RAND_IC-(*seedp)) % RAND_M) < 0) *seedp = -(*seedp);
   1714         for (j=1;j<=97;++j) {
   1715             *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
   1716             ir[j]=(*seedp);
   1717         }
   1718         *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
   1719         iy=(*seedp);
   1720     }
   1721     j=(int32_t)(1 + 97.0*iy/RAND_M);
   1722     U_ASSERT(j>=1 && j<=97);
   1723     iy=ir[j];
   1724     *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
   1725     ir[j]=(*seedp);
   1726     return (float) iy/RAND_M;
   1727 }
   1728 
   1729 /**
   1730  * Convenience method using a global seed.
   1731  */
   1732 float IntlTest::random() {
   1733     return random(&RAND_SEED);
   1734 }
   1735 
   1736 static inline UChar toHex(int32_t i) {
   1737     return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10)));
   1738 }
   1739 
   1740 static UnicodeString& escape(const UnicodeString& s, UnicodeString& result) {
   1741     for (int32_t i=0; i<s.length(); ++i) {
   1742         UChar c = s[i];
   1743         if (c <= (UChar)0x7F) {
   1744             result += c;
   1745         } else {
   1746             result += (UChar)0x5c;
   1747             result += (UChar)0x75;
   1748             result += toHex((c >> 12) & 0xF);
   1749             result += toHex((c >>  8) & 0xF);
   1750             result += toHex((c >>  4) & 0xF);
   1751             result += toHex( c        & 0xF);
   1752         }
   1753     }
   1754     return result;
   1755 }
   1756 
   1757 #define VERBOSE_ASSERTIONS
   1758 
   1759 UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError, const char *file, int line) {
   1760     if (file != NULL) {
   1761         if (!condition) {
   1762             if (possibleDataError) {
   1763                 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
   1764             } else {
   1765                 errln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
   1766             }
   1767         } else if (!quiet) {
   1768             logln("%s:%d: Ok: %s", file, line, message);
   1769         }
   1770     } else {
   1771         if (!condition) {
   1772             if (possibleDataError) {
   1773                 dataerrln("FAIL: assertTrue() failed: %s", message);
   1774             } else {
   1775                 errln("FAIL: assertTrue() failed: %s", message);
   1776             }
   1777         } else if (!quiet) {
   1778             logln("Ok: %s", message);
   1779         }
   1780 
   1781     }
   1782     return condition;
   1783 }
   1784 
   1785 UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet) {
   1786     if (condition) {
   1787         errln("FAIL: assertFalse() failed: %s", message);
   1788     } else if (!quiet) {
   1789         logln("Ok: %s", message);
   1790     }
   1791     return !condition;
   1792 }
   1793 
   1794 UBool IntlTest::assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError, const char *file, int line) {
   1795     if( file==NULL ) {
   1796       file = ""; // prevent failure if no file given
   1797     }
   1798     if (U_FAILURE(ec)) {
   1799         if (possibleDataError) {
   1800           dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
   1801         } else {
   1802           errcheckln(ec, "FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
   1803         }
   1804         return FALSE;
   1805     } else {
   1806       logln("OK: %s:%d: %s - (%s)", file, line, message, u_errorName(ec));
   1807     }
   1808     return TRUE;
   1809 }
   1810 
   1811 UBool IntlTest::assertEquals(const char* message,
   1812                              const UnicodeString& expected,
   1813                              const UnicodeString& actual,
   1814                              UBool possibleDataError) {
   1815     if (expected != actual) {
   1816         if (possibleDataError) {
   1817             dataerrln((UnicodeString)"FAIL: " + message + "; got " +
   1818                   prettify(actual) +
   1819                   "; expected " + prettify(expected));
   1820         } else {
   1821             errln((UnicodeString)"FAIL: " + message + "; got " +
   1822                   prettify(actual) +
   1823                   "; expected " + prettify(expected));
   1824         }
   1825         return FALSE;
   1826     }
   1827 #ifdef VERBOSE_ASSERTIONS
   1828     else {
   1829         logln((UnicodeString)"Ok: " + message + "; got " + prettify(actual));
   1830     }
   1831 #endif
   1832     return TRUE;
   1833 }
   1834 
   1835 UBool IntlTest::assertEquals(const char* message,
   1836                              const char* expected,
   1837                              const char* actual) {
   1838     if (uprv_strcmp(expected, actual) != 0) {
   1839         errln((UnicodeString)"FAIL: " + message + "; got \"" +
   1840               actual +
   1841               "\"; expected \"" + expected + "\"");
   1842         return FALSE;
   1843     }
   1844 #ifdef VERBOSE_ASSERTIONS
   1845     else {
   1846         logln((UnicodeString)"Ok: " + message + "; got \"" + actual + "\"");
   1847     }
   1848 #endif
   1849     return TRUE;
   1850 }
   1851 
   1852 UBool IntlTest::assertEquals(const char* message,
   1853                              int32_t expected,
   1854                              int32_t actual) {
   1855     if (expected != actual) {
   1856         errln((UnicodeString)"FAIL: " + message + "; got " +
   1857               actual + "=0x" + toHex(actual) +
   1858               "; expected " + expected + "=0x" + toHex(expected));
   1859         return FALSE;
   1860     }
   1861 #ifdef VERBOSE_ASSERTIONS
   1862     else {
   1863         logln((UnicodeString)"Ok: " + message + "; got " + actual + "=0x" + toHex(actual));
   1864     }
   1865 #endif
   1866     return TRUE;
   1867 }
   1868 
   1869 UBool IntlTest::assertEquals(const char* message,
   1870                              int64_t expected,
   1871                              int64_t actual) {
   1872     if (expected != actual) {
   1873         errln((UnicodeString)"FAIL: " + message + "; got int64 " +
   1874               Int64ToUnicodeString(actual) +
   1875               "; expected " + Int64ToUnicodeString(expected) );
   1876         return FALSE;
   1877     }
   1878 #ifdef VERBOSE_ASSERTIONS
   1879     else {
   1880       logln((UnicodeString)"Ok: " + message + "; got int64 " + Int64ToUnicodeString(actual));
   1881     }
   1882 #endif
   1883     return TRUE;
   1884 }
   1885 
   1886 UBool IntlTest::assertEquals(const char* message,
   1887                              UBool expected,
   1888                              UBool actual) {
   1889     if (expected != actual) {
   1890         errln((UnicodeString)"FAIL: " + message + "; got " +
   1891               toString(actual) +
   1892               "; expected " + toString(expected));
   1893         return FALSE;
   1894     }
   1895 #ifdef VERBOSE_ASSERTIONS
   1896     else {
   1897       logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
   1898     }
   1899 #endif
   1900     return TRUE;
   1901 }
   1902 
   1903 #if !UCONFIG_NO_FORMATTING
   1904 UBool IntlTest::assertEquals(const char* message,
   1905                              const Formattable& expected,
   1906                              const Formattable& actual,
   1907                              UBool possibleDataError) {
   1908     if (expected != actual) {
   1909         if (possibleDataError) {
   1910             dataerrln((UnicodeString)"FAIL: " + message + "; got " +
   1911                   toString(actual) +
   1912                   "; expected " + toString(expected));
   1913         } else {
   1914             errln((UnicodeString)"FAIL: " + message + "; got " +
   1915                   toString(actual) +
   1916                   "; expected " + toString(expected));
   1917         }
   1918         return FALSE;
   1919     }
   1920 #ifdef VERBOSE_ASSERTIONS
   1921     else {
   1922         logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
   1923     }
   1924 #endif
   1925     return TRUE;
   1926 }
   1927 #endif
   1928 
   1929 static char ASSERT_BUF[256];
   1930 
   1931 static const char* extractToAssertBuf(const UnicodeString& message) {
   1932     UnicodeString buf;
   1933     escape(message, buf);
   1934     buf.extract(0, 0x7FFFFFFF, ASSERT_BUF, sizeof(ASSERT_BUF)-1, 0);
   1935     ASSERT_BUF[sizeof(ASSERT_BUF)-1] = 0;
   1936     return ASSERT_BUF;
   1937 }
   1938 
   1939 UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet) {
   1940     return assertTrue(extractToAssertBuf(message), condition, quiet);
   1941 }
   1942 
   1943 UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet) {
   1944     return assertFalse(extractToAssertBuf(message), condition, quiet);
   1945 }
   1946 
   1947 UBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) {
   1948     return assertSuccess(extractToAssertBuf(message), ec);
   1949 }
   1950 
   1951 UBool IntlTest::assertEquals(const UnicodeString& message,
   1952                              const UnicodeString& expected,
   1953                              const UnicodeString& actual,
   1954                              UBool possibleDataError) {
   1955     return assertEquals(extractToAssertBuf(message), expected, actual, possibleDataError);
   1956 }
   1957 
   1958 UBool IntlTest::assertEquals(const UnicodeString& message,
   1959                              const char* expected,
   1960                              const char* actual) {
   1961     return assertEquals(extractToAssertBuf(message), expected, actual);
   1962 }
   1963 UBool IntlTest::assertEquals(const UnicodeString& message,
   1964                              UBool expected,
   1965                              UBool actual) {
   1966     return assertEquals(extractToAssertBuf(message), expected, actual);
   1967 }
   1968 UBool IntlTest::assertEquals(const UnicodeString& message,
   1969                              int32_t expected,
   1970                              int32_t actual) {
   1971     return assertEquals(extractToAssertBuf(message), expected, actual);
   1972 }
   1973 UBool IntlTest::assertEquals(const UnicodeString& message,
   1974                              int64_t expected,
   1975                              int64_t actual) {
   1976     return assertEquals(extractToAssertBuf(message), expected, actual);
   1977 }
   1978 
   1979 #if !UCONFIG_NO_FORMATTING
   1980 UBool IntlTest::assertEquals(const UnicodeString& message,
   1981                              const Formattable& expected,
   1982                              const Formattable& actual) {
   1983     return assertEquals(extractToAssertBuf(message), expected, actual);
   1984 }
   1985 #endif
   1986 
   1987 void IntlTest::setProperty(const char* propline) {
   1988     if (numProps < kMaxProps) {
   1989         proplines[numProps] = propline;
   1990     }
   1991     numProps++;
   1992 }
   1993 
   1994 const char* IntlTest::getProperty(const char* prop) {
   1995     const char* val = NULL;
   1996     for (int32_t i = 0; i < numProps; i++) {
   1997         int32_t plen = uprv_strlen(prop);
   1998         if ((int32_t)uprv_strlen(proplines[i]) > plen + 1
   1999                 && proplines[i][plen] == '='
   2000                 && uprv_strncmp(proplines[i], prop, plen) == 0) {
   2001             val = &(proplines[i][plen+1]);
   2002             break;
   2003         }
   2004     }
   2005     return val;
   2006 }
   2007 
   2008 /*
   2009  * Hey, Emacs, please set the following:
   2010  *
   2011  * Local Variables:
   2012  * indent-tabs-mode: nil
   2013  * End:
   2014  *
   2015  */
   2016