1 /* 2 *********************************************************************** 3 * Copyright (C) 2016 and later: Unicode, Inc. and others. 4 * License & terms of use: http://www.unicode.org/copyright.html#License 5 *********************************************************************** 6 *********************************************************************** 7 * Copyright (c) 2011-2016,International Business Machines 8 * Corporation and others. All Rights Reserved. 9 *********************************************************************** 10 */ 11 #include <stdio.h> 12 #include <string.h> 13 14 #include "cmemory.h" 15 #include "sieve.h" 16 #include "unicode/utimer.h" 17 #include "udbgutil.h" 18 #include "unicode/ustring.h" 19 #include "unicode/decimfmt.h" 20 #include "unicode/udat.h" 21 U_NAMESPACE_USE 22 23 #if U_PLATFORM_IMPLEMENTS_POSIX 24 #include <unistd.h> 25 26 static void usage(const char *prog) { 27 fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog); 28 } 29 #endif 30 31 void runTests(void); 32 33 #ifndef ITERATIONS 34 #define ITERATIONS 5 35 #endif 36 37 #ifndef TEST_LOCALE 38 #define TEST_LOCALE "en_US" 39 #endif 40 41 FILE *out = NULL; 42 UErrorCode setupStatus = U_ZERO_ERROR; 43 const char *outName = NULL; 44 int listmode = 0; 45 const char *testName = NULL; 46 const char *progname = NULL; 47 int errflg = 0; 48 int testhit = 0; 49 50 int testMatch(const char *aName) { 51 if(testName==NULL) return 1; 52 int len = strlen(testName); 53 if(testName[len-1]=='*') { 54 return strncmp(testName,aName,len-1); 55 } else { 56 return strcmp(testName,aName); 57 } 58 } 59 60 int main(int argc, char * const * argv){ 61 #if U_DEBUG 62 fprintf(stderr,"%s: warning: U_DEBUG is on.\n", argv[0]); 63 #endif 64 #if U_DEBUG 65 { 66 double m; 67 double s = uprv_getSieveTime(&m); 68 fprintf(stderr, "** Standard sieve time: %.9fs +/- %.9fs (%d iterations)\n", s,m, (int)U_LOTS_OF_TIMES); 69 } 70 #endif 71 72 #if U_PLATFORM_IMPLEMENTS_POSIX 73 int c; 74 //extern int optind; 75 extern char *optarg; 76 while((c=getopt(argc,argv,"lf:t:")) != EOF) { 77 switch(c) { 78 case 'f': 79 outName = optarg; 80 break; 81 case 'l': 82 listmode++; 83 break; 84 case 't': 85 testName = optarg; 86 break; 87 case '?': 88 errflg++; 89 } 90 if(errflg) { 91 usage(progname); 92 return 0; 93 } 94 } 95 /* for ( ; optind < argc; optind++) { ... argv[optind] } */ 96 #else 97 if(argc==2) { 98 outName = argv[1]; 99 } else if(argc>2) { 100 fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]); 101 } 102 #endif 103 104 if(listmode && outName != NULL ) { 105 fprintf(stderr, "Warning: no output when list mode\n"); 106 outName=NULL; 107 } 108 109 if(outName != NULL) { 110 111 112 out=fopen(outName,"w"); 113 if(out==NULL) { 114 fprintf(stderr,"Err: can't open %s for writing.\n", outName); 115 return 1; 116 } else { 117 fprintf(stderr, "# writing results to %s\n", outName); 118 } 119 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); 120 fprintf(out, "<tests icu=\"%s\">\n", U_ICU_VERSION); 121 fprintf(out, "<!-- %s -->\n", U_COPYRIGHT_STRING); 122 } else { 123 fprintf(stderr, "# (no output)\n"); 124 } 125 126 if(listmode && testName!=NULL) { 127 fprintf(stderr, "ERR: no -l mode when specific test with -t\n"); 128 usage(progname); 129 return 1; 130 } 131 132 133 runTests(); 134 135 136 if(out!=NULL) { 137 #ifndef SKIP_INFO 138 udbg_writeIcuInfo(out); 139 #endif 140 fprintf(out, "</tests>\n"); 141 fclose(out); 142 } 143 144 if(U_FAILURE(setupStatus)) { 145 fprintf(stderr, "Error in tests: %s\n", u_errorName(setupStatus)); 146 return 1; 147 } 148 149 return 0; 150 } 151 152 class HowExpensiveTest { 153 public: 154 virtual ~HowExpensiveTest(){} 155 protected: 156 HowExpensiveTest(const char *name, const char *file, int32_t line) : fName(name), fFile(file), fLine(line) {} 157 protected: 158 /** 159 * @return number of iterations 160 */ 161 virtual int32_t run() = 0; 162 virtual void warmup() { run(); } 163 public: 164 virtual const char *getName() { return fName; } 165 public: 166 virtual int32_t runTest(double *subTime) { 167 UTimer a,b; 168 utimer_getTime(&a); 169 int32_t iter = run(); 170 utimer_getTime(&b); 171 *subTime = utimer_getDeltaSeconds(&a,&b); 172 return iter; 173 } 174 175 virtual int32_t runTests(double *subTime, double *marginOfError) { 176 warmup(); /* warmup */ 177 double times[ITERATIONS]; 178 int subIterations = 0; 179 for(int i=0;i<ITERATIONS;i++) { 180 subIterations = runTest(×[i]); 181 #if U_DEBUG 182 fprintf(stderr, "trial: %d/%d = %.9fs\n", i, ITERATIONS,times[i]); 183 fflush(stderr); 184 #endif 185 } 186 uint32_t iterations = ITERATIONS; 187 *subTime = uprv_getMeanTime(times,&iterations,marginOfError); 188 return subIterations; 189 } 190 public: 191 const char *fName; 192 const char *fFile; 193 int32_t fLine; 194 int32_t fIterations; 195 }; 196 197 void runTestOn(HowExpensiveTest &t) { 198 if(U_FAILURE(setupStatus)) return; // silently 199 const char *tn = t.getName(); 200 if(testName!=NULL && testMatch(tn)) return; // skipped. 201 if(listmode) { 202 fprintf(stderr, "%s:%d:\t%s\n", t.fFile, t.fLine, t.getName()); 203 testhit++; 204 return; 205 } else { 206 fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.getName()); 207 testhit++; 208 } 209 double sieveTime = uprv_getSieveTime(NULL); 210 double st; 211 double me; 212 213 fflush(stdout); 214 fflush(stderr); 215 int32_t iter = t.runTests(&st,&me); 216 if(U_FAILURE(setupStatus)) { 217 fprintf(stderr, "Error in tests: %s\n", u_errorName(setupStatus)); 218 return; 219 } 220 fflush(stdout); 221 fflush(stderr); 222 223 double stn = st/sieveTime; 224 225 printf("%s\t%.9f\t%.9f +/- %.9f, @ %d iter\n", t.getName(),stn,st,me,iter); 226 227 if(out!=NULL) { 228 fprintf(out, " <test name=\"%s\" standardizedTime=\"%f\" realDuration=\"%f\" marginOfError=\"%f\" iterations=\"%d\" />\n", 229 tn,stn,st,me,iter); 230 fflush(out); 231 } 232 } 233 234 /* ------------------- test code here --------------------- */ 235 236 class SieveTest : public HowExpensiveTest { 237 public: 238 virtual ~SieveTest(){} 239 SieveTest():HowExpensiveTest("SieveTest",__FILE__,__LINE__){} 240 virtual int32_t run(){return 0;} // dummy 241 int32_t runTest(double *subTime) { 242 *subTime = uprv_getSieveTime(NULL); 243 return U_LOTS_OF_TIMES; 244 } 245 virtual int32_t runTests(double *subTime, double *marginOfError) { 246 *subTime = uprv_getSieveTime(marginOfError); 247 return U_LOTS_OF_TIMES; 248 } 249 }; 250 251 252 /* ------- NumParseTest ------------- */ 253 #include "unicode/unum.h" 254 /* open and close tests */ 255 #define OCName(svc,ub,testn,suffix,n) testn ## svc ## ub ## suffix ## n 256 #define OCStr(svc,ub,suffix,n) "Test_" # svc # ub # suffix # n 257 #define OCRun(svc,ub,suffix) svc ## ub ## suffix 258 // TODO: run away screaming 259 #define OpenCloseTest(n, svc,suffix,c,a,d) class OCName(svc,_,Test_,suffix,n) : public HowExpensiveTest { public: OCName(svc,_,Test_,suffix,n)():HowExpensiveTest(OCStr(svc,_,suffix,n),__FILE__,__LINE__) c int32_t run() { int32_t i; for(i=0;i<U_LOTS_OF_TIMES;i++){ OCRun(svc,_,close) ( OCRun(svc,_,suffix) a ); } return i; } void warmup() { OCRun(svc,_,close) ( OCRun(svc,_,suffix) a); } virtual ~ OCName(svc,_,Test_,suffix,n) () d }; 260 #define QuickTest(n,c,r,d) class n : public HowExpensiveTest { public: n():HowExpensiveTest(#n,__FILE__,__LINE__) c int32_t run() r virtual ~n () d }; 261 262 class NumTest : public HowExpensiveTest { 263 private: 264 double fExpect; 265 UNumberFormat *fFmt; 266 UnicodeString fPat; 267 UnicodeString fString; 268 const UChar *fStr; 269 int32_t fLen; 270 const char *fFile; 271 int fLine; 272 const char *fCPat; 273 const char *fCStr; 274 char name[100]; 275 public: 276 virtual const char *getName() { 277 if(name[0]==0) { 278 sprintf(name,"%s:p=|%s|,str=|%s|",getClassName(),fCPat,fCStr); 279 } 280 return name; 281 } 282 protected: 283 virtual UNumberFormat* initFmt() { 284 return unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus); 285 } 286 virtual const char *getClassName() { 287 return "NumTest"; 288 } 289 public: 290 NumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE) 291 : HowExpensiveTest("(n/a)",FILE, LINE), 292 fExpect(expect), 293 fFmt(0), 294 fPat(pat, -1, US_INV), 295 fString(num,-1,US_INV), 296 fStr(fString.getTerminatedBuffer()), 297 fLen(u_strlen(fStr)), 298 fFile(FILE), 299 fLine(LINE), 300 fCPat(pat), 301 fCStr(num) 302 { 303 name[0]=0; 304 } 305 void warmup() { 306 fFmt = initFmt(); 307 if(U_SUCCESS(setupStatus)) { 308 double trial = unum_parseDouble(fFmt,fStr,fLen, NULL, &setupStatus); 309 if(U_SUCCESS(setupStatus) && trial!=fExpect) { 310 setupStatus = U_INTERNAL_PROGRAM_ERROR; 311 printf("%s:%d: warmup() %s got %.8f expected %.8f\n", 312 fFile,fLine,getName(),trial,fExpect); 313 } 314 } 315 } 316 int32_t run() { 317 double trial=0.0; 318 int i; 319 for(i=0;i<U_LOTS_OF_TIMES;i++){ 320 trial = unum_parse(fFmt,fStr,fLen, NULL, &setupStatus); 321 } 322 return i; 323 } 324 virtual ~NumTest(){} 325 }; 326 327 #define DO_NumTest(p,n,x) { NumTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } 328 329 330 class AttrNumTest : public NumTest 331 { 332 private: 333 UNumberFormatAttribute fAttr; 334 int32_t fAttrValue; 335 char name2[100]; 336 protected: 337 virtual const char *getClassName() { 338 sprintf(name2,"AttrNumTest:%d=%d", fAttr,fAttrValue); 339 return name2; 340 } 341 public: 342 AttrNumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE, UNumberFormatAttribute attr, int32_t newValue) 343 : NumTest(pat,num,expect,FILE,LINE), 344 fAttr(attr), 345 fAttrValue(newValue) 346 { 347 } 348 virtual UNumberFormat* initFmt() { 349 UNumberFormat *fmt = NumTest::initFmt(); 350 unum_setAttribute(fmt, fAttr,fAttrValue); 351 return fmt; 352 } 353 }; 354 355 #define DO_AttrNumTest(p,n,x,a,v) { AttrNumTest t(p,n,x,__FILE__,__LINE__,a,v); runTestOn(t); } 356 357 358 class NOXNumTest : public NumTest 359 { 360 private: 361 UNumberFormatAttribute fAttr; 362 int32_t fAttrValue; 363 char name2[100]; 364 protected: 365 virtual const char *getClassName() { 366 sprintf(name2,"NOXNumTest:%d=%d", fAttr,fAttrValue); 367 return name2; 368 } 369 public: 370 NOXNumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE /*, UNumberFormatAttribute attr, int32_t newValue */) 371 : NumTest(pat,num,expect,FILE,LINE) /* , 372 fAttr(attr), 373 fAttrValue(newValue) */ 374 { 375 } 376 virtual UNumberFormat* initFmt() { 377 UNumberFormat *fmt = NumTest::initFmt(); 378 //unum_setAttribute(fmt, fAttr,fAttrValue); 379 return fmt; 380 } 381 }; 382 383 #define DO_NOXNumTest(p,n,x) { NOXNumTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } 384 385 #define DO_TripleNumTest(p,n,x) DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_YES) \ 386 DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_NO) \ 387 DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE) 388 389 390 class NumFmtTest : public HowExpensiveTest { 391 private: 392 double fExpect; 393 UNumberFormat *fFmt; 394 UnicodeString fPat; 395 UnicodeString fString; 396 const UChar *fStr; 397 int32_t fLen; 398 const char *fFile; 399 int fLine; 400 const char *fCPat; 401 const char *fCStr; 402 char name[100]; 403 public: 404 virtual const char *getName() { 405 if(name[0]==0) { 406 sprintf(name,"%s:p=|%s|,str=|%s|",getClassName(),fCPat,fCStr); 407 } 408 return name; 409 } 410 protected: 411 virtual UNumberFormat* initFmt() { 412 return unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus); 413 } 414 virtual const char *getClassName() { 415 return "NumFmtTest"; 416 } 417 public: 418 NumFmtTest(const char *pat, const char *num, double expect, const char *FILE, int LINE) 419 : HowExpensiveTest("(n/a)",FILE, LINE), 420 fExpect(expect), 421 fFmt(0), 422 fPat(pat, -1, US_INV), 423 fString(num,-1,US_INV), 424 fStr(fString.getTerminatedBuffer()), 425 fLen(u_strlen(fStr)), 426 fFile(FILE), 427 fLine(LINE), 428 fCPat(pat), 429 fCStr(num) 430 { 431 name[0]=0; 432 } 433 void warmup() { 434 fFmt = initFmt(); 435 UChar buf[100]; 436 if(U_SUCCESS(setupStatus)) { 437 int32_t trial = unum_formatDouble(fFmt,fExpect, buf, 100, NULL, &setupStatus); 438 if(!U_SUCCESS(setupStatus) 439 || trial!=fLen 440 ||trial<=0 441 || u_strncmp(fStr,buf,trial) ) { 442 char strBuf[200]; 443 u_strToUTF8(strBuf,200,NULL,buf,trial+1,&setupStatus); 444 printf("%s:%d: warmup() %s got %s expected %s, err %s\n", 445 fFile,fLine,getName(),strBuf,fCStr, u_errorName(setupStatus)); 446 setupStatus = U_INTERNAL_PROGRAM_ERROR; 447 } 448 } 449 } 450 int32_t run() { 451 int32_t trial; 452 int i; 453 UChar buf[100]; 454 if(U_SUCCESS(setupStatus)) { 455 for(i=0;i<U_LOTS_OF_TIMES;i++){ 456 trial = unum_formatDouble(fFmt,fExpect, buf, 100, NULL, &setupStatus); 457 } 458 } 459 return i; 460 } 461 virtual ~NumFmtTest(){} 462 }; 463 464 #define DO_NumFmtTest(p,n,x) { NumFmtTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } 465 466 class NumFmtInt64Test : public HowExpensiveTest { 467 public: 468 enum EMode { 469 kDefault, 470 kPattern, 471 kApplyPattern, 472 kGroupOff, 473 kApplyGroupOff 474 }; 475 private: 476 EMode fMode; 477 int64_t fExpect; 478 UNumberFormat *fFmt; 479 UnicodeString fPat; 480 UnicodeString fString; 481 const UChar *fStr; 482 int32_t fLen; 483 const char *fFile; 484 int fLine; 485 const char *fCPat; 486 const char *fCStr; 487 char name[100]; 488 public: 489 virtual const char *getName() { 490 if(name[0]==0) { 491 sprintf(name,"%s:p=|%s|,str=|%s|",getClassName(),fCPat,fCStr); 492 } 493 return name; 494 } 495 protected: 496 virtual UNumberFormat* initFmt() { 497 switch(fMode) { 498 case kPattern: 499 return unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus); 500 case kApplyPattern: 501 { 502 UNumberFormat *fmt = unum_open(UNUM_DECIMAL, NULL, -1, TEST_LOCALE, 0, &setupStatus); 503 unum_applyPattern(fmt, FALSE, fPat.getTerminatedBuffer(), -1, NULL, &setupStatus); 504 return fmt; 505 } 506 case kGroupOff: 507 { 508 UNumberFormat *fmt = unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus); 509 unum_setAttribute(fmt, UNUM_GROUPING_USED, UNUM_NO); 510 return fmt; 511 } 512 case kApplyGroupOff: 513 { 514 UNumberFormat *fmt = unum_open(UNUM_DECIMAL, NULL, -1, TEST_LOCALE, 0, &setupStatus); 515 unum_applyPattern(fmt, FALSE, fPat.getTerminatedBuffer(), -1, NULL, &setupStatus); 516 unum_setAttribute(fmt, UNUM_GROUPING_USED, UNUM_NO); 517 return fmt; 518 } 519 default: 520 case kDefault: 521 return unum_open(UNUM_DEFAULT, NULL, -1, TEST_LOCALE, 0, &setupStatus); 522 } 523 } 524 virtual const char *getClassName() { 525 switch(fMode) { 526 case EMode::kDefault: 527 return "NumFmtInt64Test (default)"; 528 case EMode::kPattern: 529 return "NumFmtInt64Test (pattern)"; 530 case EMode::kApplyPattern: 531 return "NumFmtInt64Test (applypattern)"; 532 case EMode::kGroupOff: 533 return "NumFmtInt64Test (pattern, group=off)"; 534 case EMode::kApplyGroupOff: 535 return "NumFmtInt64Test (applypattern, group=off)"; 536 default: 537 return "NumFmtInt64Test (? ? ?)"; 538 } 539 } 540 public: 541 NumFmtInt64Test(const char *pat, const char *num, int64_t expect, const char *FILE, int LINE, EMode mode) 542 : HowExpensiveTest("(n/a)",FILE, LINE), 543 fMode(mode), 544 fExpect(expect), 545 fFmt(0), 546 fPat(pat, -1, US_INV), 547 fString(num,-1,US_INV), 548 fStr(fString.getTerminatedBuffer()), 549 fLen(u_strlen(fStr)), 550 fFile(FILE), 551 fLine(LINE), 552 fCPat(pat), 553 fCStr(num) 554 { 555 name[0]=0; 556 } 557 void warmup() { 558 fFmt = initFmt(); 559 UChar buf[100]; 560 if(U_SUCCESS(setupStatus)) { 561 int32_t trial = unum_formatInt64(fFmt,fExpect, buf, 100, NULL, &setupStatus); 562 if(!U_SUCCESS(setupStatus) 563 || trial!=fLen 564 ||trial<=0 565 || u_strncmp(fStr,buf,trial) ) { 566 char strBuf[200]; 567 u_strToUTF8(strBuf,200,NULL,buf,trial+1,&setupStatus); 568 printf("%s:%d: warmup() %s got %s (len %d) expected %s (len %d), err %s\n", 569 fFile,fLine,getName(),strBuf,trial,fCStr,fLen, u_errorName(setupStatus)); 570 setupStatus = U_INTERNAL_PROGRAM_ERROR; 571 } 572 } 573 } 574 int32_t run() { 575 int32_t trial; 576 int i; 577 UChar buf[100]; 578 if(U_SUCCESS(setupStatus)) { 579 for(i=0;i<U_LOTS_OF_TIMES;i++){ 580 trial = unum_formatInt64(fFmt,fExpect, buf, 100, NULL, &setupStatus); 581 } 582 } 583 return i; 584 } 585 virtual ~NumFmtInt64Test(){} 586 }; 587 588 /** 589 * unum_open .. with pattern, == new DecimalFormat(pattern) 590 */ 591 #define DO_NumFmtInt64Test(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kPattern); runTestOn(t); } 592 /** 593 * unum_open(UNUM_DECIMAL), then 594 */ 595 #define DO_NumFmtInt64Test_apply(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kApplyPattern); runTestOn(t); } 596 597 #define DO_NumFmtInt64Test_default(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kDefault); runTestOn(t); } 598 #define DO_NumFmtInt64Test_gr0(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kGroupOff); runTestOn(t); } 599 #define DO_NumFmtInt64Test_applygr0(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kApplyGroupOff); runTestOn(t); } 600 601 602 class NumFmtStringPieceTest : public HowExpensiveTest { 603 private: 604 const StringPiece &fExpect; 605 UNumberFormat *fFmt; 606 UnicodeString fPat; 607 UnicodeString fString; 608 const UChar *fStr; 609 int32_t fLen; 610 const char *fFile; 611 int fLine; 612 const char *fCPat; 613 const char *fCStr; 614 char name[100]; 615 public: 616 virtual const char *getName() { 617 if(name[0]==0) { 618 sprintf(name,"%s:p=|%s|,str=|%s|,sp=|%s|",getClassName(),fCPat,fCStr, fExpect.data()); 619 } 620 return name; 621 } 622 protected: 623 virtual UNumberFormat* initFmt() { 624 DecimalFormat *d = new DecimalFormat(setupStatus); 625 UParseError pe; 626 d->applyPattern(fPat, pe, setupStatus); 627 return (UNumberFormat*) d; 628 } 629 virtual const char *getClassName() { 630 return "NumFmtStringPieceTest"; 631 } 632 public: 633 NumFmtStringPieceTest(const char *pat, const char *num, const StringPiece& expect, const char *FILE, int LINE) 634 : HowExpensiveTest("(n/a)",FILE, LINE), 635 fExpect(expect), 636 fFmt(0), 637 fPat(pat, -1, US_INV), 638 fString(num,-1,US_INV), 639 fStr(fString.getTerminatedBuffer()), 640 fLen(u_strlen(fStr)), 641 fFile(FILE), 642 fLine(LINE), 643 fCPat(pat), 644 fCStr(num) 645 { 646 name[0]=0; 647 } 648 void warmup() { 649 fFmt = initFmt(); 650 UnicodeString buf; 651 if(U_SUCCESS(setupStatus)) { 652 buf.remove(); 653 ((const DecimalFormat*)fFmt)->format(fExpect, buf, NULL, setupStatus); 654 if(!U_SUCCESS(setupStatus) 655 || fString!=buf 656 ) { 657 char strBuf[200]; 658 u_strToUTF8(strBuf,200,NULL,buf.getTerminatedBuffer(),buf.length()+1,&setupStatus); 659 printf("%s:%d: warmup() %s got %s (len %d) expected %s (len %d), err %s\n", 660 fFile,fLine,getName(),strBuf,buf.length(),fCStr,fLen, u_errorName(setupStatus)); 661 setupStatus = U_INTERNAL_PROGRAM_ERROR; 662 } 663 } 664 } 665 666 int32_t run() { 667 #if U_DEBUG 668 int32_t trial; 669 #endif 670 int i=0; 671 UnicodeString buf; 672 if(U_SUCCESS(setupStatus)) { 673 for(i=0;i<U_LOTS_OF_TIMES;i++){ 674 buf.remove(); 675 ((const DecimalFormat*)fFmt)->format(fExpect, buf, NULL, setupStatus); 676 } 677 } 678 return i; 679 } 680 virtual ~NumFmtStringPieceTest(){} 681 }; 682 683 #define DO_NumFmtStringPieceTest(p,n,x) { NumFmtStringPieceTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } 684 685 // TODO: move, scope. 686 static UChar pattern[] = { 0x23 }; // '#' 687 static UChar strdot[] = { '2', '.', '0', 0 }; 688 static UChar strspc[] = { '2', ' ', 0 }; 689 static UChar strgrp[] = {'2',',','2','2','2', 0 }; 690 static UChar strbeng[] = {0x09E8,0x09E8,0x09E8,0x09E8, 0 }; 691 692 UNumberFormat *NumParseTest_fmt; 693 694 // TODO: de-uglify. 695 QuickTest(NumParseTest,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; static UChar str[] = { 0x31 };double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,str,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);}) 696 697 QuickTest(NumParseTestdot,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strdot,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);}) 698 QuickTest(NumParseTestspc,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strspc,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);}) 699 QuickTest(NumParseTestgrp,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strgrp,-1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);}) 700 701 QuickTest(NumParseTestbeng,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strbeng,-1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);}) 702 703 UDateFormat *DateFormatTest_fmt = NULL; 704 UDate sometime = 100000000.0; 705 UChar onekbuf[1024]; 706 const int32_t onekbuf_len = UPRV_LENGTHOF(onekbuf); 707 708 709 QuickTest(DateFormatTestBasic, \ 710 { \ 711 DateFormatTest_fmt = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &setupStatus); \ 712 }, \ 713 { \ 714 int i; \ 715 for(i=0;i<U_LOTS_OF_TIMES;i++) \ 716 { \ 717 udat_format(DateFormatTest_fmt, sometime, onekbuf, onekbuf_len, NULL, &setupStatus); \ 718 } \ 719 return i; \ 720 }, \ 721 { \ 722 udat_close(DateFormatTest_fmt); \ 723 } \ 724 ) 725 726 727 QuickTest(NullTest,{},{int j=U_LOTS_OF_TIMES;while(--j);return U_LOTS_OF_TIMES;},{}) 728 729 #if 0 730 #include <time.h> 731 732 QuickTest(RandomTest,{},{timespec ts; ts.tv_sec=rand()%4; int j=U_LOTS_OF_TIMES;while(--j) { ts.tv_nsec=100000+(rand()%10000)*1000000; nanosleep(&ts,NULL); return j;} return U_LOTS_OF_TIMES;},{}) 733 #endif 734 735 OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,TEST_LOCALE,0,&setupStatus),{}) 736 OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,TEST_LOCALE,0,&setupStatus),{}) 737 #if !UCONFIG_NO_CONVERSION 738 #include "unicode/ucnv.h" 739 OpenCloseTest(gb18030,ucnv,open,{},("gb18030",&setupStatus),{}) 740 #endif 741 #include "unicode/ures.h" 742 OpenCloseTest(root,ures,open,{},(NULL,"root",&setupStatus),{}) 743 744 void runTests() { 745 { 746 SieveTest t; 747 runTestOn(t); 748 } 749 #if 0 750 { 751 RandomTest t; 752 runTestOn(t); 753 } 754 #endif 755 { 756 NullTest t; 757 runTestOn(t); 758 } 759 760 #ifndef SKIP_DATEFMT_TESTS 761 { 762 DateFormatTestBasic t; 763 runTestOn(t); 764 } 765 #endif 766 767 #ifndef SKIP_NUMPARSE_TESTS 768 { 769 // parse tests 770 771 DO_NumTest("#","0",0.0); 772 DO_NumTest("#","2.0",2.0); 773 DO_NumTest("#","2 ",2); 774 DO_NumTest("#","-2 ",-2); 775 DO_NumTest("+#","+2",2); 776 DO_NumTest("#,###.0","2222.0",2222.0); 777 DO_NumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0); 778 DO_NumTest("#","123456",123456); 779 780 // attr 781 #ifdef HAVE_UNUM_MAYBE 782 DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_YES); 783 DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_NO); 784 DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE); 785 DO_TripleNumTest("#","2.0",2.0); 786 DO_AttrNumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0,UNUM_PARSE_ALL_INPUT,UNUM_NO); 787 #endif 788 789 790 // { NumParseTestgrp t; runTestOn(t); } 791 { NumParseTestbeng t; runTestOn(t); } 792 793 } 794 #endif 795 796 #ifndef SKIP_NUMFORMAT_TESTS 797 // format tests 798 { 799 800 DO_NumFmtInt64Test("0000","0001",1); 801 DO_NumFmtInt64Test("0000","0000",0); 802 StringPiece sp3456("3456"); 803 DO_NumFmtStringPieceTest("0000","3456",sp3456); 804 DO_NumFmtStringPieceTest("#","3456",sp3456); 805 StringPiece sp3("3"); 806 DO_NumFmtStringPieceTest("0000","0003",sp3); 807 DO_NumFmtStringPieceTest("#","3",sp3); 808 StringPiece spn3("-3"); 809 DO_NumFmtStringPieceTest("0000","-0003",spn3); 810 DO_NumFmtStringPieceTest("#","-3",spn3); 811 StringPiece spPI("123.456"); 812 DO_NumFmtStringPieceTest("#.0000","123.4560",spPI); 813 DO_NumFmtStringPieceTest("#.00","123.46",spPI); 814 815 DO_NumFmtTest("#","0",0.0); 816 DO_NumFmtTest("#","12345",12345); 817 DO_NumFmtTest("#","-2",-2); 818 DO_NumFmtTest("+#","+2",2); 819 820 DO_NumFmtInt64Test("#","-682",-682); 821 DO_NumFmtInt64Test("#","0",0); 822 DO_NumFmtInt64Test("#","12345",12345); 823 DO_NumFmtInt64Test("#,###","12,345",12345); 824 DO_NumFmtInt64Test("#","1234",1234); 825 DO_NumFmtInt64Test("#","123",123); 826 DO_NumFmtInt64Test("#,###","123",123); 827 DO_NumFmtInt64Test_apply("#","123",123); 828 DO_NumFmtInt64Test_apply("#","12345",12345); 829 DO_NumFmtInt64Test_apply("#,###","123",123); 830 DO_NumFmtInt64Test_apply("#,###","12,345",12345); 831 DO_NumFmtInt64Test_default("","123",123); 832 DO_NumFmtInt64Test_default("","12,345",12345); 833 DO_NumFmtInt64Test_applygr0("#","123",123); 834 DO_NumFmtInt64Test_applygr0("#","12345",12345); 835 DO_NumFmtInt64Test_applygr0("#,###","123",123); 836 DO_NumFmtInt64Test_applygr0("#,###","12345",12345); 837 DO_NumFmtInt64Test_gr0("#","123",123); 838 DO_NumFmtInt64Test_gr0("#","12345",12345); 839 DO_NumFmtInt64Test_gr0("#,###","123",123); 840 DO_NumFmtInt64Test_gr0("#,###","12345",12345); 841 DO_NumFmtInt64Test("#","-2",-2); 842 DO_NumFmtInt64Test("+#","+2",2); 843 } 844 845 #ifndef SKIP_NUM_OPEN_TEST 846 { 847 Test_unum_opendefault t; 848 runTestOn(t); 849 } 850 { 851 Test_unum_openpattern t; 852 runTestOn(t); 853 } 854 #endif 855 856 #endif /* skip numformat tests */ 857 #if !UCONFIG_NO_CONVERSION 858 { 859 Test_ucnv_opengb18030 t; 860 runTestOn(t); 861 } 862 #endif 863 { 864 Test_ures_openroot t; 865 runTestOn(t); 866 } 867 868 if(testhit==0) { 869 fprintf(stderr, "ERROR: no tests matched.\n"); 870 } 871 } 872