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(&times[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