1 /******************************************************************** 
   3  * Copyright (c) 1997-2016, International Business Machines Corporation and 
   4  * others. All Rights Reserved. 
   5  ********************************************************************/ 
   8 #include "unicode/utypes.h" 
  11  * IntlTest is a base class for tests. 
  20 #include "unicode/ctest.h" // for str_timeDelta 
  21 #include "unicode/curramt.h" 
  22 #include "unicode/locid.h" 
  23 #include "unicode/putil.h" 
  24 #include "unicode/smpdtfmt.h" 
  25 #include "unicode/timezone.h" 
  26 #include "unicode/uclean.h" 
  27 #include "unicode/ucnv.h" 
  28 #include "unicode/unistr.h" 
  29 #include "unicode/ures.h" 
  38 #include "putilimp.h" // for uprv_getRawUTCtime() 
  50 static char* _testDataPath
=NULL
; 
  52 // Static list of errors found 
  53 static UnicodeString errorList
; 
  54 static void *knownList 
= NULL
; // known issues 
  55 static UBool noKnownIssues 
= FALSE
; // if TRUE, don't emit known issues 
  57 //----------------------------------------------------------------------------- 
  58 //convenience classes to ease porting code that uses the Java 
  59 //string-concatenation operator (moved from findword test by rtg) 
  61 // [LIU] Just to get things working 
  63 UCharToUnicodeString(UChar c
) 
  64 { return UnicodeString(c
); } 
  66 // [rtg] Just to get things working 
  68 operator+(const UnicodeString
& left
, 
  71     char buffer
[64];    // nos changed from 10 to 64 
  72     char danger 
= 'p';  // guard against overrunning the buffer (rtg) 
  74     sprintf(buffer
, "%ld", num
); 
  75     assert(danger 
== 'p'); 
  81 operator+(const UnicodeString
& left
, 
  84     char buffer
[64];    // nos changed from 10 to 64 
  85     char danger 
= 'p';  // guard against overrunning the buffer (rtg) 
  87     sprintf(buffer
, "%lu", num
); 
  88     assert(danger 
== 'p'); 
  94 Int64ToUnicodeString(int64_t num
) 
  96     char buffer
[64];    // nos changed from 10 to 64 
  97     char danger 
= 'p';  // guard against overrunning the buffer (rtg) 
 100     sprintf(buffer
, "%I64d", num
); 
 102     sprintf(buffer
, "%lld", (long long)num
); 
 104     assert(danger 
== 'p'); 
 109 // [LIU] Just to get things working 
 111 operator+(const UnicodeString
& left
, 
 114     char buffer
[64];   // was 32, made it arbitrarily bigger (rtg) 
 115     char danger 
= 'p'; // guard against overrunning the buffer (rtg) 
 117     // IEEE floating point has 52 bits of mantissa, plus one assumed bit 
 118     //  53*log(2)/log(10) = 15.95 
 119     // so there is no need to show more than 16 digits. [alan] 
 121     sprintf(buffer
, "%.17g", num
); 
 122     assert(danger 
== 'p'); 
 124     return left 
+ buffer
; 
 129 operator+(const UnicodeString
& left
, 
 131   return left 
+ Int64ToUnicodeString(num
); 
 135 #if !UCONFIG_NO_FORMATTING 
 138  * Return a string display for this, without surrounding braces. 
 140 UnicodeString 
_toString(const Formattable
& f
) { 
 142     switch (f
.getType()) { 
 143     case Formattable::kDate
: 
 145             UErrorCode status 
= U_ZERO_ERROR
; 
 146             SimpleDateFormat 
fmt(status
); 
 147             if (U_SUCCESS(status
)) { 
 149                 fmt
.format(f
.getDate(), s
, pos
); 
 150                 s
.insert(0, "Date:"); 
 152                 s 
= UnicodeString("Error creating date format]"); 
 156     case Formattable::kDouble
: 
 157         s 
= UnicodeString("double:") + f
.getDouble(); 
 159     case Formattable::kLong
: 
 160         s 
= UnicodeString("long:") + f
.getLong(); 
 163     case Formattable::kInt64
: 
 164         s 
= UnicodeString("int64:") + Int64ToUnicodeString(f
.getInt64()); 
 167     case Formattable::kString
: 
 169         s
.insert(0, "String:"); 
 171     case Formattable::kArray
: 
 174             const Formattable
* array 
= f
.getArray(n
); 
 175             s
.insert(0, UnicodeString("Array:")); 
 176             UnicodeString 
delim(", "); 
 177             for (i
=0; i
<n
; ++i
) { 
 181                 s 
= s 
+ _toString(array
[i
]); 
 185     case Formattable::kObject
: { 
 186         const CurrencyAmount
* c 
= dynamic_cast<const CurrencyAmount
*>(f
.getObject()); 
 188             s 
= _toString(c
->getNumber()) + " " + UnicodeString(c
->getISOCurrency()); 
 190             s 
= UnicodeString("Unknown UObject"); 
 195         s 
= UnicodeString("Unknown Formattable type=") + (int32_t)f
.getType(); 
 202  * Originally coded this as operator+, but that makes the expression 
 203  * + char* ambiguous. - liu 
 205 UnicodeString 
toString(const Formattable
& f
) { 
 206     UnicodeString 
s((UChar
)91/*[*/); 
 207     s
.append(_toString(f
)); 
 208     s
.append((UChar
)0x5d/*]*/); 
 214 // useful when operator+ won't cooperate 
 215 UnicodeString 
toString(int32_t n
) { 
 216     return UnicodeString() + (long)n
; 
 221 UnicodeString 
toString(UBool b
) { 
 222   return b 
? UnicodeString("TRUE"):UnicodeString("FALSE"); 
 225 // stephen - cleaned up 05/05/99 
 226 UnicodeString 
operator+(const UnicodeString
& left
, char num
) 
 227 { return left 
+ (long)num
; } 
 228 UnicodeString 
operator+(const UnicodeString
& left
, short num
) 
 229 { return left 
+ (long)num
; } 
 230 UnicodeString 
operator+(const UnicodeString
& left
, int num
) 
 231 { return left 
+ (long)num
; } 
 232 UnicodeString 
operator+(const UnicodeString
& left
, unsigned char num
) 
 233 { return left 
+ (unsigned long)num
; } 
 234 UnicodeString 
operator+(const UnicodeString
& left
, unsigned short num
) 
 235 { return left 
+ (unsigned long)num
; } 
 236 UnicodeString 
operator+(const UnicodeString
& left
, unsigned int num
) 
 237 { return left 
+ (unsigned long)num
; } 
 238 UnicodeString 
operator+(const UnicodeString
& left
, float num
) 
 239 { return left 
+ (double)num
; } 
 243 // Append a hex string to the target 
 245 IntlTest::appendHex(uint32_t number
, 
 247             UnicodeString
& target
) 
 249     static const UChar digitString
[] = { 
 250         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 
 251         0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0 
 252     }; /* "0123456789ABCDEF" */ 
 254     if (digits 
< 0) {  // auto-digits 
 257         while (number 
> max
) { 
 259             max 
= (max 
<< 8) | 0xff; 
 265         target 
+= digitString
[(number 
>> 28) & 0xF]; 
 268         target 
+= digitString
[(number 
>> 24) & 0xF]; 
 271         target 
+= digitString
[(number 
>> 20) & 0xF]; 
 274         target 
+= digitString
[(number 
>> 16) & 0xF]; 
 277         target 
+= digitString
[(number 
>> 12) & 0xF]; 
 280         target 
+= digitString
[(number 
>>  8) & 0xF]; 
 283         target 
+= digitString
[(number 
>>  4) & 0xF]; 
 286         target 
+= digitString
[(number 
>>  0) & 0xF]; 
 295 IntlTest::toHex(uint32_t number
, int32_t digits
) { 
 296     UnicodeString result
; 
 297     appendHex(number
, digits
, result
); 
 301 static inline UBool 
isPrintable(UChar32 c
) { 
 302     return c 
<= 0x7E && (c 
>= 0x20 || c 
== 9 || c 
== 0xA || c 
== 0xD); 
 305 // Replace nonprintable characters with unicode escapes 
 307 IntlTest::prettify(const UnicodeString 
&source
, 
 308            UnicodeString 
&target
) 
 315     for (i 
= 0; i 
< source
.length(); ) 
 317         UChar32 ch 
= source
.char32At(i
); 
 320         if (!isPrintable(ch
)) 
 324                 appendHex(ch
, 4, target
); 
 327                 appendHex(ch
, 8, target
); 
 341 // Replace nonprintable characters with unicode escapes 
 343 IntlTest::prettify(const UnicodeString 
&source
, UBool parseBackslash
) 
 346     UnicodeString target
; 
 350     for (i 
= 0; i 
< source
.length();) 
 352         UChar32 ch 
= source
.char32At(i
); 
 355         if (!isPrintable(ch
)) 
 357             if (parseBackslash
) { 
 358                 // If we are preceded by an odd number of backslashes, 
 359                 // then this character has already been backslash escaped. 
 360                 // Delete a backslash. 
 361                 int32_t backslashCount 
= 0; 
 362                 for (int32_t j
=target
.length()-1; j
>=0; --j
) { 
 363                     if (target
.charAt(j
) == (UChar
)92) { 
 369                 if ((backslashCount 
% 2) == 1) { 
 370                     target
.truncate(target
.length() - 1); 
 375                 appendHex(ch
, 4, target
); 
 378                 appendHex(ch
, 8, target
); 
 392 /*  IntlTest::setICU_DATA  - if the ICU_DATA environment variable is not already 
 393  *                       set, try to deduce the directory in which ICU was built, 
 394  *                       and set ICU_DATA to "icu/source/data" in that location. 
 395  *                       The intent is to allow the tests to have a good chance 
 396  *                       of running without requiring that the user manually set 
 397  *                       ICU_DATA.  Common data isn't a problem, since it is 
 398  *                       picked up via a static (build time) reference, but the 
 399  *                       tests dynamically load some data. 
 401 void IntlTest::setICU_DATA() { 
 402     const char *original_ICU_DATA 
= getenv("ICU_DATA"); 
 404     if (original_ICU_DATA 
!= NULL 
&& *original_ICU_DATA 
!= 0) { 
 405         /*  If the user set ICU_DATA, don't second-guess the person. */ 
 409     // U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst 
 410     //              to point to the top of the build hierarchy, which may or 
 411     //              may not be the same as the source directory, depending on 
 412     //              the configure options used.  At any rate, 
 413     //              set the data path to the built data from this directory. 
 414     //              The value is complete with quotes, so it can be used 
 415     //              as-is as a string constant. 
 417 #if defined (U_TOPBUILDDIR) 
 419         static char env_string
[] = U_TOPBUILDDIR 
"data" U_FILE_SEP_STRING 
"out" U_FILE_SEP_STRING
; 
 420         u_setDataDirectory(env_string
); 
 425     // Use #else so we don't get compiler warnings due to the return above. 
 427     /* On Windows, the file name obtained from __FILE__ includes a full path. 
 428      *             This file is "wherever\icu\source\test\cintltst\cintltst.c" 
 429      *             Change to    "wherever\icu\source\data" 
 432         char p
[sizeof(__FILE__
) + 10]; 
 437         /* We want to back over three '\' chars.                            */ 
 438         /*   Only Windows should end up here, so looking for '\' is safe.   */ 
 439         for (i
=1; i
<=3; i
++) { 
 440             pBackSlash 
= strrchr(p
, U_FILE_SEP_CHAR
); 
 441             if (pBackSlash 
!= NULL
) { 
 442                 *pBackSlash 
= 0;        /* Truncate the string at the '\'   */ 
 446         if (pBackSlash 
!= NULL
) { 
 447             /* We found and truncated three names from the path. 
 448              *  Now append "source\data" and set the environment 
 450             strcpy(pBackSlash
, U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING 
"out" U_FILE_SEP_STRING
); 
 451             u_setDataDirectory(p
);     /*  p is "ICU_DATA=wherever\icu\source\data"    */ 
 455             /* __FILE__ on MSVC7 does not contain the directory */ 
 456             u_setDataDirectory(".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING 
"out" U_FILE_SEP_STRING
); 
 462     /* No location for the data dir was identifiable. 
 463      *   Add other fallbacks for the test data location here if the need arises 
 468 //-------------------------------------------------------------------------------------- 
 470 static const int32_t indentLevel_offset 
= 3; 
 471 static const char delim 
= '/'; 
 473 IntlTest
* IntlTest::gTest 
= NULL
; 
 475 static int32_t execCount 
= 0; 
 477 void it_log( UnicodeString message 
) 
 480         IntlTest::gTest
->log( message 
); 
 483 void it_logln( UnicodeString message 
) 
 486         IntlTest::gTest
->logln( message 
); 
 489 void it_logln( void ) 
 492         IntlTest::gTest
->logln(); 
 495 void it_info( UnicodeString message 
) 
 498         IntlTest::gTest
->info( message 
); 
 501 void it_infoln( UnicodeString message 
) 
 504         IntlTest::gTest
->infoln( message 
); 
 507 void it_infoln( void ) 
 510         IntlTest::gTest
->infoln(); 
 516         IntlTest::gTest
->err(); 
 519 void it_err( UnicodeString message 
) 
 522         IntlTest::gTest
->err( message 
); 
 525 void it_errln( UnicodeString message 
) 
 528         IntlTest::gTest
->errln( message 
); 
 531 void it_dataerr( UnicodeString message 
) 
 534         IntlTest::gTest
->dataerr( message 
); 
 537 void it_dataerrln( UnicodeString message 
) 
 540         IntlTest::gTest
->dataerrln( message 
); 
 553     warn_on_missing_data 
= FALSE
; 
 558     LL_indentlevel 
= indentLevel_offset
; 
 560     strcpy(basePath
, "/"); 
 564 void IntlTest::setCaller( IntlTest
* callingTest 
) 
 566     caller 
= callingTest
; 
 568         warn_on_missing_data 
= caller
->warn_on_missing_data
; 
 569         verbose 
= caller
->verbose
; 
 570         no_err_msg 
= caller
->no_err_msg
; 
 571         quick 
= caller
->quick
; 
 572         threadCount 
= caller
->threadCount
; 
 573         testoutfp 
= caller
->testoutfp
; 
 574         LL_indentlevel 
= caller
->LL_indentlevel 
+ indentLevel_offset
; 
 575         numProps 
= caller
->numProps
; 
 576         for (int32_t i 
= 0; i 
< numProps
; i
++) { 
 577             proplines
[i
] = caller
->proplines
[i
]; 
 582 UBool 
IntlTest::callTest( IntlTest
& testToBeCalled
, char* par 
) 
 584     execCount
--; // correct a previously assumed test-exec, as this only calls a subtest 
 585     testToBeCalled
.setCaller( this ); 
 586     strcpy(testToBeCalled
.basePath
, this->basePath 
); 
 587     UBool result 
= testToBeCalled
.runTest( testPath
, par
, testToBeCalled
.basePath 
); 
 588     strcpy(testToBeCalled
.basePath
, this->basePath 
); // reset it. 
 592 void IntlTest::setPath( char* pathVal 
) 
 594     this->testPath 
= pathVal
; 
 597 UBool 
IntlTest::setVerbose( UBool verboseVal 
) 
 599     UBool rval 
= this->verbose
; 
 600     this->verbose 
= verboseVal
; 
 604 UBool 
IntlTest::setNotime( UBool no_time 
) 
 606     UBool rval 
= this->no_time
; 
 607     this->no_time 
= no_time
; 
 611 UBool 
IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal 
) 
 613     UBool rval 
= this->warn_on_missing_data
; 
 614     this->warn_on_missing_data 
= warn_on_missing_dataVal
; 
 618 UBool 
IntlTest::setNoErrMsg( UBool no_err_msgVal 
) 
 620     UBool rval 
= this->no_err_msg
; 
 621     this->no_err_msg 
= no_err_msgVal
; 
 625 UBool 
IntlTest::setQuick( UBool quickVal 
) 
 627     UBool rval 
= this->quick
; 
 628     this->quick 
= quickVal
; 
 632 UBool 
IntlTest::setLeaks( UBool leaksVal 
) 
 634     UBool rval 
= this->leaks
; 
 635     this->leaks 
= leaksVal
; 
 639 int32_t IntlTest::setThreadCount( int32_t count 
) 
 641     int32_t rval 
= this->threadCount
; 
 642     this->threadCount 
= count
; 
 646 int32_t IntlTest::getErrors( void ) 
 651 int32_t IntlTest::getDataErrors( void ) 
 653     return dataErrorCount
; 
 656 UBool 
IntlTest::runTest( char* name
, char* par
, char *baseName 
) 
 661     char* baseNameBuffer 
= NULL
; 
 663     if(baseName 
== NULL
) { 
 664       baseNameBuffer 
= (char*)malloc(1024); 
 665       baseName
=baseNameBuffer
; 
 666       strcpy(baseName
, "/"); 
 670         pos 
= strchr( name
, delim 
); // check if name contains path (by looking for '/') 
 672         testPath 
= pos
+1;   // store subpath for calling subtest 
 673         *pos 
= 0;       // split into two strings 
 678     if (!name 
|| (name
[0] == 0) || (strcmp(name
, "*") == 0)) { 
 679       rval 
= runTestLoop( NULL
, par
, baseName 
); 
 681     }else if (strcmp( name
, "LIST" ) == 0) { 
 686       rval 
= runTestLoop( name
, par
, baseName 
); 
 690         *pos 
= delim
;  // restore original value at pos 
 691     if(baseNameBuffer
!=NULL
) { 
 692       free(baseNameBuffer
); 
 697 // call individual tests, to be overriden to call implementations 
 698 void IntlTest::runIndexedTest( int32_t /*index*/, UBool 
/*exec*/, const char* & /*name*/, char* /*par*/ ) 
 700     // to be overriden by a method like: 
 703         case 0: name = "First Test"; if (exec) FirstTest( par ); break; 
 704         case 1: name = "Second Test"; if (exec) SecondTest( par ); break; 
 705         default: name = ""; break; 
 708     this->errln("*** runIndexedTest needs to be overriden! ***"); 
 712 UBool 
IntlTest::runTestLoop( char* testname
, char* par
, char *baseName 
) 
 717     int32_t    lastErrorCount
; 
 719     UBool   lastTestFailed
; 
 721     if(baseName 
== NULL
) { 
 722       printf("ERROR: baseName can't be null.\n"); 
 725       if ((char *)this->basePath 
!= baseName
) { 
 726         strcpy(this->basePath
, baseName
); 
 730     char * saveBaseLoc 
= baseName
+strlen(baseName
); 
 732     IntlTest
* saveTest 
= gTest
; 
 735         this->runIndexedTest( index
, FALSE
, name
, par 
); 
 736         if (strcmp(name
,"skip") == 0) { 
 737             run_this_test 
= FALSE
; 
 739             if (!name 
|| (name
[0] == 0)) 
 742                 run_this_test 
= TRUE
; 
 744                 run_this_test 
= (UBool
) (strcmp( name
, testname 
) == 0); 
 748             lastErrorCount 
= errorCount
; 
 751             sprintf(msg
, "%s {", name
); 
 752             LL_message(msg
, TRUE
); 
 753             UDate timeStart 
= uprv_getRawUTCtime(); 
 754             strcpy(saveBaseLoc
,name
); 
 755             strcat(saveBaseLoc
,"/"); 
 757             strcpy(currName
, name
); // set 
 758             this->runIndexedTest( index
, TRUE
, name
, par 
); 
 759             currName
[0]=0; // reset 
 761             UDate timeStop 
= uprv_getRawUTCtime(); 
 762             rval 
= TRUE
; // at least one test has been called 
 765               sprintf(secs
, "%f", (timeStop
-timeStart
)/1000.0); 
 771             strcpy(saveBaseLoc
,name
); 
 774             ctest_xml_testcase(baseName
, name
, secs
, (lastErrorCount
!=errorCount
)?"err":NULL
); 
 777             saveBaseLoc
[0]=0; /* reset path */ 
 779             if (lastErrorCount 
== errorCount
) { 
 780                 sprintf( msg
, "   } OK:   %s ", name 
); 
 781                 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
); 
 782                 lastTestFailed 
= FALSE
; 
 784                 sprintf(msg
,  "   } ERRORS (%li) in %s", (long)(errorCount
-lastErrorCount
), name
); 
 785                 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
); 
 787                 for(int i
=0;i
<LL_indentlevel
;i
++) { 
 792                 lastTestFailed 
= TRUE
; 
 795             if (lastTestFailed
) { 
 796                 LL_message( "", TRUE
); 
 798             LL_message( msg
, TRUE
); 
 799             if (lastTestFailed
) { 
 800                 LL_message( "", TRUE
); 
 815 * Adds given string to the log if we are in verbose mode. 
 817 void IntlTest::log( const UnicodeString 
&message 
) 
 820         LL_message( message
, FALSE 
); 
 825 * Adds given string to the log if we are in verbose mode. Adds a new line to 
 828 void IntlTest::logln( const UnicodeString 
&message 
) 
 831         LL_message( message
, TRUE 
); 
 835 void IntlTest::logln( void ) 
 838         LL_message( "", TRUE 
); 
 843 * Unconditionally adds given string to the log. 
 845 void IntlTest::info( const UnicodeString 
&message 
) 
 847   LL_message( message
, FALSE 
); 
 851 * Unconditionally adds given string to the log. Adds a new line to 
 854 void IntlTest::infoln( const UnicodeString 
&message 
) 
 856   LL_message( message
, TRUE 
); 
 859 void IntlTest::infoln( void ) 
 861   LL_message( "", TRUE 
); 
 864 int32_t IntlTest::IncErrorCount( void ) 
 867     if (caller
) caller
->IncErrorCount(); 
 871 int32_t IntlTest::IncDataErrorCount( void ) 
 874     if (caller
) caller
->IncDataErrorCount(); 
 875     return dataErrorCount
; 
 883 void IntlTest::err( const UnicodeString 
&message 
) 
 886     if (!no_err_msg
) LL_message( message
, FALSE 
); 
 889 void IntlTest::errln( const UnicodeString 
&message 
) 
 892     if (!no_err_msg
) LL_message( message
, TRUE 
); 
 895 void IntlTest::dataerr( const UnicodeString 
&message 
) 
 899     if (!warn_on_missing_data
) { 
 903     if (!no_err_msg
) LL_message( message
, FALSE 
); 
 906 void IntlTest::dataerrln( const UnicodeString 
&message 
) 
 908     int32_t errCount 
= IncDataErrorCount(); 
 910     if (!warn_on_missing_data
) { 
 914         msg 
= UnicodeString("[DATA] " + message
); 
 918       if ( errCount 
== 1) { 
 919           LL_message( msg 
+ " - (Are you missing data?)", TRUE 
); // only show this message the first time 
 921           LL_message( msg 
, TRUE 
); 
 926 void IntlTest::errcheckln(UErrorCode status
, const UnicodeString 
&message 
) { 
 927     if (status 
== U_FILE_ACCESS_ERROR 
|| status 
== U_MISSING_RESOURCE_ERROR
) { 
 934 /* convenience functions that include sprintf formatting */ 
 935 void IntlTest::log(const char *fmt
, ...) 
 941     /* sprintf it just to make sure that the information is valid */ 
 942     vsprintf(buffer
, fmt
, ap
); 
 945         log(UnicodeString(buffer
, (const char *)NULL
)); 
 949 void IntlTest::logln(const char *fmt
, ...) 
 955     /* sprintf it just to make sure that the information is valid */ 
 956     vsprintf(buffer
, fmt
, ap
); 
 959         logln(UnicodeString(buffer
, (const char *)NULL
)); 
 963 UBool 
IntlTest::logKnownIssue(const char *ticket
, const char *fmt
, ...) 
 969     /* sprintf it just to make sure that the information is valid */ 
 970     vsprintf(buffer
, fmt
, ap
); 
 972     return logKnownIssue(ticket
, UnicodeString(buffer
, (const char *)NULL
)); 
 975 UBool 
IntlTest::logKnownIssue(const char *ticket
) { 
 976   return logKnownIssue(ticket
, UnicodeString()); 
 979 UBool 
IntlTest::logKnownIssue(const char *ticket
, const UnicodeString 
&msg
) { 
 980   if(noKnownIssues
) return FALSE
; 
 983   strcpy(fullpath
, basePath
); 
 984   strcat(fullpath
, currName
); 
 985   UnicodeString msg2 
= msg
; 
 986   UBool firstForTicket 
= TRUE
, firstForWhere 
= TRUE
; 
 987   knownList 
= udbg_knownIssue_openU(knownList
, ticket
, fullpath
, msg2
.getTerminatedBuffer(), &firstForTicket
, &firstForWhere
); 
 989   msg2 
= UNICODE_STRING_SIMPLE("(Known issue #") + 
 990       UnicodeString(ticket
, -1, US_INV
) + UNICODE_STRING_SIMPLE(") ") + msg
; 
 991   if(firstForTicket 
|| firstForWhere
) { 
1000 /* convenience functions that include sprintf formatting */ 
1001 void IntlTest::info(const char *fmt
, ...) 
1007     /* sprintf it just to make sure that the information is valid */ 
1008     vsprintf(buffer
, fmt
, ap
); 
1010     info(UnicodeString(buffer
, (const char *)NULL
)); 
1013 void IntlTest::infoln(const char *fmt
, ...) 
1019     /* sprintf it just to make sure that the information is valid */ 
1020     vsprintf(buffer
, fmt
, ap
); 
1022     infoln(UnicodeString(buffer
, (const char *)NULL
)); 
1025 void IntlTest::err(const char *fmt
, ...) 
1031     vsprintf(buffer
, fmt
, ap
); 
1033     err(UnicodeString(buffer
, (const char *)NULL
)); 
1036 void IntlTest::errln(const char *fmt
, ...) 
1042     vsprintf(buffer
, fmt
, ap
); 
1044     errln(UnicodeString(buffer
, (const char *)NULL
)); 
1047 void IntlTest::dataerrln(const char *fmt
, ...) 
1053     vsprintf(buffer
, fmt
, ap
); 
1055     dataerrln(UnicodeString(buffer
, (const char *)NULL
)); 
1058 void IntlTest::errcheckln(UErrorCode status
, const char *fmt
, ...) 
1064     vsprintf(buffer
, fmt
, ap
); 
1067     if (status 
== U_FILE_ACCESS_ERROR 
|| status 
== U_MISSING_RESOURCE_ERROR
) { 
1068         dataerrln(UnicodeString(buffer
, (const char *)NULL
)); 
1070         errln(UnicodeString(buffer
, (const char *)NULL
)); 
1074 void IntlTest::printErrors() 
1076      IntlTest::LL_message(errorList
, TRUE
); 
1079 UBool 
IntlTest::printKnownIssues() 
1081   if(knownList 
!= NULL
) { 
1082     udbg_knownIssue_print(knownList
); 
1083     udbg_knownIssue_close(knownList
); 
1090 static UMutex messageMutex 
= U_MUTEX_INITIALIZER
; 
1092 void IntlTest::LL_message( UnicodeString message
, UBool newline 
) 
1094     // Synchronize this function. 
1095     // All error messages generated by tests funnel through here. 
1096     // Multithreaded tests can concurrently generate errors, requiring syncronization 
1097     // to keep each message together. 
1098     Mutex 
lock(&messageMutex
); 
1100     // string that starts with a LineFeed character and continues 
1101     // with spaces according to the current indentation 
1102     static const UChar indentUChars
[] = { 
1104         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1105         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1106         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1107         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1108         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1109         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1110         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1111         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1112         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
1113         32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 
1115     U_ASSERT(1 + LL_indentlevel 
<= UPRV_LENGTHOF(indentUChars
)); 
1116     UnicodeString 
indent(FALSE
, indentUChars
, 1 + LL_indentlevel
); 
1121     // stream out the indentation string first if necessary 
1122     length 
= indent
.extract(1, indent
.length(), buffer
, sizeof(buffer
)); 
1124         fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
); 
1127     // replace each LineFeed by the indentation string 
1128     message
.findAndReplace(UnicodeString((UChar
)'\n'), indent
); 
1130     // stream out the message 
1131     length 
= message
.extract(0, message
.length(), buffer
, sizeof(buffer
)); 
1133         length 
= length 
> 30000 ? 30000 : length
; 
1134         fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
); 
1138         char newLine 
= '\n'; 
1139         fwrite(&newLine
, sizeof(newLine
), 1, (FILE *)testoutfp
); 
1142     // A newline usually flushes the buffer, but 
1143     // flush the message just in case of a core dump. 
1144     fflush((FILE *)testoutfp
); 
1148 * Print a usage message for this test class. 
1150 void IntlTest::usage( void ) 
1152     UBool save_verbose 
= setVerbose( TRUE 
); 
1153     logln("Test names:"); 
1154     logln("-----------"); 
1157     const char* name 
= NULL
; 
1159         this->runIndexedTest( index
, FALSE
, name 
); 
1163     }while (name 
&& (name
[0] != 0)); 
1164     setVerbose( save_verbose 
); 
1168 // memory leak reporting software will be able to take advantage of the testsuite 
1169 // being run a second time local to a specific method in order to report only actual leaks 
1171 IntlTest::run_phase2( char* name
, char* par 
) // supports reporting memory leaks 
1173     UnicodeString
* strLeak 
= new UnicodeString("forced leak"); // for verifying purify filter 
1174     strLeak
->append(" for verifying purify filter"); 
1175     return this->runTest( name
, par 
); 
1179 #if UCONFIG_NO_LEGACY_CONVERSION 
1180 #   define TRY_CNV_1 "iso-8859-1" 
1181 #   define TRY_CNV_2 "ibm-1208" 
1183 #   define TRY_CNV_1 "iso-8859-7" 
1184 #   define TRY_CNV_2 "sjis" 
1187 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS 
1188 U_CAPI 
void unistr_printLengths(); 
1192 main(int argc
, char* argv
[]) 
1194     UBool syntax 
= FALSE
; 
1196     UBool verbose 
= FALSE
; 
1197     UBool no_err_msg 
= FALSE
; 
1198     UBool no_time 
= FALSE
; 
1201     UBool leaks 
= FALSE
; 
1203     const char *summary_file 
= NULL
; 
1204     UBool warnOnMissingData 
= FALSE
; 
1205     UBool defaultDataFound 
= FALSE
; 
1206     int32_t threadCount 
= 12; 
1207     UErrorCode errorCode 
= U_ZERO_ERROR
; 
1208     UConverter 
*cnv 
= NULL
; 
1209     const char *warnOrErr 
= "Failure"; 
1210     UDate startTime
, endTime
; 
1212     const char *props
[IntlTest::kMaxProps
]; 
1215     U_MAIN_INIT_ARGS(argc
, argv
); 
1217     startTime 
= uprv_getRawUTCtime(); 
1219     for (int i 
= 1; i 
< argc
; ++i
) { 
1220         if (argv
[i
][0] == '-') { 
1221             const char* str 
= argv
[i
] + 1; 
1222             if (strcmp("verbose", str
) == 0 || 
1223                 strcmp("v", str
) == 0) 
1225             else if (strcmp("noerrormsg", str
) == 0 || 
1226                      strcmp("n", str
) == 0) 
1228             else if (strcmp("exhaustive", str
) == 0 || 
1229                      strcmp("e", str
) == 0) 
1231             else if (strcmp("all", str
) == 0 || 
1232                      strcmp("a", str
) == 0) 
1234             else if (strcmp("utf-8", str
) == 0 || 
1235                      strcmp("u", str
) == 0) 
1237             else if (strcmp("noknownissues", str
) == 0 || 
1238                      strcmp("K", str
) == 0) 
1239                 noKnownIssues 
= TRUE
; 
1240             else if (strcmp("leaks", str
) == 0 || 
1241                      strcmp("l", str
) == 0) 
1243             else if (strcmp("notime", str
) == 0 || 
1244                      strcmp("T", str
) == 0) 
1246             else if (strncmp("E", str
, 1) == 0) 
1247                 summary_file 
= str
+1; 
1248             else if (strcmp("x", str
)==0) { 
1250                 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n"); 
1253               if(ctest_xml_setFileName(argv
[i
])) { /* set the name */ 
1254                 return 1; /* error */ 
1256             } else if (strcmp("w", str
) == 0) { 
1257               warnOnMissingData 
= TRUE
; 
1258               warnOrErr 
= "WARNING"; 
1260             else if (strncmp("threads:", str
, 8) == 0) { 
1261                 threadCount 
= atoi(str 
+ 8); 
1263             else if (strncmp("prop:", str
, 5) == 0) { 
1264                 if (nProps 
< IntlTest::kMaxProps
) { 
1265                     props
[nProps
] = str 
+ 5; 
1277     if (!all 
&& !name
) { 
1279     } else if (all 
&& name
) { 
1286                 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n" 
1288                 "### Options are: verbose (v), all (a), noerrormsg (n), \n" 
1289                 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n" 
1290                 "### notime (T), \n" 
1291                 "### threads:<threadCount>\n" 
1292                 "###     (The default thread count is 12.),\n" 
1293                 "### (Specify either -all (shortcut -a) or a test name). \n" 
1294                 "### -all will run all of the tests.\n" 
1296                 "### To get a list of the test names type: intltest LIST \n" 
1297                 "### To run just the utility tests type: intltest utility \n" 
1299                 "### Test names can be nested using slashes (\"testA/subtest1\") \n" 
1300                 "### For example to list the utility tests type: intltest utility/LIST \n" 
1301                 "### To run just the Locale test type: intltest utility/LocaleTest \n" 
1303                 "### A parameter can be specified for a test by appending '@' and the value \n" 
1304                 "### to the testname. \n\n"); 
1308     if (nProps 
> IntlTest::kMaxProps
) { 
1309         fprintf(stdout
, "### Too many properties.  Exiting.\n"); 
1312     MajorTestLevel major
; 
1313     major
.setVerbose( verbose 
); 
1314     major
.setNoErrMsg( no_err_msg 
); 
1315     major
.setQuick( quick 
); 
1316     major
.setLeaks( leaks 
); 
1317     major
.setThreadCount( threadCount 
); 
1318     major
.setWarnOnMissingData( warnOnMissingData 
); 
1319     major
.setNotime (no_time
); 
1320     for (int32_t i 
= 0; i 
< nProps
; i
++) { 
1321         major
.setProperty(props
[i
]); 
1325     fprintf(stdout
, "-----------------------------------------------\n"); 
1326     fprintf(stdout
, " IntlTest (C++) Test Suite for                 \n"); 
1327     fprintf(stdout
, "   International Components for Unicode %s\n", U_ICU_VERSION
); 
1331         const char *charsetFamily 
= "Unknown"; 
1332         int32_t voidSize 
= (int32_t)sizeof(void*); 
1333         int32_t bits 
= voidSize 
* 8; 
1334         if(U_CHARSET_FAMILY
==U_ASCII_FAMILY
) { 
1335            charsetFamily
="ASCII"; 
1336         } else if(U_CHARSET_FAMILY
==U_EBCDIC_FAMILY
) { 
1337            charsetFamily
="EBCDIC"; 
1340                     "   Bits: %d, Byte order: %s, Chars: %s\n", 
1341                      bits
, U_IS_BIG_ENDIAN
?"Big endian":"Little endian", 
1344     fprintf(stdout
, "-----------------------------------------------\n"); 
1345     fprintf(stdout
, " Options:                                       \n"); 
1346     fprintf(stdout
, "   all (a)                  : %s\n", (all
?               "On" : "Off")); 
1347     fprintf(stdout
, "   Verbose (v)              : %s\n", (verbose
?           "On" : "Off")); 
1348     fprintf(stdout
, "   No error messages (n)    : %s\n", (no_err_msg
?        "On" : "Off")); 
1349     fprintf(stdout
, "   Exhaustive (e)           : %s\n", (!quick
?            "On" : "Off")); 
1350     fprintf(stdout
, "   Leaks (l)                : %s\n", (leaks
?             "On" : "Off")); 
1351     fprintf(stdout
, "   utf-8 (u)                : %s\n", (utf8
?              "On" : "Off")); 
1352     fprintf(stdout
, "   notime (T)               : %s\n", (no_time
?             "On" : "Off")); 
1353     fprintf(stdout
, "   noknownissues (K)        : %s\n", (noKnownIssues
?      "On" : "Off")); 
1354     fprintf(stdout
, "   Warn on missing data (w) : %s\n", (warnOnMissingData
? "On" : "Off")); 
1355     fprintf(stdout
, "   Threads                  : %d\n", threadCount
); 
1356     for (int32_t i 
= 0; i 
< nProps
; i
++) { 
1357         fprintf(stdout
, "   Custom property (prop:)  : %s\n", props
[i
]); 
1359     fprintf(stdout
, "-----------------------------------------------\n"); 
1362       ucnv_setDefaultName("utf-8"); 
1364     /* Check whether ICU will initialize without forcing the build data directory into 
1365      *  the ICU_DATA path.  Success here means either the data dll contains data, or that 
1366      *  this test program was run with ICU_DATA set externally.  Failure of this check 
1367      *  is normal when ICU data is not packaged into a shared library. 
1369      *  Whether or not this test succeeds, we want to cleanup and reinitialize 
1370      *  with a data path so that data loading from individual files can be tested. 
1373     if (U_FAILURE(errorCode
)) { 
1375             "#### Note:  ICU Init without build-specific setDataDirectory() failed.\n"); 
1376         defaultDataFound 
= FALSE
; 
1379         defaultDataFound 
= TRUE
; 
1383       ucnv_setDefaultName("utf-8"); 
1385     errorCode 
= U_ZERO_ERROR
; 
1387     /* Initialize ICU */ 
1388     if (!defaultDataFound
) { 
1389         IntlTest::setICU_DATA();   // Must set data directory before u_init() is called. 
1392     if (U_FAILURE(errorCode
)) { 
1394             "#### ERROR! %s: u_init() failed with status = \"%s\".\n" 
1395             "*** Check the ICU_DATA environment variable and \n" 
1396             "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
)); 
1397             if(warnOnMissingData 
== 0) { 
1398                 fprintf(stderr
, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n"); 
1404     // initial check for the default converter 
1405     errorCode 
= U_ZERO_ERROR
; 
1406     cnv 
= ucnv_open(0, &errorCode
); 
1412                 "*** %s! The default converter [%s] cannot be opened.\n" 
1413                 "*** Check the ICU_DATA environment variable and\n" 
1414                 "*** check that the data files are present.\n", 
1415                 warnOrErr
, ucnv_getDefaultName()); 
1416         if(!warnOnMissingData
) { 
1417           fprintf(stdout
, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n"); 
1423     cnv 
= ucnv_open(TRY_CNV_2
, &errorCode
); 
1429                 "*** %s! The converter for " TRY_CNV_2 
" cannot be opened.\n" 
1430                 "*** Check the ICU_DATA environment variable and \n" 
1431                 "*** check that the data files are present.\n", warnOrErr
); 
1432         if(!warnOnMissingData
) { 
1433           fprintf(stdout
, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n"); 
1438     UResourceBundle 
*rb 
= ures_open(0, "en", &errorCode
); 
1440     if(U_FAILURE(errorCode
)) { 
1442                 "*** %s! The \"en\" locale resource bundle cannot be opened.\n" 
1443                 "*** Check the ICU_DATA environment variable and \n" 
1444                 "*** check that the data files are present.\n", warnOrErr
); 
1445         if(!warnOnMissingData
) { 
1446           fprintf(stdout
, "*** Exiting.  Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n"); 
1451     Locale originalLocale
;  // Save the default locale for comparison later on. 
1453     if(ctest_xml_init("intltest"))  
1457     /* TODO: Add option to call u_cleanup and rerun tests. */ 
1461             major
.run_phase2( NULL
, NULL 
); 
1464         for (int i 
= 1; i 
< argc
; ++i
) { 
1465             if (argv
[i
][0] != '-') { 
1466                 char* name 
= argv
[i
]; 
1467                 fprintf(stdout
, "\n=== Handling test: %s: ===\n", name
); 
1469                 char baseName
[1024]; 
1470                 sprintf(baseName
, "/%s/", name
); 
1472                 char* parameter 
= strchr( name
, '@' ); 
1478                 UBool res 
= major
.runTest( name
, parameter
, baseName 
); 
1480                     major
.run_phase2( name
, parameter 
); 
1482                 if (!res 
|| (execCount 
<= 0)) { 
1483                     fprintf(stdout
, "\n---ERROR: Test doesn't exist: %s!\n", name
); 
1485             } else if(!strcmp(argv
[i
],"-x")) { 
1492 #if !UCONFIG_NO_FORMATTING 
1493     CalendarTimeZoneTest::cleanup(); 
1496     free(_testDataPath
); 
1499     Locale lastDefaultLocale
; 
1500     if (originalLocale 
!= lastDefaultLocale
) { 
1501         major
.errln("FAILURE: A test changed the default locale without resetting it."); 
1504     fprintf(stdout
, "\n--------------------------------------\n"); 
1505     if( major
.printKnownIssues() ) { 
1506       fprintf(stdout
, " To run suppressed tests, use the -K option. \n"); 
1508     if (major
.getErrors() == 0) { 
1509         /* Call it twice to make sure that the defaults were reset. */ 
1510         /* Call it before the OK message to verify proper cleanup. */ 
1514         fprintf(stdout
, "OK: All tests passed without error.\n"); 
1516         if (major
.getDataErrors() != 0) { 
1517             fprintf(stdout
, "\t*WARNING* some data-loading errors were ignored by the -w option.\n"); 
1520         fprintf(stdout
, "Errors in total: %ld.\n", (long)major
.getErrors()); 
1521         major
.printErrors(); 
1523         if(summary_file 
!= NULL
) { 
1524           FILE *summf 
= fopen(summary_file
, "w"); 
1525           if( summf 
!= NULL
) { 
1527             int32_t length 
= errorList
.extract(0, errorList
.length(), buf
, sizeof(buf
)); 
1528             fwrite(buf
, sizeof(*buf
), length
, (FILE*)summf
); 
1534         if (major
.getDataErrors() != 0) { 
1535             fprintf(stdout
, "\t*Note* some errors are data-loading related. If the data used is not the \n" 
1536                     "\tstock ICU data (i.e some have been added or removed), consider using\n" 
1537                     "\tthe '-w' option to turn these errors into warnings.\n"); 
1540         /* Call afterwards to display errors. */ 
1544 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS 
1545     unistr_printLengths(); 
1548     fprintf(stdout
, "--------------------------------------\n"); 
1550     if (execCount 
<= 0) { 
1551         fprintf(stdout
, "***** Not all called tests actually exist! *****\n"); 
1554       endTime 
= uprv_getRawUTCtime(); 
1555       diffTime 
= (int32_t)(endTime 
- startTime
); 
1556       printf("Elapsed Time: %02d:%02d:%02d.%03d\n", 
1557              (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
), 
1558              (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
), 
1559              (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
), 
1560              (int)(diffTime%U_MILLIS_PER_SECOND
)); 
1563     if(ctest_xml_fini()) 
1566     return major
.getErrors(); 
1569 const char* IntlTest::loadTestData(UErrorCode
& err
){ 
1570     if( _testDataPath 
== NULL
){ 
1571         const char*      directory
=NULL
; 
1572         UResourceBundle
* test 
=NULL
; 
1574         const char* tdrelativepath
; 
1576 #if defined (U_TOPBUILDDIR) 
1577         tdrelativepath 
= "test" U_FILE_SEP_STRING 
"testdata" U_FILE_SEP_STRING 
"out" U_FILE_SEP_STRING
; 
1578         directory 
= U_TOPBUILDDIR
; 
1580         tdrelativepath 
= ".." U_FILE_SEP_STRING 
"test" U_FILE_SEP_STRING 
"testdata" U_FILE_SEP_STRING 
"out" U_FILE_SEP_STRING
; 
1581         directory 
= pathToDataDirectory(); 
1584         tdpath 
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100)); 
1587         /* u_getDataDirectory shoul return \source\data ... set the 
1588          * directory to ..\source\data\..\test\testdata\out\testdata 
1590         strcpy(tdpath
, directory
); 
1591         strcat(tdpath
, tdrelativepath
); 
1592         strcat(tdpath
,"testdata"); 
1594         test
=ures_open(tdpath
, "testtypes", &err
); 
1597             err 
= U_FILE_ACCESS_ERROR
; 
1598             it_dataerrln((UnicodeString
)"Could not load testtypes.res in testdata bundle with path " + tdpath 
+ (UnicodeString
)" - " + u_errorName(err
)); 
1602         _testDataPath 
= tdpath
; 
1603         return _testDataPath
; 
1605     return _testDataPath
; 
1608 const char* IntlTest::getTestDataPath(UErrorCode
& err
) { 
1609     return loadTestData(err
); 
1612 /* Returns the path to icu/source/test/testdata/ */ 
1613 const char *IntlTest::getSourceTestData(UErrorCode
& /*err*/) { 
1614     const char *srcDataDir 
= NULL
; 
1616     srcDataDir 
= U_TOPSRCDIR U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING 
"testdata" U_FILE_SEP_STRING
; 
1618     srcDataDir 
= ".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
"test" U_FILE_SEP_STRING 
"testdata" U_FILE_SEP_STRING
; 
1619     FILE *f 
= fopen(".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
"test" U_FILE_SEP_STRING 
"testdata" U_FILE_SEP_STRING 
"rbbitst.txt", "r"); 
1621         /* We're in icu/source/test/intltest/ */ 
1625         /* We're in icu/source/test/intltest/Platform/(Debug|Release) */ 
1626         srcDataDir 
= ".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING
 
1627                      "test" U_FILE_SEP_STRING 
"testdata" U_FILE_SEP_STRING
; 
1633 char *IntlTest::getUnidataPath(char path
[]) { 
1634     const int kUnicodeDataTxtLength 
= 15;  // strlen("UnicodeData.txt") 
1636     // Look inside ICU_DATA first. 
1637     strcpy(path
, pathToDataDirectory()); 
1638     strcat(path
, "unidata" U_FILE_SEP_STRING 
"UnicodeData.txt"); 
1639     FILE *f 
= fopen(path
, "r"); 
1642         *(strchr(path
, 0) - kUnicodeDataTxtLength
) = 0;  // Remove the basename. 
1646     // As a fallback, try to guess where the source data was located 
1647     // at the time ICU was built, and look there. 
1649         strcpy(path
, U_TOPSRCDIR  U_FILE_SEP_STRING 
"data"); 
1651         UErrorCode errorCode 
= U_ZERO_ERROR
; 
1652         const char *testDataPath 
= loadTestData(errorCode
); 
1653         if(U_FAILURE(errorCode
)) { 
1654             it_errln(UnicodeString( 
1655                         "unable to find path to source/data/unidata/ and loadTestData() failed: ") + 
1656                     u_errorName(errorCode
)); 
1659         strcpy(path
, testDataPath
); 
1660         strcat(path
, U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
".." 
1661                      U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
".." 
1662                      U_FILE_SEP_STRING 
"data"); 
1664     strcat(path
, U_FILE_SEP_STRING
); 
1665     strcat(path
, "unidata" U_FILE_SEP_STRING 
"UnicodeData.txt"); 
1666     f 
= fopen(path
, "r"); 
1669         *(strchr(path
, 0) - kUnicodeDataTxtLength
) = 0;  // Remove the basename. 
1675 const char* IntlTest::fgDataDir 
= NULL
; 
1677 /* returns the path to icu/source/data */ 
1678 const char *  IntlTest::pathToDataDirectory() 
1681     if(fgDataDir 
!= NULL
) { 
1685     /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst 
1686     //              to point to the top of the build hierarchy, which may or 
1687     //              may not be the same as the source directory, depending on 
1688     //              the configure options used.  At any rate, 
1689     //              set the data path to the built data from this directory. 
1690     //              The value is complete with quotes, so it can be used 
1691     //              as-is as a string constant. 
1693 #if defined (U_TOPSRCDIR) 
1695         fgDataDir 
= U_TOPSRCDIR  U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING
; 
1699     /* On Windows, the file name obtained from __FILE__ includes a full path. 
1700      *             This file is "wherever\icu\source\test\cintltst\cintltst.c" 
1701      *             Change to    "wherever\icu\source\data" 
1704         static char p
[sizeof(__FILE__
) + 10]; 
1708         strcpy(p
, __FILE__
); 
1709         /* We want to back over three '\' chars.                            */ 
1710         /*   Only Windows should end up here, so looking for '\' is safe.   */ 
1711         for (i
=1; i
<=3; i
++) { 
1712             pBackSlash 
= strrchr(p
, U_FILE_SEP_CHAR
); 
1713             if (pBackSlash 
!= NULL
) { 
1714                 *pBackSlash 
= 0;        /* Truncate the string at the '\'   */ 
1718         if (pBackSlash 
!= NULL
) { 
1719             /* We found and truncated three names from the path. 
1720             *  Now append "source\data" and set the environment 
1722             strcpy(pBackSlash
, U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING 
); 
1726             /* __FILE__ on MSVC7 does not contain the directory */ 
1727             FILE *file 
= fopen(".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING 
"Makefile.in", "r"); 
1730                 fgDataDir 
= ".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING
; 
1733                 fgDataDir 
= ".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
".." U_FILE_SEP_STRING 
"data" U_FILE_SEP_STRING
; 
1744  * This is a variant of cintltst/ccolltst.c:CharsToUChars(). 
1745  * It converts an invariant-character string into a UnicodeString, with 
1746  * unescaping \u sequences. 
1748 UnicodeString 
CharsToUnicodeString(const char* chars
){ 
1749     return UnicodeString(chars
, -1, US_INV
).unescape(); 
1752 UnicodeString 
ctou(const char* chars
) { 
1753     return CharsToUnicodeString(chars
); 
1756 #define RAND_M  (714025) 
1757 #define RAND_IA (1366) 
1758 #define RAND_IC (150889) 
1760 static int32_t RAND_SEED
; 
1763  * Returns a uniform random value x, with 0.0 <= x < 1.0.  Use 
1764  * with care: Does not return all possible values; returns one of 
1765  * 714,025 values, uniformly spaced.  However, the period is 
1766  * effectively infinite.  See: Numerical Recipes, section 7.1. 
1768  * @param seedp pointer to seed. Set *seedp to any negative value 
1769  * to restart the sequence. 
1771 float IntlTest::random(int32_t* seedp
) { 
1772     static int32_t iy
, ir
[98]; 
1773     static UBool first
=TRUE
; 
1775     if (*seedp 
< 0 || first
) { 
1777         if ((*seedp
=(RAND_IC
-(*seedp
)) % RAND_M
) < 0) *seedp 
= -(*seedp
); 
1778         for (j
=1;j
<=97;++j
) { 
1779             *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
; 
1782         *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
; 
1785     j
=(int32_t)(1 + 97.0*iy
/RAND_M
); 
1786     U_ASSERT(j
>=1 && j
<=97); 
1788     *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
; 
1790     return (float) iy
/RAND_M
; 
1794  * Convenience method using a global seed. 
1796 float IntlTest::random() { 
1797     return random(&RAND_SEED
); 
1802  * Integer random number class implementation. 
1803  * Similar to C++ std::minstd_rand, with the same algorithm & constants. 
1805 IntlTest::icu_rand::icu_rand(uint32_t seed
) { 
1806     seed 
= seed 
% 2147483647UL; 
1813 IntlTest::icu_rand::~icu_rand() {} 
1815 void IntlTest::icu_rand::seed(uint32_t seed
) { 
1822 uint32_t IntlTest::icu_rand::operator() () { 
1823     fLast 
= ((uint64_t)fLast 
* 48271UL) % 2147483647UL; 
1827 uint32_t IntlTest::icu_rand::getSeed() { 
1828     return (uint32_t) fLast
; 
1833 static inline UChar 
toHex(int32_t i
) { 
1834     return (UChar
)(i 
+ (i 
< 10 ? 0x30 : (0x41 - 10))); 
1837 static UnicodeString
& escape(const UnicodeString
& s
, UnicodeString
& result
) { 
1838     for (int32_t i
=0; i
<s
.length(); ++i
) { 
1840         if (c 
<= (UChar
)0x7F) { 
1843             result 
+= (UChar
)0x5c; 
1844             result 
+= (UChar
)0x75; 
1845             result 
+= toHex((c 
>> 12) & 0xF); 
1846             result 
+= toHex((c 
>>  8) & 0xF); 
1847             result 
+= toHex((c 
>>  4) & 0xF); 
1848             result 
+= toHex( c        
& 0xF); 
1854 #define VERBOSE_ASSERTIONS 
1856 UBool 
IntlTest::assertTrue(const char* message
, UBool condition
, UBool quiet
, UBool possibleDataError
, const char *file
, int line
) { 
1859             if (possibleDataError
) { 
1860                 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
); 
1862                 errln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
); 
1864         } else if (!quiet
) { 
1865             logln("%s:%d: Ok: %s", file
, line
, message
); 
1869             if (possibleDataError
) { 
1870                 dataerrln("FAIL: assertTrue() failed: %s", message
); 
1872                 errln("FAIL: assertTrue() failed: %s", message
); 
1874         } else if (!quiet
) { 
1875             logln("Ok: %s", message
); 
1882 UBool 
IntlTest::assertFalse(const char* message
, UBool condition
, UBool quiet
) { 
1884         errln("FAIL: assertFalse() failed: %s", message
); 
1885     } else if (!quiet
) { 
1886         logln("Ok: %s", message
); 
1891 UBool 
IntlTest::assertSuccess(const char* message
, UErrorCode ec
, UBool possibleDataError
, const char *file
, int line
) { 
1893       file 
= ""; // prevent failure if no file given 
1895     if (U_FAILURE(ec
)) { 
1896         if (possibleDataError
) { 
1897           dataerrln("FAIL: %s:%d: %s (%s)", file
, line
, message
, u_errorName(ec
)); 
1899           errcheckln(ec
, "FAIL: %s:%d: %s (%s)", file
, line
, message
, u_errorName(ec
)); 
1903       logln("OK: %s:%d: %s - (%s)", file
, line
, message
, u_errorName(ec
)); 
1908 UBool 
IntlTest::assertEquals(const char* message
, 
1909                              const UnicodeString
& expected
, 
1910                              const UnicodeString
& actual
, 
1911                              UBool possibleDataError
) { 
1912     if (expected 
!= actual
) { 
1913         if (possibleDataError
) { 
1914             dataerrln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
1916                   "; expected " + prettify(expected
)); 
1918             errln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
1920                   "; expected " + prettify(expected
)); 
1924 #ifdef VERBOSE_ASSERTIONS 
1926         logln((UnicodeString
)"Ok: " + message 
+ "; got " + prettify(actual
)); 
1932 UBool 
IntlTest::assertEquals(const char* message
, 
1933                              const char* expected
, 
1934                              const char* actual
) { 
1935     if (uprv_strcmp(expected
, actual
) != 0) { 
1936         errln((UnicodeString
)"FAIL: " + message 
+ "; got \"" + 
1938               "\"; expected \"" + expected 
+ "\""); 
1941 #ifdef VERBOSE_ASSERTIONS 
1943         logln((UnicodeString
)"Ok: " + message 
+ "; got \"" + actual 
+ "\""); 
1949 UBool 
IntlTest::assertEquals(const char* message
, 
1952     if (expected 
!= actual
) { 
1953         errln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
1954               actual 
+ "=0x" + toHex(actual
) + 
1955               "; expected " + expected 
+ "=0x" + toHex(expected
)); 
1958 #ifdef VERBOSE_ASSERTIONS 
1960         logln((UnicodeString
)"Ok: " + message 
+ "; got " + actual 
+ "=0x" + toHex(actual
)); 
1966 UBool 
IntlTest::assertEquals(const char* message
, 
1969     if (expected 
!= actual
) { 
1970         errln((UnicodeString
)"FAIL: " + message 
+ "; got int64 " + 
1971               Int64ToUnicodeString(actual
) +  
1972               "; expected " + Int64ToUnicodeString(expected
) ); 
1975 #ifdef VERBOSE_ASSERTIONS 
1977       logln((UnicodeString
)"Ok: " + message 
+ "; got int64 " + Int64ToUnicodeString(actual
)); 
1983 UBool 
IntlTest::assertEquals(const char* message
, 
1986     if (expected 
!= actual
) { 
1987         errln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
1989               "; expected " + expected
); 
1992 #ifdef VERBOSE_ASSERTIONS 
1994         logln((UnicodeString
)"Ok: " + message 
+ "; got " + actual
); 
2001 UBool 
IntlTest::assertEquals(const char* message
, 
2004     if (expected 
!= actual
) { 
2005         errln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
2007               "; expected " + toString(expected
)); 
2010 #ifdef VERBOSE_ASSERTIONS 
2012       logln((UnicodeString
)"Ok: " + message 
+ "; got " + toString(actual
)); 
2018 #if !UCONFIG_NO_FORMATTING 
2019 UBool 
IntlTest::assertEquals(const char* message
, 
2020                              const Formattable
& expected
, 
2021                              const Formattable
& actual
, 
2022                              UBool possibleDataError
) { 
2023     if (expected 
!= actual
) { 
2024         if (possibleDataError
) { 
2025             dataerrln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
2027                   "; expected " + toString(expected
)); 
2029             errln((UnicodeString
)"FAIL: " + message 
+ "; got " + 
2031                   "; expected " + toString(expected
)); 
2035 #ifdef VERBOSE_ASSERTIONS 
2037         logln((UnicodeString
)"Ok: " + message 
+ "; got " + toString(actual
)); 
2044 static char ASSERT_BUF
[256]; 
2046 static const char* extractToAssertBuf(const UnicodeString
& message
) { 
2048     escape(message
, buf
); 
2049     buf
.extract(0, 0x7FFFFFFF, ASSERT_BUF
, sizeof(ASSERT_BUF
)-1, 0); 
2050     ASSERT_BUF
[sizeof(ASSERT_BUF
)-1] = 0; 
2054 UBool 
IntlTest::assertTrue(const UnicodeString
& message
, UBool condition
, UBool quiet
) { 
2055     return assertTrue(extractToAssertBuf(message
), condition
, quiet
); 
2058 UBool 
IntlTest::assertFalse(const UnicodeString
& message
, UBool condition
, UBool quiet
) { 
2059     return assertFalse(extractToAssertBuf(message
), condition
, quiet
); 
2062 UBool 
IntlTest::assertSuccess(const UnicodeString
& message
, UErrorCode ec
) { 
2063     return assertSuccess(extractToAssertBuf(message
), ec
); 
2066 UBool 
IntlTest::assertEquals(const UnicodeString
& message
, 
2067                              const UnicodeString
& expected
, 
2068                              const UnicodeString
& actual
, 
2069                              UBool possibleDataError
) { 
2070     return assertEquals(extractToAssertBuf(message
), expected
, actual
, possibleDataError
); 
2073 UBool 
IntlTest::assertEquals(const UnicodeString
& message
, 
2074                              const char* expected
, 
2075                              const char* actual
) { 
2076     return assertEquals(extractToAssertBuf(message
), expected
, actual
); 
2078 UBool 
IntlTest::assertEquals(const UnicodeString
& message
, 
2081     return assertEquals(extractToAssertBuf(message
), expected
, actual
); 
2083 UBool 
IntlTest::assertEquals(const UnicodeString
& message
, 
2086     return assertEquals(extractToAssertBuf(message
), expected
, actual
); 
2088 UBool 
IntlTest::assertEquals(const UnicodeString
& message
, 
2091     return assertEquals(extractToAssertBuf(message
), expected
, actual
); 
2094 #if !UCONFIG_NO_FORMATTING 
2095 UBool 
IntlTest::assertEquals(const UnicodeString
& message
, 
2096                              const Formattable
& expected
, 
2097                              const Formattable
& actual
) { 
2098     return assertEquals(extractToAssertBuf(message
), expected
, actual
); 
2102 void IntlTest::setProperty(const char* propline
) { 
2103     if (numProps 
< kMaxProps
) { 
2104         proplines
[numProps
] = propline
; 
2109 const char* IntlTest::getProperty(const char* prop
) { 
2110     const char* val 
= NULL
; 
2111     for (int32_t i 
= 0; i 
< numProps
; i
++) { 
2112         int32_t plen 
= uprv_strlen(prop
); 
2113         if ((int32_t)uprv_strlen(proplines
[i
]) > plen 
+ 1 
2114                 && proplines
[i
][plen
] == '=' 
2115                 && uprv_strncmp(proplines
[i
], prop
, plen
) == 0) { 
2116             val 
= &(proplines
[i
][plen
+1]); 
2124  * Hey, Emacs, please set the following: 
2127  * indent-tabs-mode: nil