]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/intltest.cpp
ICU-62135.0.1.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
A
595 testoutfp = caller->testoutfp;
596 LL_indentlevel = caller->LL_indentlevel + indentLevel_offset;
729e4ab9
A
597 numProps = caller->numProps;
598 for (int32_t i = 0; i < numProps; i++) {
599 proplines[i] = caller->proplines[i];
600 }
b75a7d8f
A
601 }
602}
603
604UBool IntlTest::callTest( IntlTest& testToBeCalled, char* par )
605{
606 execCount--; // correct a previously assumed test-exec, as this only calls a subtest
607 testToBeCalled.setCaller( this );
729e4ab9
A
608 strcpy(testToBeCalled.basePath, this->basePath );
609 UBool result = testToBeCalled.runTest( testPath, par, testToBeCalled.basePath );
610 strcpy(testToBeCalled.basePath, this->basePath ); // reset it.
611 return result;
b75a7d8f
A
612}
613
614void IntlTest::setPath( char* pathVal )
615{
73c04bcf 616 this->testPath = pathVal;
b75a7d8f
A
617}
618
619UBool IntlTest::setVerbose( UBool verboseVal )
620{
621 UBool rval = this->verbose;
622 this->verbose = verboseVal;
623 return rval;
624}
625
51004dcb
A
626UBool IntlTest::setNotime( UBool no_time )
627{
628 UBool rval = this->no_time;
629 this->no_time = no_time;
630 return rval;
631}
632
73c04bcf
A
633UBool IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal )
634{
635 UBool rval = this->warn_on_missing_data;
636 this->warn_on_missing_data = warn_on_missing_dataVal;
637 return rval;
638}
639
b75a7d8f
A
640UBool IntlTest::setNoErrMsg( UBool no_err_msgVal )
641{
642 UBool rval = this->no_err_msg;
643 this->no_err_msg = no_err_msgVal;
644 return rval;
645}
646
647UBool IntlTest::setQuick( UBool quickVal )
648{
649 UBool rval = this->quick;
650 this->quick = quickVal;
651 return rval;
652}
653
654UBool IntlTest::setLeaks( UBool leaksVal )
655{
656 UBool rval = this->leaks;
657 this->leaks = leaksVal;
658 return rval;
659}
660
729e4ab9
A
661int32_t IntlTest::setThreadCount( int32_t count )
662{
663 int32_t rval = this->threadCount;
664 this->threadCount = count;
665 return rval;
666}
667
b75a7d8f
A
668int32_t IntlTest::getErrors( void )
669{
670 return errorCount;
671}
672
73c04bcf
A
673int32_t IntlTest::getDataErrors( void )
674{
675 return dataErrorCount;
676}
677
729e4ab9 678UBool IntlTest::runTest( char* name, char* par, char *baseName )
b75a7d8f
A
679{
680 UBool rval;
681 char* pos = NULL;
682
729e4ab9
A
683 char* baseNameBuffer = NULL;
684
685 if(baseName == NULL) {
686 baseNameBuffer = (char*)malloc(1024);
687 baseName=baseNameBuffer;
688 strcpy(baseName, "/");
689 }
690
b75a7d8f
A
691 if (name)
692 pos = strchr( name, delim ); // check if name contains path (by looking for '/')
693 if (pos) {
73c04bcf 694 testPath = pos+1; // store subpath for calling subtest
b75a7d8f
A
695 *pos = 0; // split into two strings
696 }else{
73c04bcf 697 testPath = NULL;
b75a7d8f
A
698 }
699
700 if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
729e4ab9 701 rval = runTestLoop( NULL, par, baseName );
b75a7d8f
A
702
703 }else if (strcmp( name, "LIST" ) == 0) {
704 this->usage();
705 rval = TRUE;
706
707 }else{
729e4ab9 708 rval = runTestLoop( name, par, baseName );
b75a7d8f
A
709 }
710
711 if (pos)
712 *pos = delim; // restore original value at pos
729e4ab9
A
713 if(baseNameBuffer!=NULL) {
714 free(baseNameBuffer);
715 }
b75a7d8f
A
716 return rval;
717}
718
0f5d89e8 719// call individual tests, to be overridden to call implementations
51004dcb 720void IntlTest::runIndexedTest( int32_t /*index*/, UBool /*exec*/, const char* & /*name*/, char* /*par*/ )
b75a7d8f 721{
0f5d89e8 722 // to be overridden by a method like:
b75a7d8f
A
723 /*
724 switch (index) {
725 case 0: name = "First Test"; if (exec) FirstTest( par ); break;
726 case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
727 default: name = ""; break;
728 }
729 */
0f5d89e8 730 this->errln("*** runIndexedTest needs to be overridden! ***");
b75a7d8f
A
731}
732
733
729e4ab9 734UBool IntlTest::runTestLoop( char* testname, char* par, char *baseName )
b75a7d8f
A
735{
736 int32_t index = 0;
737 const char* name;
738 UBool run_this_test;
739 int32_t lastErrorCount;
740 UBool rval = FALSE;
741 UBool lastTestFailed;
742
729e4ab9
A
743 if(baseName == NULL) {
744 printf("ERROR: baseName can't be null.\n");
745 return FALSE;
746 } else {
747 if ((char *)this->basePath != baseName) {
748 strcpy(this->basePath, baseName);
749 }
750 }
751
752 char * saveBaseLoc = baseName+strlen(baseName);
753
b75a7d8f
A
754 IntlTest* saveTest = gTest;
755 gTest = this;
756 do {
374ca955 757 this->runIndexedTest( index, FALSE, name, par );
729e4ab9
A
758 if (strcmp(name,"skip") == 0) {
759 run_this_test = FALSE;
760 } else {
761 if (!name || (name[0] == 0))
762 break;
763 if (!testname) {
764 run_this_test = TRUE;
765 }else{
766 run_this_test = (UBool) (strcmp( name, testname ) == 0);
767 }
b75a7d8f
A
768 }
769 if (run_this_test) {
770 lastErrorCount = errorCount;
771 execCount++;
729e4ab9
A
772 char msg[256];
773 sprintf(msg, "%s {", name);
774 LL_message(msg, TRUE);
775 UDate timeStart = uprv_getRawUTCtime();
776 strcpy(saveBaseLoc,name);
777 strcat(saveBaseLoc,"/");
778
57a6839d 779 strcpy(currName, name); // set
b75a7d8f 780 this->runIndexedTest( index, TRUE, name, par );
57a6839d 781 currName[0]=0; // reset
729e4ab9
A
782
783 UDate timeStop = uprv_getRawUTCtime();
b75a7d8f 784 rval = TRUE; // at least one test has been called
729e4ab9 785 char secs[256];
51004dcb
A
786 if(!no_time) {
787 sprintf(secs, "%f", (timeStop-timeStart)/1000.0);
788 } else {
789 secs[0]=0;
790 }
729e4ab9
A
791
792
793 strcpy(saveBaseLoc,name);
794
795
796 ctest_xml_testcase(baseName, name, secs, (lastErrorCount!=errorCount)?"err":NULL);
797
798
799 saveBaseLoc[0]=0; /* reset path */
800
b75a7d8f 801 if (lastErrorCount == errorCount) {
729e4ab9 802 sprintf( msg, " } OK: %s ", name );
51004dcb 803 if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
b75a7d8f
A
804 lastTestFailed = FALSE;
805 }else{
729e4ab9 806 sprintf(msg, " } ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name);
51004dcb 807 if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
b75a7d8f
A
808
809 for(int i=0;i<LL_indentlevel;i++) {
810 errorList += " ";
811 }
812 errorList += name;
813 errorList += "\n";
814 lastTestFailed = TRUE;
815 }
816 LL_indentlevel -= 3;
817 if (lastTestFailed) {
818 LL_message( "", TRUE);
819 }
820 LL_message( msg, TRUE);
821 if (lastTestFailed) {
822 LL_message( "", TRUE);
823 }
824 LL_indentlevel += 3;
825 }
826 index++;
827 }while(name);
828
729e4ab9
A
829 *saveBaseLoc = 0;
830
b75a7d8f
A
831 gTest = saveTest;
832 return rval;
833}
834
835
836/**
837* Adds given string to the log if we are in verbose mode.
838*/
839void IntlTest::log( const UnicodeString &message )
840{
841 if( verbose ) {
842 LL_message( message, FALSE );
843 }
844}
845
846/**
847* Adds given string to the log if we are in verbose mode. Adds a new line to
848* the given message.
849*/
850void IntlTest::logln( const UnicodeString &message )
851{
852 if( verbose ) {
853 LL_message( message, TRUE );
854 }
855}
856
857void IntlTest::logln( void )
858{
859 if( verbose ) {
860 LL_message( "", TRUE );
861 }
862}
863
864/**
865* Unconditionally adds given string to the log.
866*/
867void IntlTest::info( const UnicodeString &message )
868{
869 LL_message( message, FALSE );
870}
871
872/**
873* Unconditionally adds given string to the log. Adds a new line to
874* the given message.
875*/
876void IntlTest::infoln( const UnicodeString &message )
877{
878 LL_message( message, TRUE );
879}
880
881void IntlTest::infoln( void )
882{
883 LL_message( "", TRUE );
884}
885
886int32_t IntlTest::IncErrorCount( void )
887{
888 errorCount++;
889 if (caller) caller->IncErrorCount();
890 return errorCount;
891}
892
73c04bcf
A
893int32_t IntlTest::IncDataErrorCount( void )
894{
895 dataErrorCount++;
896 if (caller) caller->IncDataErrorCount();
897 return dataErrorCount;
898}
899
900void IntlTest::err()
901{
b75a7d8f
A
902 IncErrorCount();
903}
904
905void IntlTest::err( const UnicodeString &message )
906{
907 IncErrorCount();
908 if (!no_err_msg) LL_message( message, FALSE );
909}
910
911void IntlTest::errln( const UnicodeString &message )
912{
913 IncErrorCount();
914 if (!no_err_msg) LL_message( message, TRUE );
915}
916
73c04bcf
A
917void IntlTest::dataerr( const UnicodeString &message )
918{
919 IncDataErrorCount();
920
921 if (!warn_on_missing_data) {
922 IncErrorCount();
923 }
924
925 if (!no_err_msg) LL_message( message, FALSE );
926}
927
928void IntlTest::dataerrln( const UnicodeString &message )
929{
57a6839d 930 int32_t errCount = IncDataErrorCount();
729e4ab9 931 UnicodeString msg;
73c04bcf
A
932 if (!warn_on_missing_data) {
933 IncErrorCount();
729e4ab9
A
934 msg = message;
935 } else {
936 msg = UnicodeString("[DATA] " + message);
73c04bcf
A
937 }
938
57a6839d
A
939 if (!no_err_msg) {
940 if ( errCount == 1) {
941 LL_message( msg + " - (Are you missing data?)", TRUE ); // only show this message the first time
942 } else {
943 LL_message( msg , TRUE );
944 }
945 }
729e4ab9
A
946}
947
948void IntlTest::errcheckln(UErrorCode status, const UnicodeString &message ) {
949 if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
950 dataerrln(message);
951 } else {
952 errln(message);
953 }
73c04bcf
A
954}
955
b75a7d8f
A
956/* convenience functions that include sprintf formatting */
957void IntlTest::log(const char *fmt, ...)
958{
374ca955 959 char buffer[4000];
b75a7d8f
A
960 va_list ap;
961
962 va_start(ap, fmt);
963 /* sprintf it just to make sure that the information is valid */
964 vsprintf(buffer, fmt, ap);
965 va_end(ap);
966 if( verbose ) {
2ca993e8 967 log(UnicodeString(buffer, (const char *)NULL));
b75a7d8f
A
968 }
969}
970
971void IntlTest::logln(const char *fmt, ...)
972{
374ca955 973 char buffer[4000];
b75a7d8f
A
974 va_list ap;
975
976 va_start(ap, fmt);
977 /* sprintf it just to make sure that the information is valid */
978 vsprintf(buffer, fmt, ap);
979 va_end(ap);
980 if( verbose ) {
2ca993e8 981 logln(UnicodeString(buffer, (const char *)NULL));
b75a7d8f
A
982 }
983}
984
57a6839d
A
985UBool IntlTest::logKnownIssue(const char *ticket, const char *fmt, ...)
986{
987 char buffer[4000];
988 va_list ap;
989
990 va_start(ap, fmt);
991 /* sprintf it just to make sure that the information is valid */
992 vsprintf(buffer, fmt, ap);
993 va_end(ap);
2ca993e8 994 return logKnownIssue(ticket, UnicodeString(buffer, (const char *)NULL));
57a6839d
A
995}
996
997UBool IntlTest::logKnownIssue(const char *ticket) {
998 return logKnownIssue(ticket, UnicodeString());
999}
1000
1001UBool IntlTest::logKnownIssue(const char *ticket, const UnicodeString &msg) {
1002 if(noKnownIssues) return FALSE;
1003
1004 char fullpath[2048];
1005 strcpy(fullpath, basePath);
1006 strcat(fullpath, currName);
2ca993e8
A
1007 UnicodeString msg2 = msg;
1008 UBool firstForTicket = TRUE, firstForWhere = TRUE;
57a6839d
A
1009 knownList = udbg_knownIssue_openU(knownList, ticket, fullpath, msg2.getTerminatedBuffer(), &firstForTicket, &firstForWhere);
1010
b331163b
A
1011 msg2 = UNICODE_STRING_SIMPLE("(Known issue #") +
1012 UnicodeString(ticket, -1, US_INV) + UNICODE_STRING_SIMPLE(") ") + msg;
57a6839d 1013 if(firstForTicket || firstForWhere) {
b331163b 1014 infoln(msg2);
57a6839d 1015 } else {
b331163b 1016 logln(msg2);
57a6839d
A
1017 }
1018
1019 return TRUE;
1020}
1021
b75a7d8f
A
1022/* convenience functions that include sprintf formatting */
1023void IntlTest::info(const char *fmt, ...)
1024{
374ca955 1025 char buffer[4000];
b75a7d8f
A
1026 va_list ap;
1027
1028 va_start(ap, fmt);
1029 /* sprintf it just to make sure that the information is valid */
1030 vsprintf(buffer, fmt, ap);
1031 va_end(ap);
2ca993e8 1032 info(UnicodeString(buffer, (const char *)NULL));
b75a7d8f
A
1033}
1034
1035void IntlTest::infoln(const char *fmt, ...)
1036{
374ca955 1037 char buffer[4000];
b75a7d8f
A
1038 va_list ap;
1039
1040 va_start(ap, fmt);
1041 /* sprintf it just to make sure that the information is valid */
1042 vsprintf(buffer, fmt, ap);
1043 va_end(ap);
2ca993e8 1044 infoln(UnicodeString(buffer, (const char *)NULL));
b75a7d8f
A
1045}
1046
1047void IntlTest::err(const char *fmt, ...)
1048{
374ca955 1049 char buffer[4000];
b75a7d8f
A
1050 va_list ap;
1051
1052 va_start(ap, fmt);
1053 vsprintf(buffer, fmt, ap);
1054 va_end(ap);
2ca993e8 1055 err(UnicodeString(buffer, (const char *)NULL));
b75a7d8f
A
1056}
1057
1058void IntlTest::errln(const char *fmt, ...)
1059{
374ca955 1060 char buffer[4000];
b75a7d8f
A
1061 va_list ap;
1062
1063 va_start(ap, fmt);
1064 vsprintf(buffer, fmt, ap);
1065 va_end(ap);
2ca993e8 1066 errln(UnicodeString(buffer, (const char *)NULL));
b75a7d8f
A
1067}
1068
73c04bcf
A
1069void IntlTest::dataerrln(const char *fmt, ...)
1070{
1071 char buffer[4000];
1072 va_list ap;
1073
1074 va_start(ap, fmt);
1075 vsprintf(buffer, fmt, ap);
1076 va_end(ap);
2ca993e8 1077 dataerrln(UnicodeString(buffer, (const char *)NULL));
73c04bcf
A
1078}
1079
729e4ab9
A
1080void IntlTest::errcheckln(UErrorCode status, const char *fmt, ...)
1081{
1082 char buffer[4000];
1083 va_list ap;
1084
1085 va_start(ap, fmt);
1086 vsprintf(buffer, fmt, ap);
1087 va_end(ap);
1088
1089 if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
2ca993e8 1090 dataerrln(UnicodeString(buffer, (const char *)NULL));
729e4ab9 1091 } else {
2ca993e8 1092 errln(UnicodeString(buffer, (const char *)NULL));
729e4ab9
A
1093 }
1094}
1095
b75a7d8f
A
1096void IntlTest::printErrors()
1097{
1098 IntlTest::LL_message(errorList, TRUE);
1099}
1100
57a6839d
A
1101UBool IntlTest::printKnownIssues()
1102{
1103 if(knownList != NULL) {
1104 udbg_knownIssue_print(knownList);
1105 udbg_knownIssue_close(knownList);
1106 return TRUE;
1107 } else {
1108 return FALSE;
1109 }
1110}
1111
2ca993e8
A
1112static UMutex messageMutex = U_MUTEX_INITIALIZER;
1113
b75a7d8f
A
1114void IntlTest::LL_message( UnicodeString message, UBool newline )
1115{
2ca993e8
A
1116 // Synchronize this function.
1117 // All error messages generated by tests funnel through here.
0f5d89e8 1118 // Multithreaded tests can concurrently generate errors, requiring synchronization
2ca993e8
A
1119 // to keep each message together.
1120 Mutex lock(&messageMutex);
1121
b75a7d8f
A
1122 // string that starts with a LineFeed character and continues
1123 // with spaces according to the current indentation
1124 static const UChar indentUChars[] = {
1125 '\n',
1126 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1127 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1128 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1129 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1130 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1131 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1132 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1133 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
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 };
2ca993e8 1137 U_ASSERT(1 + LL_indentlevel <= UPRV_LENGTHOF(indentUChars));
b75a7d8f
A
1138 UnicodeString indent(FALSE, indentUChars, 1 + LL_indentlevel);
1139
57a6839d 1140 char buffer[30000];
b75a7d8f
A
1141 int32_t length;
1142
1143 // stream out the indentation string first if necessary
1144 length = indent.extract(1, indent.length(), buffer, sizeof(buffer));
1145 if (length > 0) {
374ca955 1146 fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
b75a7d8f
A
1147 }
1148
1149 // replace each LineFeed by the indentation string
1150 message.findAndReplace(UnicodeString((UChar)'\n'), indent);
1151
1152 // stream out the message
1153 length = message.extract(0, message.length(), buffer, sizeof(buffer));
1154 if (length > 0) {
57a6839d 1155 length = length > 30000 ? 30000 : length;
374ca955 1156 fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
b75a7d8f
A
1157 }
1158
1159 if (newline) {
1160 char newLine = '\n';
374ca955 1161 fwrite(&newLine, sizeof(newLine), 1, (FILE *)testoutfp);
b75a7d8f
A
1162 }
1163
1164 // A newline usually flushes the buffer, but
1165 // flush the message just in case of a core dump.
374ca955 1166 fflush((FILE *)testoutfp);
b75a7d8f
A
1167}
1168
1169/**
1170* Print a usage message for this test class.
1171*/
1172void IntlTest::usage( void )
1173{
1174 UBool save_verbose = setVerbose( TRUE );
1175 logln("Test names:");
1176 logln("-----------");
1177
1178 int32_t index = 0;
1179 const char* name = NULL;
1180 do{
1181 this->runIndexedTest( index, FALSE, name );
1182 if (!name) break;
1183 logln(name);
1184 index++;
1185 }while (name && (name[0] != 0));
1186 setVerbose( save_verbose );
1187}
1188
1189
1190// memory leak reporting software will be able to take advantage of the testsuite
1191// being run a second time local to a specific method in order to report only actual leaks
1192UBool
1193IntlTest::run_phase2( char* name, char* par ) // supports reporting memory leaks
1194{
1195 UnicodeString* strLeak = new UnicodeString("forced leak"); // for verifying purify filter
1196 strLeak->append(" for verifying purify filter");
1197 return this->runTest( name, par );
1198}
1199
1200
1201#if UCONFIG_NO_LEGACY_CONVERSION
1202# define TRY_CNV_1 "iso-8859-1"
1203# define TRY_CNV_2 "ibm-1208"
1204#else
1205# define TRY_CNV_1 "iso-8859-7"
1206# define TRY_CNV_2 "sjis"
1207#endif
1208
2ca993e8
A
1209#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
1210U_CAPI void unistr_printLengths();
1211#endif
1212
b75a7d8f
A
1213int
1214main(int argc, char* argv[])
1215{
1216 UBool syntax = FALSE;
374ca955 1217 UBool all = FALSE;
b75a7d8f
A
1218 UBool verbose = FALSE;
1219 UBool no_err_msg = FALSE;
51004dcb 1220 UBool no_time = FALSE;
b75a7d8f
A
1221 UBool quick = TRUE;
1222 UBool name = FALSE;
1223 UBool leaks = FALSE;
57a6839d
A
1224 UBool utf8 = FALSE;
1225 const char *summary_file = NULL;
b75a7d8f 1226 UBool warnOnMissingData = FALSE;
73c04bcf 1227 UBool defaultDataFound = FALSE;
2ca993e8 1228 int32_t threadCount = 12;
b75a7d8f
A
1229 UErrorCode errorCode = U_ZERO_ERROR;
1230 UConverter *cnv = NULL;
374ca955 1231 const char *warnOrErr = "Failure";
73c04bcf
A
1232 UDate startTime, endTime;
1233 int32_t diffTime;
729e4ab9
A
1234 const char *props[IntlTest::kMaxProps];
1235 int32_t nProps = 0;
b75a7d8f 1236
73c04bcf 1237 U_MAIN_INIT_ARGS(argc, argv);
374ca955 1238
729e4ab9 1239 startTime = uprv_getRawUTCtime();
b75a7d8f
A
1240
1241 for (int i = 1; i < argc; ++i) {
1242 if (argv[i][0] == '-') {
1243 const char* str = argv[i] + 1;
374ca955
A
1244 if (strcmp("verbose", str) == 0 ||
1245 strcmp("v", str) == 0)
b75a7d8f 1246 verbose = TRUE;
374ca955
A
1247 else if (strcmp("noerrormsg", str) == 0 ||
1248 strcmp("n", str) == 0)
b75a7d8f 1249 no_err_msg = TRUE;
374ca955
A
1250 else if (strcmp("exhaustive", str) == 0 ||
1251 strcmp("e", str) == 0)
b75a7d8f 1252 quick = FALSE;
374ca955
A
1253 else if (strcmp("all", str) == 0 ||
1254 strcmp("a", str) == 0)
b75a7d8f 1255 all = TRUE;
57a6839d
A
1256 else if (strcmp("utf-8", str) == 0 ||
1257 strcmp("u", str) == 0)
1258 utf8 = TRUE;
1259 else if (strcmp("noknownissues", str) == 0 ||
1260 strcmp("K", str) == 0)
1261 noKnownIssues = TRUE;
374ca955
A
1262 else if (strcmp("leaks", str) == 0 ||
1263 strcmp("l", str) == 0)
b75a7d8f 1264 leaks = TRUE;
51004dcb
A
1265 else if (strcmp("notime", str) == 0 ||
1266 strcmp("T", str) == 0)
1267 no_time = TRUE;
57a6839d
A
1268 else if (strncmp("E", str, 1) == 0)
1269 summary_file = str+1;
729e4ab9
A
1270 else if (strcmp("x", str)==0) {
1271 if(++i>=argc) {
1272 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
1273 syntax = TRUE;
1274 }
1275 if(ctest_xml_setFileName(argv[i])) { /* set the name */
1276 return 1; /* error */
1277 }
1278 } else if (strcmp("w", str) == 0) {
b75a7d8f
A
1279 warnOnMissingData = TRUE;
1280 warnOrErr = "WARNING";
374ca955 1281 }
729e4ab9
A
1282 else if (strncmp("threads:", str, 8) == 0) {
1283 threadCount = atoi(str + 8);
1284 }
1285 else if (strncmp("prop:", str, 5) == 0) {
1286 if (nProps < IntlTest::kMaxProps) {
1287 props[nProps] = str + 5;
1288 }
1289 nProps++;
1290 }
374ca955 1291 else {
b75a7d8f
A
1292 syntax = TRUE;
1293 }
1294 }else{
1295 name = TRUE;
b75a7d8f
A
1296 }
1297 }
1298
374ca955
A
1299 if (!all && !name) {
1300 all = TRUE;
1301 } else if (all && name) {
1302 syntax = TRUE;
1303 }
b75a7d8f
A
1304
1305 if (syntax) {
1306 fprintf(stdout,
1307 "### Syntax:\n"
1308 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
729e4ab9
A
1309 "### \n"
1310 "### Options are: verbose (v), all (a), noerrormsg (n), \n"
1311 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
51004dcb 1312 "### notime (T), \n"
2ca993e8
A
1313 "### threads:<threadCount>\n"
1314 "### (The default thread count is 12.),\n"
b75a7d8f
A
1315 "### (Specify either -all (shortcut -a) or a test name). \n"
1316 "### -all will run all of the tests.\n"
1317 "### \n"
1318 "### To get a list of the test names type: intltest LIST \n"
1319 "### To run just the utility tests type: intltest utility \n"
1320 "### \n"
1321 "### Test names can be nested using slashes (\"testA/subtest1\") \n"
1322 "### For example to list the utility tests type: intltest utility/LIST \n"
1323 "### To run just the Locale test type: intltest utility/LocaleTest \n"
1324 "### \n"
1325 "### A parameter can be specified for a test by appending '@' and the value \n"
1326 "### to the testname. \n\n");
1327 return 1;
1328 }
1329
729e4ab9
A
1330 if (nProps > IntlTest::kMaxProps) {
1331 fprintf(stdout, "### Too many properties. Exiting.\n");
1332 }
1333
b75a7d8f
A
1334 MajorTestLevel major;
1335 major.setVerbose( verbose );
1336 major.setNoErrMsg( no_err_msg );
1337 major.setQuick( quick );
1338 major.setLeaks( leaks );
729e4ab9 1339 major.setThreadCount( threadCount );
73c04bcf 1340 major.setWarnOnMissingData( warnOnMissingData );
51004dcb 1341 major.setNotime (no_time);
729e4ab9
A
1342 for (int32_t i = 0; i < nProps; i++) {
1343 major.setProperty(props[i]);
1344 }
1345
1346
b75a7d8f
A
1347 fprintf(stdout, "-----------------------------------------------\n");
1348 fprintf(stdout, " IntlTest (C++) Test Suite for \n");
1349 fprintf(stdout, " International Components for Unicode %s\n", U_ICU_VERSION);
729e4ab9
A
1350
1351
1352 {
1353 const char *charsetFamily = "Unknown";
1354 int32_t voidSize = (int32_t)sizeof(void*);
1355 int32_t bits = voidSize * 8;
1356 if(U_CHARSET_FAMILY==U_ASCII_FAMILY) {
1357 charsetFamily="ASCII";
1358 } else if(U_CHARSET_FAMILY==U_EBCDIC_FAMILY) {
1359 charsetFamily="EBCDIC";
1360 }
1361 fprintf(stdout,
1362 " Bits: %d, Byte order: %s, Chars: %s\n",
1363 bits, U_IS_BIG_ENDIAN?"Big endian":"Little endian",
1364 charsetFamily);
1365 }
b75a7d8f
A
1366 fprintf(stdout, "-----------------------------------------------\n");
1367 fprintf(stdout, " Options: \n");
73c04bcf
A
1368 fprintf(stdout, " all (a) : %s\n", (all? "On" : "Off"));
1369 fprintf(stdout, " Verbose (v) : %s\n", (verbose? "On" : "Off"));
1370 fprintf(stdout, " No error messages (n) : %s\n", (no_err_msg? "On" : "Off"));
1371 fprintf(stdout, " Exhaustive (e) : %s\n", (!quick? "On" : "Off"));
1372 fprintf(stdout, " Leaks (l) : %s\n", (leaks? "On" : "Off"));
57a6839d 1373 fprintf(stdout, " utf-8 (u) : %s\n", (utf8? "On" : "Off"));
51004dcb 1374 fprintf(stdout, " notime (T) : %s\n", (no_time? "On" : "Off"));
57a6839d 1375 fprintf(stdout, " noknownissues (K) : %s\n", (noKnownIssues? "On" : "Off"));
73c04bcf 1376 fprintf(stdout, " Warn on missing data (w) : %s\n", (warnOnMissingData? "On" : "Off"));
729e4ab9 1377 fprintf(stdout, " Threads : %d\n", threadCount);
729e4ab9
A
1378 for (int32_t i = 0; i < nProps; i++) {
1379 fprintf(stdout, " Custom property (prop:) : %s\n", props[i]);
1380 }
b75a7d8f
A
1381 fprintf(stdout, "-----------------------------------------------\n");
1382
57a6839d
A
1383 if(utf8) {
1384 ucnv_setDefaultName("utf-8");
1385 }
73c04bcf
A
1386 /* Check whether ICU will initialize without forcing the build data directory into
1387 * the ICU_DATA path. Success here means either the data dll contains data, or that
1388 * this test program was run with ICU_DATA set externally. Failure of this check
1389 * is normal when ICU data is not packaged into a shared library.
1390 *
1391 * Whether or not this test succeeds, we want to cleanup and reinitialize
1392 * with a data path so that data loading from individual files can be tested.
1393 */
1394 u_init(&errorCode);
1395 if (U_FAILURE(errorCode)) {
1396 fprintf(stderr,
1397 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
1398 defaultDataFound = FALSE;
1399 }
1400 else {
1401 defaultDataFound = TRUE;
1402 }
1403 u_cleanup();
57a6839d
A
1404 if(utf8) {
1405 ucnv_setDefaultName("utf-8");
1406 }
b75a7d8f 1407 errorCode = U_ZERO_ERROR;
73c04bcf
A
1408
1409 /* Initialize ICU */
1410 if (!defaultDataFound) {
1411 IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
1412 }
b75a7d8f
A
1413 u_init(&errorCode);
1414 if (U_FAILURE(errorCode)) {
73c04bcf
A
1415 fprintf(stderr,
1416 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
1417 "*** Check the ICU_DATA environment variable and \n"
1418 "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
1419 if(warnOnMissingData == 0) {
1420 fprintf(stderr, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1421 u_cleanup();
1422 return 1;
1423 }
b75a7d8f
A
1424 }
1425
b75a7d8f
A
1426 // initial check for the default converter
1427 errorCode = U_ZERO_ERROR;
1428 cnv = ucnv_open(0, &errorCode);
1429 if(cnv != 0) {
1430 // ok
1431 ucnv_close(cnv);
1432 } else {
1433 fprintf(stdout,
1434 "*** %s! The default converter [%s] cannot be opened.\n"
1435 "*** Check the ICU_DATA environment variable and\n"
1436 "*** check that the data files are present.\n",
1437 warnOrErr, ucnv_getDefaultName());
1438 if(!warnOnMissingData) {
374ca955 1439 fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
b75a7d8f
A
1440 return 1;
1441 }
1442 }
1443
1444 // try more data
1445 cnv = ucnv_open(TRY_CNV_2, &errorCode);
1446 if(cnv != 0) {
1447 // ok
1448 ucnv_close(cnv);
1449 } else {
1450 fprintf(stdout,
1451 "*** %s! The converter for " TRY_CNV_2 " cannot be opened.\n"
1452 "*** Check the ICU_DATA environment variable and \n"
1453 "*** check that the data files are present.\n", warnOrErr);
1454 if(!warnOnMissingData) {
374ca955 1455 fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
b75a7d8f
A
1456 return 1;
1457 }
1458 }
1459
1460 UResourceBundle *rb = ures_open(0, "en", &errorCode);
1461 ures_close(rb);
1462 if(U_FAILURE(errorCode)) {
1463 fprintf(stdout,
1464 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
1465 "*** Check the ICU_DATA environment variable and \n"
1466 "*** check that the data files are present.\n", warnOrErr);
1467 if(!warnOnMissingData) {
374ca955 1468 fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
b75a7d8f
A
1469 return 1;
1470 }
1471 }
1472
73c04bcf
A
1473 Locale originalLocale; // Save the default locale for comparison later on.
1474
729e4ab9
A
1475 if(ctest_xml_init("intltest"))
1476 return 1;
1477
1478
b75a7d8f
A
1479 /* TODO: Add option to call u_cleanup and rerun tests. */
1480 if (all) {
1481 major.runTest();
1482 if (leaks) {
1483 major.run_phase2( NULL, NULL );
1484 }
1485 }else{
1486 for (int i = 1; i < argc; ++i) {
1487 if (argv[i][0] != '-') {
1488 char* name = argv[i];
1489 fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
729e4ab9
A
1490
1491 char baseName[1024];
1492 sprintf(baseName, "/%s/", name);
1493
b75a7d8f
A
1494 char* parameter = strchr( name, '@' );
1495 if (parameter) {
1496 *parameter = 0;
1497 parameter += 1;
1498 }
1499 execCount = 0;
729e4ab9 1500 UBool res = major.runTest( name, parameter, baseName );
b75a7d8f
A
1501 if (leaks && res) {
1502 major.run_phase2( name, parameter );
1503 }
1504 if (!res || (execCount <= 0)) {
1505 fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
b75a7d8f 1506 }
729e4ab9
A
1507 } else if(!strcmp(argv[i],"-x")) {
1508 i++;
b75a7d8f
A
1509 }
1510 }
1511 }
1512
729e4ab9 1513
b75a7d8f
A
1514#if !UCONFIG_NO_FORMATTING
1515 CalendarTimeZoneTest::cleanup();
1516#endif
1517
1518 free(_testDataPath);
1519 _testDataPath = 0;
1520
73c04bcf
A
1521 Locale lastDefaultLocale;
1522 if (originalLocale != lastDefaultLocale) {
1523 major.errln("FAILURE: A test changed the default locale without resetting it.");
1524 }
1525
b75a7d8f 1526 fprintf(stdout, "\n--------------------------------------\n");
57a6839d
A
1527 if( major.printKnownIssues() ) {
1528 fprintf(stdout, " To run suppressed tests, use the -K option. \n");
1529 }
b75a7d8f
A
1530 if (major.getErrors() == 0) {
1531 /* Call it twice to make sure that the defaults were reset. */
1532 /* Call it before the OK message to verify proper cleanup. */
1533 u_cleanup();
73c04bcf 1534 u_cleanup();
b75a7d8f
A
1535
1536 fprintf(stdout, "OK: All tests passed without error.\n");
73c04bcf
A
1537
1538 if (major.getDataErrors() != 0) {
1539 fprintf(stdout, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
1540 }
b75a7d8f
A
1541 }else{
1542 fprintf(stdout, "Errors in total: %ld.\n", (long)major.getErrors());
1543 major.printErrors();
1544
57a6839d
A
1545 if(summary_file != NULL) {
1546 FILE *summf = fopen(summary_file, "w");
1547 if( summf != NULL) {
1548 char buf[10000];
1549 int32_t length = errorList.extract(0, errorList.length(), buf, sizeof(buf));
1550 fwrite(buf, sizeof(*buf), length, (FILE*)summf);
1551 fclose(summf);
1552 }
1553 }
1554
73c04bcf
A
1555
1556 if (major.getDataErrors() != 0) {
1557 fprintf(stdout, "\t*Note* some errors are data-loading related. If the data used is not the \n"
1558 "\tstock ICU data (i.e some have been added or removed), consider using\n"
1559 "\tthe '-w' option to turn these errors into warnings.\n");
1560 }
1561
b75a7d8f
A
1562 /* Call afterwards to display errors. */
1563 u_cleanup();
1564 }
1565
2ca993e8
A
1566#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
1567 unistr_printLengths();
1568#endif
1569
b75a7d8f
A
1570 fprintf(stdout, "--------------------------------------\n");
1571
b75a7d8f
A
1572 if (execCount <= 0) {
1573 fprintf(stdout, "***** Not all called tests actually exist! *****\n");
1574 }
51004dcb
A
1575 if(!no_time) {
1576 endTime = uprv_getRawUTCtime();
1577 diffTime = (int32_t)(endTime - startTime);
1578 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
1579 (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
1580 (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
1581 (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
1582 (int)(diffTime%U_MILLIS_PER_SECOND));
1583 }
729e4ab9
A
1584
1585 if(ctest_xml_fini())
1586 return 1;
1587
b75a7d8f
A
1588 return major.getErrors();
1589}
1590
1591const char* IntlTest::loadTestData(UErrorCode& err){
1592 if( _testDataPath == NULL){
1593 const char* directory=NULL;
1594 UResourceBundle* test =NULL;
1595 char* tdpath=NULL;
1596 const char* tdrelativepath;
1597
1598#if defined (U_TOPBUILDDIR)
51004dcb 1599 tdrelativepath = "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
b75a7d8f
A
1600 directory = U_TOPBUILDDIR;
1601#else
51004dcb 1602 tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
b75a7d8f
A
1603 directory = pathToDataDirectory();
1604#endif
1605
1606 tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
1607
1608
1609 /* u_getDataDirectory shoul return \source\data ... set the
1610 * directory to ..\source\data\..\test\testdata\out\testdata
1611 */
374ca955 1612 strcpy(tdpath, directory);
b75a7d8f
A
1613 strcat(tdpath, tdrelativepath);
1614 strcat(tdpath,"testdata");
1615
1616 test=ures_open(tdpath, "testtypes", &err);
1617
1618 if(U_FAILURE(err)){
1619 err = U_FILE_ACCESS_ERROR;
729e4ab9 1620 it_dataerrln((UnicodeString)"Could not load testtypes.res in testdata bundle with path " + tdpath + (UnicodeString)" - " + u_errorName(err));
b75a7d8f
A
1621 return "";
1622 }
1623 ures_close(test);
1624 _testDataPath = tdpath;
1625 return _testDataPath;
1626 }
1627 return _testDataPath;
1628}
1629
374ca955
A
1630const char* IntlTest::getTestDataPath(UErrorCode& err) {
1631 return loadTestData(err);
1632}
1633
1634/* Returns the path to icu/source/test/testdata/ */
1635const char *IntlTest::getSourceTestData(UErrorCode& /*err*/) {
1636 const char *srcDataDir = NULL;
1637#ifdef U_TOPSRCDIR
51004dcb 1638 srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
374ca955 1639#else
51004dcb
A
1640 srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
1641 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
1642 if (f) {
1643 /* We're in icu/source/test/intltest/ */
1644 fclose(f);
1645 }
1646 else {
729e4ab9 1647 /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
b331163b
A
1648 srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING
1649 "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
374ca955
A
1650 }
1651#endif
1652 return srcDataDir;
1653}
1654
b331163b
A
1655char *IntlTest::getUnidataPath(char path[]) {
1656 const int kUnicodeDataTxtLength = 15; // strlen("UnicodeData.txt")
1657
1658 // Look inside ICU_DATA first.
1659 strcpy(path, pathToDataDirectory());
1660 strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
1661 FILE *f = fopen(path, "r");
1662 if(f != NULL) {
1663 fclose(f);
1664 *(strchr(path, 0) - kUnicodeDataTxtLength) = 0; // Remove the basename.
1665 return path;
1666 }
1667
1668 // As a fallback, try to guess where the source data was located
1669 // at the time ICU was built, and look there.
1670# ifdef U_TOPSRCDIR
1671 strcpy(path, U_TOPSRCDIR U_FILE_SEP_STRING "data");
1672# else
1673 UErrorCode errorCode = U_ZERO_ERROR;
1674 const char *testDataPath = loadTestData(errorCode);
1675 if(U_FAILURE(errorCode)) {
1676 it_errln(UnicodeString(
1677 "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
1678 u_errorName(errorCode));
1679 return NULL;
1680 }
1681 strcpy(path, testDataPath);
1682 strcat(path, U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
1683 U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
1684 U_FILE_SEP_STRING "data");
1685# endif
1686 strcat(path, U_FILE_SEP_STRING);
1687 strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
1688 f = fopen(path, "r");
1689 if(f != NULL) {
1690 fclose(f);
1691 *(strchr(path, 0) - kUnicodeDataTxtLength) = 0; // Remove the basename.
1692 return path;
1693 }
1694 return NULL;
1695}
1696
b75a7d8f
A
1697const char* IntlTest::fgDataDir = NULL;
1698
1699/* returns the path to icu/source/data */
1700const char * IntlTest::pathToDataDirectory()
1701{
1702
1703 if(fgDataDir != NULL) {
1704 return fgDataDir;
1705 }
1706
1707 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
1708 // to point to the top of the build hierarchy, which may or
1709 // may not be the same as the source directory, depending on
1710 // the configure options used. At any rate,
1711 // set the data path to the built data from this directory.
1712 // The value is complete with quotes, so it can be used
1713 // as-is as a string constant.
1714 */
1715#if defined (U_TOPSRCDIR)
1716 {
1717 fgDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
1718 }
1719#else
1720
1721 /* On Windows, the file name obtained from __FILE__ includes a full path.
1722 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
1723 * Change to "wherever\icu\source\data"
1724 */
1725 {
1726 static char p[sizeof(__FILE__) + 10];
1727 char *pBackSlash;
1728 int i;
1729
1730 strcpy(p, __FILE__);
1731 /* We want to back over three '\' chars. */
1732 /* Only Windows should end up here, so looking for '\' is safe. */
1733 for (i=1; i<=3; i++) {
1734 pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
1735 if (pBackSlash != NULL) {
1736 *pBackSlash = 0; /* Truncate the string at the '\' */
1737 }
1738 }
1739
1740 if (pBackSlash != NULL) {
1741 /* We found and truncated three names from the path.
1742 * Now append "source\data" and set the environment
1743 */
1744 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
1745 fgDataDir = p;
1746 }
1747 else {
1748 /* __FILE__ on MSVC7 does not contain the directory */
b331163b 1749 FILE *file = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
374ca955
A
1750 if (file) {
1751 fclose(file);
b331163b 1752 fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
374ca955
A
1753 }
1754 else {
b331163b 1755 fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
374ca955 1756 }
b75a7d8f
A
1757 }
1758 }
1759#endif
1760
1761 return fgDataDir;
1762
1763}
1764
1765/*
1766 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
729e4ab9 1767 * It converts an invariant-character string into a UnicodeString, with
b75a7d8f
A
1768 * unescaping \u sequences.
1769 */
729e4ab9
A
1770UnicodeString CharsToUnicodeString(const char* chars){
1771 return UnicodeString(chars, -1, US_INV).unescape();
b75a7d8f
A
1772}
1773
374ca955
A
1774UnicodeString ctou(const char* chars) {
1775 return CharsToUnicodeString(chars);
1776}
1777
1778#define RAND_M (714025)
1779#define RAND_IA (1366)
1780#define RAND_IC (150889)
1781
1782static int32_t RAND_SEED;
1783
1784/**
1785 * Returns a uniform random value x, with 0.0 <= x < 1.0. Use
1786 * with care: Does not return all possible values; returns one of
1787 * 714,025 values, uniformly spaced. However, the period is
1788 * effectively infinite. See: Numerical Recipes, section 7.1.
1789 *
1790 * @param seedp pointer to seed. Set *seedp to any negative value
1791 * to restart the sequence.
1792 */
1793float IntlTest::random(int32_t* seedp) {
1794 static int32_t iy, ir[98];
1795 static UBool first=TRUE;
1796 int32_t j;
1797 if (*seedp < 0 || first) {
1798 first = FALSE;
1799 if ((*seedp=(RAND_IC-(*seedp)) % RAND_M) < 0) *seedp = -(*seedp);
1800 for (j=1;j<=97;++j) {
1801 *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1802 ir[j]=(*seedp);
1803 }
1804 *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1805 iy=(*seedp);
1806 }
1807 j=(int32_t)(1 + 97.0*iy/RAND_M);
1808 U_ASSERT(j>=1 && j<=97);
1809 iy=ir[j];
1810 *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1811 ir[j]=(*seedp);
1812 return (float) iy/RAND_M;
1813}
1814
1815/**
1816 * Convenience method using a global seed.
1817 */
1818float IntlTest::random() {
1819 return random(&RAND_SEED);
1820}
1821
2ca993e8
A
1822
1823/*
1824 * Integer random number class implementation.
1825 * Similar to C++ std::minstd_rand, with the same algorithm & constants.
1826 */
1827IntlTest::icu_rand::icu_rand(uint32_t seed) {
1828 seed = seed % 2147483647UL;
1829 if (seed == 0) {
1830 seed = 1;
1831 }
1832 fLast = seed;
1833}
1834
1835IntlTest::icu_rand::~icu_rand() {}
1836
1837void IntlTest::icu_rand::seed(uint32_t seed) {
1838 if (seed == 0) {
1839 seed = 1;
1840 }
1841 fLast = seed;
1842}
1843
1844uint32_t IntlTest::icu_rand::operator() () {
1845 fLast = ((uint64_t)fLast * 48271UL) % 2147483647UL;
1846 return fLast;
1847}
1848
1849uint32_t IntlTest::icu_rand::getSeed() {
1850 return (uint32_t) fLast;
1851}
1852
1853
1854
374ca955
A
1855static inline UChar toHex(int32_t i) {
1856 return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10)));
1857}
1858
1859static UnicodeString& escape(const UnicodeString& s, UnicodeString& result) {
1860 for (int32_t i=0; i<s.length(); ++i) {
1861 UChar c = s[i];
1862 if (c <= (UChar)0x7F) {
1863 result += c;
1864 } else {
1865 result += (UChar)0x5c;
1866 result += (UChar)0x75;
1867 result += toHex((c >> 12) & 0xF);
1868 result += toHex((c >> 8) & 0xF);
1869 result += toHex((c >> 4) & 0xF);
1870 result += toHex( c & 0xF);
1871 }
1872 }
1873 return result;
1874}
1875
1876#define VERBOSE_ASSERTIONS
1877
51004dcb
A
1878UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError, const char *file, int line) {
1879 if (file != NULL) {
1880 if (!condition) {
1881 if (possibleDataError) {
1882 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
1883 } else {
1884 errln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
1885 }
1886 } else if (!quiet) {
1887 logln("%s:%d: Ok: %s", file, line, message);
729e4ab9 1888 }
51004dcb
A
1889 } else {
1890 if (!condition) {
1891 if (possibleDataError) {
1892 dataerrln("FAIL: assertTrue() failed: %s", message);
1893 } else {
1894 errln("FAIL: assertTrue() failed: %s", message);
1895 }
1896 } else if (!quiet) {
1897 logln("Ok: %s", message);
1898 }
1899
374ca955
A
1900 }
1901 return condition;
1902}
1903
0f5d89e8 1904UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet, UBool possibleDataError) {
374ca955 1905 if (condition) {
0f5d89e8
A
1906 if (possibleDataError) {
1907 dataerrln("FAIL: assertTrue() failed: %s", message);
1908 } else {
1909 errln("FAIL: assertTrue() failed: %s", message);
1910 }
374ca955
A
1911 } else if (!quiet) {
1912 logln("Ok: %s", message);
1913 }
1914 return !condition;
1915}
1916
57a6839d
A
1917UBool IntlTest::assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError, const char *file, int line) {
1918 if( file==NULL ) {
1919 file = ""; // prevent failure if no file given
1920 }
374ca955 1921 if (U_FAILURE(ec)) {
729e4ab9 1922 if (possibleDataError) {
57a6839d 1923 dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
46f4442e 1924 } else {
57a6839d 1925 errcheckln(ec, "FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
46f4442e 1926 }
374ca955 1927 return FALSE;
57a6839d
A
1928 } else {
1929 logln("OK: %s:%d: %s - (%s)", file, line, message, u_errorName(ec));
374ca955
A
1930 }
1931 return TRUE;
1932}
1933
1934UBool IntlTest::assertEquals(const char* message,
1935 const UnicodeString& expected,
729e4ab9
A
1936 const UnicodeString& actual,
1937 UBool possibleDataError) {
374ca955 1938 if (expected != actual) {
729e4ab9
A
1939 if (possibleDataError) {
1940 dataerrln((UnicodeString)"FAIL: " + message + "; got " +
1941 prettify(actual) +
1942 "; expected " + prettify(expected));
1943 } else {
1944 errln((UnicodeString)"FAIL: " + message + "; got " +
1945 prettify(actual) +
1946 "; expected " + prettify(expected));
1947 }
374ca955
A
1948 return FALSE;
1949 }
1950#ifdef VERBOSE_ASSERTIONS
1951 else {
1952 logln((UnicodeString)"Ok: " + message + "; got " + prettify(actual));
1953 }
1954#endif
1955 return TRUE;
1956}
1957
1958UBool IntlTest::assertEquals(const char* message,
1959 const char* expected,
1960 const char* actual) {
1961 if (uprv_strcmp(expected, actual) != 0) {
1962 errln((UnicodeString)"FAIL: " + message + "; got \"" +
1963 actual +
1964 "\"; expected \"" + expected + "\"");
1965 return FALSE;
1966 }
1967#ifdef VERBOSE_ASSERTIONS
1968 else {
1969 logln((UnicodeString)"Ok: " + message + "; got \"" + actual + "\"");
1970 }
1971#endif
1972 return TRUE;
1973}
1974
51004dcb
A
1975UBool IntlTest::assertEquals(const char* message,
1976 int32_t expected,
1977 int32_t actual) {
1978 if (expected != actual) {
1979 errln((UnicodeString)"FAIL: " + message + "; got " +
1980 actual + "=0x" + toHex(actual) +
1981 "; expected " + expected + "=0x" + toHex(expected));
1982 return FALSE;
1983 }
1984#ifdef VERBOSE_ASSERTIONS
1985 else {
1986 logln((UnicodeString)"Ok: " + message + "; got " + actual + "=0x" + toHex(actual));
1987 }
1988#endif
1989 return TRUE;
1990}
1991
374ca955 1992UBool IntlTest::assertEquals(const char* message,
57a6839d
A
1993 int64_t expected,
1994 int64_t actual) {
1995 if (expected != actual) {
1996 errln((UnicodeString)"FAIL: " + message + "; got int64 " +
1997 Int64ToUnicodeString(actual) +
1998 "; expected " + Int64ToUnicodeString(expected) );
1999 return FALSE;
2000 }
2001#ifdef VERBOSE_ASSERTIONS
2002 else {
2003 logln((UnicodeString)"Ok: " + message + "; got int64 " + Int64ToUnicodeString(actual));
2004 }
2005#endif
2006 return TRUE;
2007}
2008
2ca993e8
A
2009UBool IntlTest::assertEquals(const char* message,
2010 double expected,
2011 double actual) {
0f5d89e8
A
2012 bool bothNaN = std::isnan(expected) && std::isnan(actual);
2013 if (expected != actual && !bothNaN) {
2ca993e8
A
2014 errln((UnicodeString)"FAIL: " + message + "; got " +
2015 actual +
2016 "; expected " + expected);
2017 return FALSE;
2018 }
2019#ifdef VERBOSE_ASSERTIONS
2020 else {
2021 logln((UnicodeString)"Ok: " + message + "; got " + actual);
2022 }
2023#endif
2024 return TRUE;
2025}
2026
2027
57a6839d
A
2028UBool IntlTest::assertEquals(const char* message,
2029 UBool expected,
2030 UBool actual) {
374ca955
A
2031 if (expected != actual) {
2032 errln((UnicodeString)"FAIL: " + message + "; got " +
2033 toString(actual) +
2034 "; expected " + toString(expected));
2035 return FALSE;
2036 }
57a6839d
A
2037#ifdef VERBOSE_ASSERTIONS
2038 else {
2039 logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
2040 }
2041#endif
2042 return TRUE;
2043}
2044
0f5d89e8
A
2045
2046UBool IntlTest::assertEquals(const char* message,
2047 UErrorCode expected,
2048 UErrorCode actual) {
2049 if (expected != actual) {
2050 errln((UnicodeString)"FAIL: " + message + "; got " +
2051 u_errorName(actual) +
2052 "; expected " + u_errorName(expected));
2053 return FALSE;
2054 }
2055#ifdef VERBOSE_ASSERTIONS
2056 else {
2057 logln((UnicodeString)"Ok: " + message + "; got " + u_errorName(actual));
2058 }
2059#endif
2060 return TRUE;
2061}
2062
2063UBool IntlTest::assertEquals(const char* message,
2064 const UnicodeSet& expected,
2065 const UnicodeSet& actual) {
2066 IcuTestErrorCode status(*this, "assertEqualsUniSet");
2067 if (expected != actual) {
2068 errln((UnicodeString)"FAIL: " + message + "; got " +
2069 toString(actual, status) +
2070 "; expected " + toString(expected, status));
2071 return FALSE;
2072 }
2073#ifdef VERBOSE_ASSERTIONS
2074 else {
2075 logln((UnicodeString)"Ok: " + message + "; got " + toString(actual, status));
2076 }
2077#endif
2078 return TRUE;
2079}
2080
2081
57a6839d
A
2082#if !UCONFIG_NO_FORMATTING
2083UBool IntlTest::assertEquals(const char* message,
2084 const Formattable& expected,
2085 const Formattable& actual,
2086 UBool possibleDataError) {
2087 if (expected != actual) {
2088 if (possibleDataError) {
2089 dataerrln((UnicodeString)"FAIL: " + message + "; got " +
2090 toString(actual) +
2091 "; expected " + toString(expected));
2092 } else {
2093 errln((UnicodeString)"FAIL: " + message + "; got " +
2094 toString(actual) +
2095 "; expected " + toString(expected));
2096 }
2097 return FALSE;
2098 }
374ca955
A
2099#ifdef VERBOSE_ASSERTIONS
2100 else {
2101 logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
2102 }
2103#endif
2104 return TRUE;
2105}
2106#endif
2107
2108static char ASSERT_BUF[256];
2109
2110static const char* extractToAssertBuf(const UnicodeString& message) {
2111 UnicodeString buf;
2112 escape(message, buf);
2113 buf.extract(0, 0x7FFFFFFF, ASSERT_BUF, sizeof(ASSERT_BUF)-1, 0);
2114 ASSERT_BUF[sizeof(ASSERT_BUF)-1] = 0;
2115 return ASSERT_BUF;
2116}
2117
0f5d89e8
A
2118UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
2119 return assertTrue(extractToAssertBuf(message), condition, quiet, possibleDataError);
374ca955
A
2120}
2121
0f5d89e8
A
2122UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
2123 return assertFalse(extractToAssertBuf(message), condition, quiet, possibleDataError);
374ca955
A
2124}
2125
2126UBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) {
2127 return assertSuccess(extractToAssertBuf(message), ec);
2128}
2129
2130UBool IntlTest::assertEquals(const UnicodeString& message,
2131 const UnicodeString& expected,
57a6839d
A
2132 const UnicodeString& actual,
2133 UBool possibleDataError) {
2134 return assertEquals(extractToAssertBuf(message), expected, actual, possibleDataError);
374ca955
A
2135}
2136
2137UBool IntlTest::assertEquals(const UnicodeString& message,
2138 const char* expected,
2139 const char* actual) {
2140 return assertEquals(extractToAssertBuf(message), expected, actual);
2141}
57a6839d
A
2142UBool IntlTest::assertEquals(const UnicodeString& message,
2143 UBool expected,
2144 UBool actual) {
2145 return assertEquals(extractToAssertBuf(message), expected, actual);
2146}
2147UBool IntlTest::assertEquals(const UnicodeString& message,
2148 int32_t expected,
2149 int32_t actual) {
2150 return assertEquals(extractToAssertBuf(message), expected, actual);
2151}
2152UBool IntlTest::assertEquals(const UnicodeString& message,
2153 int64_t expected,
2154 int64_t actual) {
2155 return assertEquals(extractToAssertBuf(message), expected, actual);
0f5d89e8
A
2156}
2157UBool IntlTest::assertEquals(const UnicodeString& message,
2158 double expected,
2159 double actual) {
2160 return assertEquals(extractToAssertBuf(message), expected, actual);
2161}
2162UBool IntlTest::assertEquals(const UnicodeString& message,
2163 UErrorCode expected,
2164 UErrorCode actual) {
2165 return assertEquals(extractToAssertBuf(message), expected, actual);
2166}
2167UBool IntlTest::assertEquals(const UnicodeString& message,
2168 const UnicodeSet& expected,
2169 const UnicodeSet& actual) {
2170 return assertEquals(extractToAssertBuf(message), expected, actual);
374ca955
A
2171}
2172
2173#if !UCONFIG_NO_FORMATTING
2174UBool IntlTest::assertEquals(const UnicodeString& message,
2175 const Formattable& expected,
2176 const Formattable& actual) {
2177 return assertEquals(extractToAssertBuf(message), expected, actual);
2178}
2179#endif
2180
729e4ab9
A
2181void IntlTest::setProperty(const char* propline) {
2182 if (numProps < kMaxProps) {
2183 proplines[numProps] = propline;
2184 }
2185 numProps++;
2186}
2187
2188const char* IntlTest::getProperty(const char* prop) {
2189 const char* val = NULL;
2190 for (int32_t i = 0; i < numProps; i++) {
2191 int32_t plen = uprv_strlen(prop);
2192 if ((int32_t)uprv_strlen(proplines[i]) > plen + 1
2193 && proplines[i][plen] == '='
2194 && uprv_strncmp(proplines[i], prop, plen) == 0) {
2195 val = &(proplines[i][plen+1]);
2196 break;
2197 }
2198 }
2199 return val;
2200}
2201
b75a7d8f
A
2202/*
2203 * Hey, Emacs, please set the following:
2204 *
2205 * Local Variables:
2206 * indent-tabs-mode: nil
2207 * End:
2208 *
2209 */