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
20static void usage(const char *prog) {
21  fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog);
22}
23#endif
24
25void runTests(void);
26
27#ifndef ITERATIONS
28#define ITERATIONS 5
29#endif
30
31
32FILE *out = NULL;
33UErrorCode setupStatus = U_ZERO_ERROR;
34const char *outName = NULL;
35int listmode = 0;
36const char *testName = NULL;
37const char *progname = NULL;
38int errflg = 0;
39int testhit = 0;
40
41int 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
51int 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
143class HowExpensiveTest {
144public:
145  virtual ~HowExpensiveTest(){}
146protected:
147  HowExpensiveTest(const char *name, const char *file, int32_t line) : fName(name), fFile(file), fLine(line) {}
148protected:
149  /**
150   * @return number of iterations
151   */
152  virtual int32_t run() = 0;
153  virtual void warmup() {  run(); }
154public:
155  virtual const char *getName() { return fName; }
156public:
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  }
181public:
182  const char *fName;
183  const char *fFile;
184  int32_t fLine;
185  int32_t fIterations;
186};
187
188void 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
227class SieveTest : public HowExpensiveTest {
228public:
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
253class NumTest : public HowExpensiveTest {
254private:
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];
266public:
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  }
273protected:
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  }
280public:
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
321class AttrNumTest : public NumTest
322{
323private:
324  UNumberFormatAttribute fAttr;
325  int32_t fAttrValue;
326  char name2[100];
327protected:
328  virtual const char *getClassName() {
329    sprintf(name2,"AttrNumTest:%d=%d", fAttr,fAttrValue);
330    return name2;
331  }
332public:
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
349class NOXNumTest : public NumTest
350{
351private:
352  UNumberFormatAttribute fAttr;
353  int32_t fAttrValue;
354  char name2[100];
355protected:
356  virtual const char *getClassName() {
357    sprintf(name2,"NOXNumTest:%d=%d", fAttr,fAttrValue);
358    return name2;
359  }
360public:
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
381class NumFmtTest : public HowExpensiveTest {
382private:
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];
394public:
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  }
401protected:
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  }
408public:
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
458class NumFmtInt64Test : public HowExpensiveTest {
459private:
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];
471public:
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  }
478protected:
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  }
485public:
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
535class NumFmtStringPieceTest : public HowExpensiveTest {
536private:
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];
548public:
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  }
555protected:
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  }
565public:
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.
617static UChar pattern[] = { 0x23 }; // '#'
618static UChar strdot[] = { '2', '.', '0', 0 };
619static UChar strspc[] = { '2', ' ', 0 };
620static UChar strgrp[] = {'2',',','2','2','2', 0 };
621static UChar strbeng[] = {0x09E8,0x09E8,0x09E8,0x09E8, 0 };
622
623UNumberFormat *NumParseTest_fmt;
624
625// TODO: de-uglify.
626QuickTest(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
628QuickTest(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);})
629QuickTest(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);})
630QuickTest(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
632QuickTest(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
634UDateFormat *DateFormatTest_fmt = NULL;
635UDate sometime = 100000000.0;
636UChar onekbuf[1024];
637const int32_t onekbuf_len = sizeof(onekbuf)/sizeof(onekbuf[0]);
638
639
640QuickTest(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
658QuickTest(NullTest,{},{int j=U_LOTS_OF_TIMES;while(--j);return U_LOTS_OF_TIMES;},{})
659
660#if 0
661#include <time.h>
662
663QuickTest(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
666OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,"en_US",0,&setupStatus),{})
667OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,"en_US",0,&setupStatus),{})
668#if !UCONFIG_NO_CONVERSION
669#include "unicode/ucnv.h"
670OpenCloseTest(gb18030,ucnv,open,{},("gb18030",&setupStatus),{})
671#endif
672#include "unicode/ures.h"
673OpenCloseTest(root,ures,open,{},(NULL,"root",&setupStatus),{})
674
675void 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