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