/* *********************************************************************** * © 2016 and later: Unicode, Inc. and others. * License & terms of use: http://www.unicode.org/copyright.html *********************************************************************** *********************************************************************** * Copyright (c) 2011-2016,International Business Machines * Corporation and others. All Rights Reserved. *********************************************************************** */ #include #include #include "cmemory.h" #include "sieve.h" #include "unicode/utimer.h" #include "udbgutil.h" #include "unicode/ustring.h" #include "unicode/decimfmt.h" #include "unicode/udat.h" U_NAMESPACE_USE #if U_PLATFORM_IMPLEMENTS_POSIX #include static void usage(const char *prog) { fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog); } #endif void runTests(void); #ifndef ITERATIONS #define ITERATIONS 5 #endif #ifndef TEST_LOCALE #define TEST_LOCALE "en_US" #endif FILE *out = NULL; UErrorCode setupStatus = U_ZERO_ERROR; const char *outName = NULL; int listmode = 0; const char *testName = NULL; const char *progname = NULL; int errflg = 0; int testhit = 0; int testMatch(const char *aName) { if(testName==NULL) return 1; int len = strlen(testName); if(testName[len-1]=='*') { return strncmp(testName,aName,len-1); } else { return strcmp(testName,aName); } } int main(int argc, char * const * argv){ #if U_DEBUG fprintf(stderr,"%s: warning: U_DEBUG is on.\n", argv[0]); #endif #if U_DEBUG { double m; double s = uprv_getSieveTime(&m); fprintf(stderr, "** Standard sieve time: %.9fs +/- %.9fs (%d iterations)\n", s,m, (int)U_LOTS_OF_TIMES); } #endif #if U_PLATFORM_IMPLEMENTS_POSIX int c; //extern int optind; extern char *optarg; while((c=getopt(argc,argv,"lf:t:")) != EOF) { switch(c) { case 'f': outName = optarg; break; case 'l': listmode++; break; case 't': testName = optarg; break; case '?': errflg++; } if(errflg) { usage(progname); return 0; } } /* for ( ; optind < argc; optind++) { ... argv[optind] } */ #else if(argc==2) { outName = argv[1]; } else if(argc>2) { fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]); } #endif if(listmode && outName != NULL ) { fprintf(stderr, "Warning: no output when list mode\n"); outName=NULL; } if(outName != NULL) { out=fopen(outName,"w"); if(out==NULL) { fprintf(stderr,"Err: can't open %s for writing.\n", outName); return 1; } else { fprintf(stderr, "# writing results to %s\n", outName); } fprintf(out, "\n"); fprintf(out, "\n", U_ICU_VERSION); fprintf(out, "\n", U_COPYRIGHT_STRING); } else { fprintf(stderr, "# (no output)\n"); } if(listmode && testName!=NULL) { fprintf(stderr, "ERR: no -l mode when specific test with -t\n"); usage(progname); return 1; } runTests(); if(out!=NULL) { #ifndef SKIP_INFO udbg_writeIcuInfo(out); #endif fprintf(out, "\n"); fclose(out); } if(U_FAILURE(setupStatus)) { fprintf(stderr, "Error in tests: %s\n", u_errorName(setupStatus)); return 1; } return 0; } class HowExpensiveTest { public: virtual ~HowExpensiveTest(){} protected: HowExpensiveTest(const char *name, const char *file, int32_t line) : fName(name), fFile(file), fLine(line) {} protected: /** * @return number of iterations */ virtual int32_t run() = 0; virtual void warmup() { run(); } public: virtual const char *getName() { return fName; } public: virtual int32_t runTest(double *subTime) { UTimer a,b; utimer_getTime(&a); int32_t iter = run(); utimer_getTime(&b); *subTime = utimer_getDeltaSeconds(&a,&b); return iter; } virtual int32_t runTests(double *subTime, double *marginOfError) { warmup(); /* warmup */ double times[ITERATIONS]; int subIterations = 0; for(int i=0;i\n", tn,stn,st,me,iter); fflush(out); } } /* ------------------- test code here --------------------- */ class SieveTest : public HowExpensiveTest { public: virtual ~SieveTest(){} SieveTest():HowExpensiveTest("SieveTest",__FILE__,__LINE__){} virtual int32_t run(){return 0;} // dummy int32_t runTest(double *subTime) { *subTime = uprv_getSieveTime(NULL); return U_LOTS_OF_TIMES; } virtual int32_t runTests(double *subTime, double *marginOfError) { *subTime = uprv_getSieveTime(marginOfError); return U_LOTS_OF_TIMES; } }; /* ------- NumParseTest ------------- */ #include "unicode/unum.h" /* open and close tests */ #define OCName(svc,ub,testn,suffix,n) testn ## svc ## ub ## suffix ## n #define OCStr(svc,ub,suffix,n) "Test_" # svc # ub # suffix # n #define OCRun(svc,ub,suffix) svc ## ub ## suffix // TODO: run away screaming #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;iapplyPattern(fPat, pe, setupStatus); return (UNumberFormat*) d; } virtual const char *getClassName() { return "NumFmtStringPieceTest"; } public: NumFmtStringPieceTest(const char *pat, const char *num, const StringPiece& expect, const char *FILE, int LINE) : HowExpensiveTest("(n/a)",FILE, LINE), fExpect(expect), fFmt(0), fPat(pat, -1, US_INV), fString(num,-1,US_INV), fStr(fString.getTerminatedBuffer()), fLen(u_strlen(fStr)), fFile(FILE), fLine(LINE), fCPat(pat), fCStr(num) { name[0]=0; } void warmup() { fFmt = initFmt(); UnicodeString buf; if(U_SUCCESS(setupStatus)) { buf.remove(); ((const DecimalFormat*)fFmt)->format(fExpect, buf, NULL, setupStatus); if(!U_SUCCESS(setupStatus) || fString!=buf ) { char strBuf[200]; u_strToUTF8(strBuf,200,NULL,buf.getTerminatedBuffer(),buf.length()+1,&setupStatus); printf("%s:%d: warmup() %s got %s (len %d) expected %s (len %d), err %s\n", fFile,fLine,getName(),strBuf,buf.length(),fCStr,fLen, u_errorName(setupStatus)); setupStatus = U_INTERNAL_PROGRAM_ERROR; } } } int32_t run() { #if U_DEBUG int32_t trial; #endif int i=0; UnicodeString buf; if(U_SUCCESS(setupStatus)) { for(i=0;iformat(fExpect, buf, NULL, setupStatus); } } return i; } virtual ~NumFmtStringPieceTest(){} }; #define DO_NumFmtStringPieceTest(p,n,x) { NumFmtStringPieceTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); } // TODO: move, scope. static UChar pattern[] = { 0x23 }; // '#' static UChar strdot[] = { '2', '.', '0', 0 }; static UChar strspc[] = { '2', ' ', 0 }; static UChar strgrp[] = {'2',',','2','2','2', 0 }; static UChar strbeng[] = {0x09E8,0x09E8,0x09E8,0x09E8, 0 }; UNumberFormat *NumParseTest_fmt; // TODO: de-uglify. QuickTest(NumParseTest,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; static UChar str[] = { 0x31 };double val; for(i=0;i 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;},{}) #endif OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,TEST_LOCALE,0,&setupStatus),{}) OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,TEST_LOCALE,0,&setupStatus),{}) #if !UCONFIG_NO_CONVERSION #include "unicode/ucnv.h" OpenCloseTest(gb18030,ucnv,open,{},("gb18030",&setupStatus),{}) #endif #include "unicode/ures.h" OpenCloseTest(root,ures,open,{},(NULL,"root",&setupStatus),{}) void runTests() { { SieveTest t; runTestOn(t); } #if 0 { RandomTest t; runTestOn(t); } #endif { NullTest t; runTestOn(t); } #ifndef SKIP_DATEFMT_TESTS { DateFormatTestBasic t; runTestOn(t); } #endif #ifndef SKIP_NUMPARSE_TESTS { // parse tests DO_NumTest("#","0",0.0); DO_NumTest("#","2.0",2.0); DO_NumTest("#","2 ",2); DO_NumTest("#","-2 ",-2); DO_NumTest("+#","+2",2); DO_NumTest("#,###.0","2222.0",2222.0); DO_NumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0); DO_NumTest("#","123456",123456); // attr #ifdef HAVE_UNUM_MAYBE DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_YES); DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_NO); DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE); DO_TripleNumTest("#","2.0",2.0); DO_AttrNumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0,UNUM_PARSE_ALL_INPUT,UNUM_NO); #endif // { NumParseTestgrp t; runTestOn(t); } { NumParseTestbeng t; runTestOn(t); } } #endif #ifndef SKIP_NUMFORMAT_TESTS // format tests { DO_NumFmtInt64Test("0000","0001",1); DO_NumFmtInt64Test("0000","0000",0); StringPiece sp3456("3456"); DO_NumFmtStringPieceTest("0000","3456",sp3456); DO_NumFmtStringPieceTest("#","3456",sp3456); StringPiece sp3("3"); DO_NumFmtStringPieceTest("0000","0003",sp3); DO_NumFmtStringPieceTest("#","3",sp3); StringPiece spn3("-3"); DO_NumFmtStringPieceTest("0000","-0003",spn3); DO_NumFmtStringPieceTest("#","-3",spn3); StringPiece spPI("123.456"); DO_NumFmtStringPieceTest("#.0000","123.4560",spPI); DO_NumFmtStringPieceTest("#.00","123.46",spPI); DO_NumFmtTest("#","0",0.0); DO_NumFmtTest("#","12345",12345); DO_NumFmtTest("#","-2",-2); DO_NumFmtTest("+#","+2",2); DO_NumFmtInt64Test("#","-682",-682); DO_NumFmtInt64Test("#","0",0); DO_NumFmtInt64Test("#","12345",12345); DO_NumFmtInt64Test("#,###","12,345",12345); DO_NumFmtInt64Test("#","1234",1234); DO_NumFmtInt64Test("#","123",123); DO_NumFmtInt64Test("#,###","123",123); DO_NumFmtInt64Test_apply("#","123",123); DO_NumFmtInt64Test_apply("#","12345",12345); DO_NumFmtInt64Test_apply("#,###","123",123); DO_NumFmtInt64Test_apply("#,###","12,345",12345); DO_NumFmtInt64Test_default("","123",123); DO_NumFmtInt64Test_default("","12,345",12345); DO_NumFmtInt64Test_applygr0("#","123",123); DO_NumFmtInt64Test_applygr0("#","12345",12345); DO_NumFmtInt64Test_applygr0("#,###","123",123); DO_NumFmtInt64Test_applygr0("#,###","12345",12345); DO_NumFmtInt64Test_gr0("#","123",123); DO_NumFmtInt64Test_gr0("#","12345",12345); DO_NumFmtInt64Test_gr0("#,###","123",123); DO_NumFmtInt64Test_gr0("#,###","12345",12345); DO_NumFmtInt64Test("#","-2",-2); DO_NumFmtInt64Test("+#","+2",2); } #ifndef SKIP_NUM_OPEN_TEST { Test_unum_opendefault t; runTestOn(t); } { Test_unum_openpattern t; runTestOn(t); } #endif #endif /* skip numformat tests */ #if !UCONFIG_NO_CONVERSION { Test_ucnv_opengb18030 t; runTestOn(t); } #endif { Test_ures_openroot t; runTestOn(t); } if(testhit==0) { fprintf(stderr, "ERROR: no tests matched.\n"); } }