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