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