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
UCharToUnicodeString(UChar c)62 UCharToUnicodeString(UChar c)
63 { return UnicodeString(c); }
64 
65 // [rtg] Just to get things working
66 UnicodeString
operator +(const UnicodeString & left,long num)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
operator +(const UnicodeString & left,unsigned long num)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
Int64ToUnicodeString(int64_t num)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
operator +(const UnicodeString & left,double num)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  */
_toString(const Formattable & f)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  */
toString(const Formattable & f)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
toString(int32_t n)214 UnicodeString toString(int32_t n) {
215     return UnicodeString() + (long)n;
216 }
217 
218 
219 
toString(UBool b)220 UnicodeString toString(UBool b) {
221   return b ? UnicodeString("TRUE"):UnicodeString("FALSE");
222 }
223 
224 // stephen - cleaned up 05/05/99
operator +(const UnicodeString & left,char num)225 UnicodeString operator+(const UnicodeString& left, char num)
226 { return left + (long)num; }
operator +(const UnicodeString & left,short num)227 UnicodeString operator+(const UnicodeString& left, short num)
228 { return left + (long)num; }
operator +(const UnicodeString & left,int num)229 UnicodeString operator+(const UnicodeString& left, int num)
230 { return left + (long)num; }
operator +(const UnicodeString & left,unsigned char num)231 UnicodeString operator+(const UnicodeString& left, unsigned char num)
232 { return left + (unsigned long)num; }
operator +(const UnicodeString & left,unsigned short num)233 UnicodeString operator+(const UnicodeString& left, unsigned short num)
234 { return left + (unsigned long)num; }
operator +(const UnicodeString & left,unsigned int num)235 UnicodeString operator+(const UnicodeString& left, unsigned int num)
236 { return left + (unsigned long)num; }
operator +(const UnicodeString & left,float 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&
appendHex(uint32_t number,int32_t digits,UnicodeString & target)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
toHex(uint32_t number,int32_t digits)287 IntlTest::toHex(uint32_t number, int32_t digits) {
288     UnicodeString result;
289     appendHex(number, digits, result);
290     return result;
291 }
292 
isPrintable(UChar32 c)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&
prettify(const UnicodeString & source,UnicodeString & target)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
prettify(const UnicodeString & source,UBool parseBackslash)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  */
setICU_DATA()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 
it_log(UnicodeString message)469 void it_log( UnicodeString message )
470 {
471     if (IntlTest::gTest)
472         IntlTest::gTest->log( message );
473 }
474 
it_logln(UnicodeString message)475 void it_logln( UnicodeString message )
476 {
477     if (IntlTest::gTest)
478         IntlTest::gTest->logln( message );
479 }
480 
it_logln(void)481 void it_logln( void )
482 {
483     if (IntlTest::gTest)
484         IntlTest::gTest->logln();
485 }
486 
it_info(UnicodeString message)487 void it_info( UnicodeString message )
488 {
489     if (IntlTest::gTest)
490         IntlTest::gTest->info( message );
491 }
492 
it_infoln(UnicodeString message)493 void it_infoln( UnicodeString message )
494 {
495     if (IntlTest::gTest)
496         IntlTest::gTest->infoln( message );
497 }
498 
it_infoln(void)499 void it_infoln( void )
500 {
501     if (IntlTest::gTest)
502         IntlTest::gTest->infoln();
503 }
504 
it_err()505 void it_err()
506 {
507     if (IntlTest::gTest)
508         IntlTest::gTest->err();
509 }
510 
it_err(UnicodeString message)511 void it_err( UnicodeString message )
512 {
513     if (IntlTest::gTest)
514         IntlTest::gTest->err( message );
515 }
516 
it_errln(UnicodeString message)517 void it_errln( UnicodeString message )
518 {
519     if (IntlTest::gTest)
520         IntlTest::gTest->errln( message );
521 }
522 
it_dataerr(UnicodeString message)523 void it_dataerr( UnicodeString message )
524 {
525     if (IntlTest::gTest)
526         IntlTest::gTest->dataerr( message );
527 }
528 
it_dataerrln(UnicodeString message)529 void it_dataerrln( UnicodeString message )
530 {
531     if (IntlTest::gTest)
532         IntlTest::gTest->dataerrln( message );
533 }
534 
IntlTest()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 
setCaller(IntlTest * callingTest)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 
callTest(IntlTest & testToBeCalled,char * par)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 
setPath(char * pathVal)583 void IntlTest::setPath( char* pathVal )
584 {
585     this->testPath = pathVal;
586 }
587 
setVerbose(UBool verboseVal)588 UBool IntlTest::setVerbose( UBool verboseVal )
589 {
590     UBool rval = this->verbose;
591     this->verbose = verboseVal;
592     return rval;
593 }
594 
setNotime(UBool no_time)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 
setWarnOnMissingData(UBool warn_on_missing_dataVal)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 
setNoErrMsg(UBool no_err_msgVal)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 
setQuick(UBool quickVal)616 UBool IntlTest::setQuick( UBool quickVal )
617 {
618     UBool rval = this->quick;
619     this->quick = quickVal;
620     return rval;
621 }
622 
setLeaks(UBool leaksVal)623 UBool IntlTest::setLeaks( UBool leaksVal )
624 {
625     UBool rval = this->leaks;
626     this->leaks = leaksVal;
627     return rval;
628 }
629 
setThreadCount(int32_t count)630 int32_t IntlTest::setThreadCount( int32_t count )
631 {
632     int32_t rval = this->threadCount;
633     this->threadCount = count;
634     return rval;
635 }
636 
getErrors(void)637 int32_t IntlTest::getErrors( void )
638 {
639     return errorCount;
640 }
641 
getDataErrors(void)642 int32_t IntlTest::getDataErrors( void )
643 {
644     return dataErrorCount;
645 }
646 
runTest(char * name,char * par,char * baseName)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
runIndexedTest(int32_t,UBool,const char * &,char *)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 
runTestLoop(char * testname,char * par,char * baseName)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 */
log(const UnicodeString & message)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 */
logln(const UnicodeString & message)819 void IntlTest::logln( const UnicodeString &message )
820 {
821     if( verbose ) {
822         LL_message( message, TRUE );
823     }
824 }
825 
logln(void)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 */
info(const UnicodeString & message)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 */
infoln(const UnicodeString & message)845 void IntlTest::infoln( const UnicodeString &message )
846 {
847   LL_message( message, TRUE );
848 }
849 
infoln(void)850 void IntlTest::infoln( void )
851 {
852   LL_message( "", TRUE );
853 }
854 
IncErrorCount(void)855 int32_t IntlTest::IncErrorCount( void )
856 {
857     errorCount++;
858     if (caller) caller->IncErrorCount();
859     return errorCount;
860 }
861 
IncDataErrorCount(void)862 int32_t IntlTest::IncDataErrorCount( void )
863 {
864     dataErrorCount++;
865     if (caller) caller->IncDataErrorCount();
866     return dataErrorCount;
867 }
868 
err()869 void IntlTest::err()
870 {
871     IncErrorCount();
872 }
873 
err(const UnicodeString & message)874 void IntlTest::err( const UnicodeString &message )
875 {
876     IncErrorCount();
877     if (!no_err_msg) LL_message( message, FALSE );
878 }
879 
errln(const UnicodeString & message)880 void IntlTest::errln( const UnicodeString &message )
881 {
882     IncErrorCount();
883     if (!no_err_msg) LL_message( message, TRUE );
884 }
885 
dataerr(const UnicodeString & message)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 
dataerrln(const UnicodeString & message)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 
errcheckln(UErrorCode status,const UnicodeString & message)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 */
log(const char * fmt,...)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 
logln(const char * fmt,...)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 
logKnownIssue(const char * ticket,const char * fmt,...)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 
logKnownIssue(const char * ticket)966 UBool IntlTest::logKnownIssue(const char *ticket) {
967   return logKnownIssue(ticket, UnicodeString());
968 }
969 
logKnownIssue(const char * ticket,const UnicodeString & msg)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 */
info(const char * fmt,...)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 
infoln(const char * fmt,...)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 
err(const char * fmt,...)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 
errln(const char * fmt,...)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 
dataerrln(const char * fmt,...)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 
errcheckln(UErrorCode status,const char * fmt,...)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 
printErrors()1065 void IntlTest::printErrors()
1066 {
1067      IntlTest::LL_message(errorList, TRUE);
1068 }
1069 
printKnownIssues()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 
LL_message(UnicodeString message,UBool newline)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 */
usage(void)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
run_phase2(char * name,char * par)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
main(int argc,char * argv[])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 
loadTestData(UErrorCode & err)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 
getTestDataPath(UErrorCode & err)1587 const char* IntlTest::getTestDataPath(UErrorCode& err) {
1588     return loadTestData(err);
1589 }
1590 
1591 /* Returns the path to icu/source/test/testdata/ */
getSourceTestData(UErrorCode &)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
1606                      "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
1607     }
1608 #endif
1609     return srcDataDir;
1610 }
1611 
getUnidataPath(char path[])1612 char *IntlTest::getUnidataPath(char path[]) {
1613     const int kUnicodeDataTxtLength = 15;  // strlen("UnicodeData.txt")
1614 
1615     // Look inside ICU_DATA first.
1616     strcpy(path, pathToDataDirectory());
1617     strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
1618     FILE *f = fopen(path, "r");
1619     if(f != NULL) {
1620         fclose(f);
1621         *(strchr(path, 0) - kUnicodeDataTxtLength) = 0;  // Remove the basename.
1622         return path;
1623     }
1624 
1625     // As a fallback, try to guess where the source data was located
1626     // at the time ICU was built, and look there.
1627 #   ifdef U_TOPSRCDIR
1628         strcpy(path, U_TOPSRCDIR  U_FILE_SEP_STRING "data");
1629 #   else
1630         UErrorCode errorCode = U_ZERO_ERROR;
1631         const char *testDataPath = loadTestData(errorCode);
1632         if(U_FAILURE(errorCode)) {
1633             it_errln(UnicodeString(
1634                         "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
1635                     u_errorName(errorCode));
1636             return NULL;
1637         }
1638         strcpy(path, testDataPath);
1639         strcat(path, U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
1640                      U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
1641                      U_FILE_SEP_STRING "data");
1642 #   endif
1643     strcat(path, U_FILE_SEP_STRING);
1644     strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
1645     f = fopen(path, "r");
1646     if(f != NULL) {
1647         fclose(f);
1648         *(strchr(path, 0) - kUnicodeDataTxtLength) = 0;  // Remove the basename.
1649         return path;
1650     }
1651     return NULL;
1652 }
1653 
1654 const char* IntlTest::fgDataDir = NULL;
1655 
1656 /* returns the path to icu/source/data */
pathToDataDirectory()1657 const char *  IntlTest::pathToDataDirectory()
1658 {
1659 
1660     if(fgDataDir != NULL) {
1661         return fgDataDir;
1662     }
1663 
1664     /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
1665     //              to point to the top of the build hierarchy, which may or
1666     //              may not be the same as the source directory, depending on
1667     //              the configure options used.  At any rate,
1668     //              set the data path to the built data from this directory.
1669     //              The value is complete with quotes, so it can be used
1670     //              as-is as a string constant.
1671     */
1672 #if defined (U_TOPSRCDIR)
1673     {
1674         fgDataDir = U_TOPSRCDIR  U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
1675     }
1676 #else
1677 
1678     /* On Windows, the file name obtained from __FILE__ includes a full path.
1679      *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
1680      *             Change to    "wherever\icu\source\data"
1681      */
1682     {
1683         static char p[sizeof(__FILE__) + 10];
1684         char *pBackSlash;
1685         int i;
1686 
1687         strcpy(p, __FILE__);
1688         /* We want to back over three '\' chars.                            */
1689         /*   Only Windows should end up here, so looking for '\' is safe.   */
1690         for (i=1; i<=3; i++) {
1691             pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
1692             if (pBackSlash != NULL) {
1693                 *pBackSlash = 0;        /* Truncate the string at the '\'   */
1694             }
1695         }
1696 
1697         if (pBackSlash != NULL) {
1698             /* We found and truncated three names from the path.
1699             *  Now append "source\data" and set the environment
1700             */
1701             strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
1702             fgDataDir = p;
1703         }
1704         else {
1705             /* __FILE__ on MSVC7 does not contain the directory */
1706             FILE *file = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
1707             if (file) {
1708                 fclose(file);
1709                 fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
1710             }
1711             else {
1712                 fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
1713             }
1714         }
1715     }
1716 #endif
1717 
1718     return fgDataDir;
1719 
1720 }
1721 
1722 /*
1723  * This is a variant of cintltst/ccolltst.c:CharsToUChars().
1724  * It converts an invariant-character string into a UnicodeString, with
1725  * unescaping \u sequences.
1726  */
CharsToUnicodeString(const char * chars)1727 UnicodeString CharsToUnicodeString(const char* chars){
1728     return UnicodeString(chars, -1, US_INV).unescape();
1729 }
1730 
ctou(const char * chars)1731 UnicodeString ctou(const char* chars) {
1732     return CharsToUnicodeString(chars);
1733 }
1734 
1735 #define RAND_M  (714025)
1736 #define RAND_IA (1366)
1737 #define RAND_IC (150889)
1738 
1739 static int32_t RAND_SEED;
1740 
1741 /**
1742  * Returns a uniform random value x, with 0.0 <= x < 1.0.  Use
1743  * with care: Does not return all possible values; returns one of
1744  * 714,025 values, uniformly spaced.  However, the period is
1745  * effectively infinite.  See: Numerical Recipes, section 7.1.
1746  *
1747  * @param seedp pointer to seed. Set *seedp to any negative value
1748  * to restart the sequence.
1749  */
random(int32_t * seedp)1750 float IntlTest::random(int32_t* seedp) {
1751     static int32_t iy, ir[98];
1752     static UBool first=TRUE;
1753     int32_t j;
1754     if (*seedp < 0 || first) {
1755         first = FALSE;
1756         if ((*seedp=(RAND_IC-(*seedp)) % RAND_M) < 0) *seedp = -(*seedp);
1757         for (j=1;j<=97;++j) {
1758             *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1759             ir[j]=(*seedp);
1760         }
1761         *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1762         iy=(*seedp);
1763     }
1764     j=(int32_t)(1 + 97.0*iy/RAND_M);
1765     U_ASSERT(j>=1 && j<=97);
1766     iy=ir[j];
1767     *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1768     ir[j]=(*seedp);
1769     return (float) iy/RAND_M;
1770 }
1771 
1772 /**
1773  * Convenience method using a global seed.
1774  */
random()1775 float IntlTest::random() {
1776     return random(&RAND_SEED);
1777 }
1778 
toHex(int32_t i)1779 static inline UChar toHex(int32_t i) {
1780     return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10)));
1781 }
1782 
escape(const UnicodeString & s,UnicodeString & result)1783 static UnicodeString& escape(const UnicodeString& s, UnicodeString& result) {
1784     for (int32_t i=0; i<s.length(); ++i) {
1785         UChar c = s[i];
1786         if (c <= (UChar)0x7F) {
1787             result += c;
1788         } else {
1789             result += (UChar)0x5c;
1790             result += (UChar)0x75;
1791             result += toHex((c >> 12) & 0xF);
1792             result += toHex((c >>  8) & 0xF);
1793             result += toHex((c >>  4) & 0xF);
1794             result += toHex( c        & 0xF);
1795         }
1796     }
1797     return result;
1798 }
1799 
1800 #define VERBOSE_ASSERTIONS
1801 
assertTrue(const char * message,UBool condition,UBool quiet,UBool possibleDataError,const char * file,int line)1802 UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError, const char *file, int line) {
1803     if (file != NULL) {
1804         if (!condition) {
1805             if (possibleDataError) {
1806                 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
1807             } else {
1808                 errln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
1809             }
1810         } else if (!quiet) {
1811             logln("%s:%d: Ok: %s", file, line, message);
1812         }
1813     } else {
1814         if (!condition) {
1815             if (possibleDataError) {
1816                 dataerrln("FAIL: assertTrue() failed: %s", message);
1817             } else {
1818                 errln("FAIL: assertTrue() failed: %s", message);
1819             }
1820         } else if (!quiet) {
1821             logln("Ok: %s", message);
1822         }
1823 
1824     }
1825     return condition;
1826 }
1827 
assertFalse(const char * message,UBool condition,UBool quiet)1828 UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet) {
1829     if (condition) {
1830         errln("FAIL: assertFalse() failed: %s", message);
1831     } else if (!quiet) {
1832         logln("Ok: %s", message);
1833     }
1834     return !condition;
1835 }
1836 
assertSuccess(const char * message,UErrorCode ec,UBool possibleDataError,const char * file,int line)1837 UBool IntlTest::assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError, const char *file, int line) {
1838     if( file==NULL ) {
1839       file = ""; // prevent failure if no file given
1840     }
1841     if (U_FAILURE(ec)) {
1842         if (possibleDataError) {
1843           dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
1844         } else {
1845           errcheckln(ec, "FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
1846         }
1847         return FALSE;
1848     } else {
1849       logln("OK: %s:%d: %s - (%s)", file, line, message, u_errorName(ec));
1850     }
1851     return TRUE;
1852 }
1853 
assertEquals(const char * message,const UnicodeString & expected,const UnicodeString & actual,UBool possibleDataError)1854 UBool IntlTest::assertEquals(const char* message,
1855                              const UnicodeString& expected,
1856                              const UnicodeString& actual,
1857                              UBool possibleDataError) {
1858     if (expected != actual) {
1859         if (possibleDataError) {
1860             dataerrln((UnicodeString)"FAIL: " + message + "; got " +
1861                   prettify(actual) +
1862                   "; expected " + prettify(expected));
1863         } else {
1864             errln((UnicodeString)"FAIL: " + message + "; got " +
1865                   prettify(actual) +
1866                   "; expected " + prettify(expected));
1867         }
1868         return FALSE;
1869     }
1870 #ifdef VERBOSE_ASSERTIONS
1871     else {
1872         logln((UnicodeString)"Ok: " + message + "; got " + prettify(actual));
1873     }
1874 #endif
1875     return TRUE;
1876 }
1877 
assertEquals(const char * message,const char * expected,const char * actual)1878 UBool IntlTest::assertEquals(const char* message,
1879                              const char* expected,
1880                              const char* actual) {
1881     if (uprv_strcmp(expected, actual) != 0) {
1882         errln((UnicodeString)"FAIL: " + message + "; got \"" +
1883               actual +
1884               "\"; expected \"" + expected + "\"");
1885         return FALSE;
1886     }
1887 #ifdef VERBOSE_ASSERTIONS
1888     else {
1889         logln((UnicodeString)"Ok: " + message + "; got \"" + actual + "\"");
1890     }
1891 #endif
1892     return TRUE;
1893 }
1894 
assertEquals(const char * message,int32_t expected,int32_t actual)1895 UBool IntlTest::assertEquals(const char* message,
1896                              int32_t expected,
1897                              int32_t actual) {
1898     if (expected != actual) {
1899         errln((UnicodeString)"FAIL: " + message + "; got " +
1900               actual + "=0x" + toHex(actual) +
1901               "; expected " + expected + "=0x" + toHex(expected));
1902         return FALSE;
1903     }
1904 #ifdef VERBOSE_ASSERTIONS
1905     else {
1906         logln((UnicodeString)"Ok: " + message + "; got " + actual + "=0x" + toHex(actual));
1907     }
1908 #endif
1909     return TRUE;
1910 }
1911 
assertEquals(const char * message,int64_t expected,int64_t actual)1912 UBool IntlTest::assertEquals(const char* message,
1913                              int64_t expected,
1914                              int64_t actual) {
1915     if (expected != actual) {
1916         errln((UnicodeString)"FAIL: " + message + "; got int64 " +
1917               Int64ToUnicodeString(actual) +
1918               "; expected " + Int64ToUnicodeString(expected) );
1919         return FALSE;
1920     }
1921 #ifdef VERBOSE_ASSERTIONS
1922     else {
1923       logln((UnicodeString)"Ok: " + message + "; got int64 " + Int64ToUnicodeString(actual));
1924     }
1925 #endif
1926     return TRUE;
1927 }
1928 
assertEquals(const char * message,UBool expected,UBool actual)1929 UBool IntlTest::assertEquals(const char* message,
1930                              UBool expected,
1931                              UBool actual) {
1932     if (expected != actual) {
1933         errln((UnicodeString)"FAIL: " + message + "; got " +
1934               toString(actual) +
1935               "; expected " + toString(expected));
1936         return FALSE;
1937     }
1938 #ifdef VERBOSE_ASSERTIONS
1939     else {
1940       logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
1941     }
1942 #endif
1943     return TRUE;
1944 }
1945 
1946 #if !UCONFIG_NO_FORMATTING
assertEquals(const char * message,const Formattable & expected,const Formattable & actual,UBool possibleDataError)1947 UBool IntlTest::assertEquals(const char* message,
1948                              const Formattable& expected,
1949                              const Formattable& actual,
1950                              UBool possibleDataError) {
1951     if (expected != actual) {
1952         if (possibleDataError) {
1953             dataerrln((UnicodeString)"FAIL: " + message + "; got " +
1954                   toString(actual) +
1955                   "; expected " + toString(expected));
1956         } else {
1957             errln((UnicodeString)"FAIL: " + message + "; got " +
1958                   toString(actual) +
1959                   "; expected " + toString(expected));
1960         }
1961         return FALSE;
1962     }
1963 #ifdef VERBOSE_ASSERTIONS
1964     else {
1965         logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
1966     }
1967 #endif
1968     return TRUE;
1969 }
1970 #endif
1971 
1972 static char ASSERT_BUF[256];
1973 
extractToAssertBuf(const UnicodeString & message)1974 static const char* extractToAssertBuf(const UnicodeString& message) {
1975     UnicodeString buf;
1976     escape(message, buf);
1977     buf.extract(0, 0x7FFFFFFF, ASSERT_BUF, sizeof(ASSERT_BUF)-1, 0);
1978     ASSERT_BUF[sizeof(ASSERT_BUF)-1] = 0;
1979     return ASSERT_BUF;
1980 }
1981 
assertTrue(const UnicodeString & message,UBool condition,UBool quiet)1982 UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet) {
1983     return assertTrue(extractToAssertBuf(message), condition, quiet);
1984 }
1985 
assertFalse(const UnicodeString & message,UBool condition,UBool quiet)1986 UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet) {
1987     return assertFalse(extractToAssertBuf(message), condition, quiet);
1988 }
1989 
assertSuccess(const UnicodeString & message,UErrorCode ec)1990 UBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) {
1991     return assertSuccess(extractToAssertBuf(message), ec);
1992 }
1993 
assertEquals(const UnicodeString & message,const UnicodeString & expected,const UnicodeString & actual,UBool possibleDataError)1994 UBool IntlTest::assertEquals(const UnicodeString& message,
1995                              const UnicodeString& expected,
1996                              const UnicodeString& actual,
1997                              UBool possibleDataError) {
1998     return assertEquals(extractToAssertBuf(message), expected, actual, possibleDataError);
1999 }
2000 
assertEquals(const UnicodeString & message,const char * expected,const char * actual)2001 UBool IntlTest::assertEquals(const UnicodeString& message,
2002                              const char* expected,
2003                              const char* actual) {
2004     return assertEquals(extractToAssertBuf(message), expected, actual);
2005 }
assertEquals(const UnicodeString & message,UBool expected,UBool actual)2006 UBool IntlTest::assertEquals(const UnicodeString& message,
2007                              UBool expected,
2008                              UBool actual) {
2009     return assertEquals(extractToAssertBuf(message), expected, actual);
2010 }
assertEquals(const UnicodeString & message,int32_t expected,int32_t actual)2011 UBool IntlTest::assertEquals(const UnicodeString& message,
2012                              int32_t expected,
2013                              int32_t actual) {
2014     return assertEquals(extractToAssertBuf(message), expected, actual);
2015 }
assertEquals(const UnicodeString & message,int64_t expected,int64_t actual)2016 UBool IntlTest::assertEquals(const UnicodeString& message,
2017                              int64_t expected,
2018                              int64_t actual) {
2019     return assertEquals(extractToAssertBuf(message), expected, actual);
2020 }
2021 
2022 #if !UCONFIG_NO_FORMATTING
assertEquals(const UnicodeString & message,const Formattable & expected,const Formattable & actual)2023 UBool IntlTest::assertEquals(const UnicodeString& message,
2024                              const Formattable& expected,
2025                              const Formattable& actual) {
2026     return assertEquals(extractToAssertBuf(message), expected, actual);
2027 }
2028 #endif
2029 
setProperty(const char * propline)2030 void IntlTest::setProperty(const char* propline) {
2031     if (numProps < kMaxProps) {
2032         proplines[numProps] = propline;
2033     }
2034     numProps++;
2035 }
2036 
getProperty(const char * prop)2037 const char* IntlTest::getProperty(const char* prop) {
2038     const char* val = NULL;
2039     for (int32_t i = 0; i < numProps; i++) {
2040         int32_t plen = uprv_strlen(prop);
2041         if ((int32_t)uprv_strlen(proplines[i]) > plen + 1
2042                 && proplines[i][plen] == '='
2043                 && uprv_strncmp(proplines[i], prop, plen) == 0) {
2044             val = &(proplines[i][plen+1]);
2045             break;
2046         }
2047     }
2048     return val;
2049 }
2050 
2051 /*
2052  * Hey, Emacs, please set the following:
2053  *
2054  * Local Variables:
2055  * indent-tabs-mode: nil
2056  * End:
2057  *
2058  */
2059