Home | History | Annotate | Download | only in iotest
      1 /*
      2 **********************************************************************
      3 *   Copyright (C) 2002-2010, International Business Machines
      4 *   Corporation and others.  All Rights Reserved.
      5 **********************************************************************
      6 *   file name:  iotest.cpp
      7 *   encoding:   US-ASCII
      8 *   tab size:   8 (not used)
      9 *   indentation:4
     10 *
     11 *   created on: 2002feb21
     12 *   created by: George Rhoten
     13 */
     14 
     15 
     16 #include "unicode/ustdio.h"
     17 #include "unicode/uclean.h"
     18 
     19 #include "unicode/ucnv.h"
     20 #include "unicode/uchar.h"
     21 #include "unicode/unistr.h"
     22 #include "unicode/ustring.h"
     23 #include "ustr_cnv.h"
     24 #include "iotest.h"
     25 #include "unicode/tstdtmod.h"
     26 #include "putilimp.h"
     27 
     28 #include <string.h>
     29 #include <stdlib.h>
     30 
     31 class DataDrivenLogger : public TestLog {
     32     static const char* fgDataDir;
     33     static char *fgTestDataPath;
     34 
     35 public:
     36     static void cleanUp() {
     37         if (fgTestDataPath) {
     38             free(fgTestDataPath);
     39             fgTestDataPath = NULL;
     40         }
     41     }
     42     virtual void errln( const UnicodeString &message ) {
     43         char buffer[4000];
     44         message.extract(0, message.length(), buffer, sizeof(buffer));
     45         buffer[3999] = 0; /* NULL terminate */
     46         log_err(buffer);
     47     }
     48 
     49     virtual void logln( const UnicodeString &message ) {
     50         char buffer[4000];
     51         message.extract(0, message.length(), buffer, sizeof(buffer));
     52         buffer[3999] = 0; /* NULL terminate */
     53         log_info(buffer);
     54     }
     55 
     56     virtual void dataerrln( const UnicodeString &message ) {
     57         char buffer[4000];
     58         message.extract(0, message.length(), buffer, sizeof(buffer));
     59         buffer[3999] = 0; /* NULL terminate */
     60         log_data_err(buffer);
     61     }
     62 
     63     static const char * pathToDataDirectory(void)
     64     {
     65 
     66         if(fgDataDir != NULL) {
     67             return fgDataDir;
     68         }
     69 
     70         /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
     71         //              to point to the top of the build hierarchy, which may or
     72         //              may not be the same as the source directory, depending on
     73         //              the configure options used.  At any rate,
     74         //              set the data path to the built data from this directory.
     75         //              The value is complete with quotes, so it can be used
     76         //              as-is as a string constant.
     77         */
     78     #if defined (U_TOPSRCDIR)
     79         {
     80             fgDataDir = U_TOPSRCDIR  U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
     81         }
     82     #else
     83 
     84         /* On Windows, the file name obtained from __FILE__ includes a full path.
     85         *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
     86         *             Change to    "wherever\icu\source\data"
     87         */
     88         {
     89             static char p[sizeof(__FILE__) + 10];
     90             char *pBackSlash;
     91             int i;
     92 
     93             strcpy(p, __FILE__);
     94             /* We want to back over three '\' chars.                            */
     95             /*   Only Windows should end up here, so looking for '\' is safe.   */
     96             for (i=1; i<=3; i++) {
     97                 pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
     98                 if (pBackSlash != NULL) {
     99                     *pBackSlash = 0;        /* Truncate the string at the '\'   */
    100                 }
    101             }
    102 
    103             if (pBackSlash != NULL) {
    104                 /* We found and truncated three names from the path.
    105                 *  Now append "source\data" and set the environment
    106                 */
    107                 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
    108                 fgDataDir = p;
    109             }
    110             else {
    111                 /* __FILE__ on MSVC7 does not contain the directory */
    112                 FILE *file = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
    113                 if (file) {
    114                     fclose(file);
    115                     fgDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
    116                 }
    117                 else {
    118                     fgDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
    119                 }
    120             }
    121         }
    122     #endif
    123 
    124         return fgDataDir;
    125 
    126     }
    127 
    128     static const char* loadTestData(UErrorCode& err){
    129         if( fgTestDataPath == NULL){
    130             const char*      directory=NULL;
    131             UResourceBundle* test =NULL;
    132             char* tdpath=NULL;
    133             const char* tdrelativepath;
    134 
    135 #if defined (U_TOPBUILDDIR)
    136             tdrelativepath = "test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
    137             directory = U_TOPBUILDDIR;
    138 #else
    139             tdrelativepath = ".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
    140             directory = pathToDataDirectory();
    141 #endif
    142 
    143             tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
    144 
    145 
    146             /* u_getDataDirectory shoul return \source\data ... set the
    147             * directory to ..\source\data\..\test\testdata\out\testdata
    148             */
    149             strcpy(tdpath, directory);
    150             strcat(tdpath, tdrelativepath);
    151             strcat(tdpath,"testdata");
    152 
    153             test=ures_open(tdpath, "testtypes", &err);
    154 
    155             if(U_FAILURE(err)){
    156                 err = U_FILE_ACCESS_ERROR;
    157                 log_data_err("Could not load testtypes.res in testdata bundle with path %s - %s\n", tdpath, u_errorName(err));
    158                 return "";
    159             }
    160             ures_close(test);
    161             fgTestDataPath = tdpath;
    162         }
    163         return fgTestDataPath;
    164     }
    165 
    166     virtual const char* getTestDataPath(UErrorCode& err) {
    167         return loadTestData(err);
    168     }
    169 };
    170 
    171 const char* DataDrivenLogger::fgDataDir = NULL;
    172 char* DataDrivenLogger::fgTestDataPath = NULL;
    173 
    174 static int64_t
    175 uto64(const UChar     *buffer)
    176 {
    177     int64_t result = 0;
    178     /* iterate through buffer */
    179     while(*buffer) {
    180         /* read the next digit */
    181         result *= 16;
    182         if (!u_isxdigit(*buffer)) {
    183             log_err("\\u%04X is not a valid hex digit for this test\n", (UChar)*buffer);
    184         }
    185         result += *buffer - 0x0030 - (*buffer >= 0x0041 ? (*buffer >= 0x0061 ? 39 : 7) : 0);
    186         buffer++;
    187     }
    188     return result;
    189 }
    190 
    191 
    192 U_CDECL_BEGIN
    193 static void U_CALLCONV DataDrivenPrintf(void)
    194 {
    195 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
    196     UErrorCode errorCode;
    197     TestDataModule *dataModule;
    198     TestData *testData;
    199     const DataMap *testCase;
    200     DataDrivenLogger logger;
    201     UChar uBuffer[512];
    202     char cBuffer[512];
    203     char cFormat[sizeof(cBuffer)];
    204     char cExpected[sizeof(cBuffer)];
    205     UnicodeString tempStr;
    206     UChar format[512];
    207     UChar expectedResult[512];
    208     UChar argument[512];
    209     int32_t i;
    210     int8_t i8;
    211     int16_t i16;
    212     int32_t i32;
    213     int64_t i64;
    214     double dbl;
    215     int32_t uBufferLenReturned;
    216 
    217     const char *fileLocale = "en_US_POSIX";
    218     int32_t uFileBufferLenReturned;
    219     LocalUFILEPointer testFile;
    220 
    221     errorCode=U_ZERO_ERROR;
    222     dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode);
    223     if(U_SUCCESS(errorCode)) {
    224         testData=dataModule->createTestData("printf", errorCode);
    225         if(U_SUCCESS(errorCode)) {
    226             for(i=0; testData->nextCase(testCase, errorCode); ++i) {
    227                 if(U_FAILURE(errorCode)) {
    228                     log_err("error retrieving icuio/printf test case %d - %s\n",
    229                             i, u_errorName(errorCode));
    230                     errorCode=U_ZERO_ERROR;
    231                     continue;
    232                 }
    233                 testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8"));
    234                 if (testFile.isNull()) {
    235                     log_err("Can't open test file - %s\n",
    236                             STANDARD_TEST_FILE);
    237                     continue;
    238                 }
    239                 u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0]));
    240                 uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0;
    241                 tempStr=testCase->getString("format", errorCode);
    242                 tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode);
    243                 tempStr=testCase->getString("result", errorCode);
    244                 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode);
    245                 tempStr=testCase->getString("argument", errorCode);
    246                 tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode);
    247                 u_austrncpy(cBuffer, format, sizeof(cBuffer));
    248                 if(U_FAILURE(errorCode)) {
    249                     log_err("error retrieving icuio/printf test case %d - %s\n",
    250                             i, u_errorName(errorCode));
    251                     errorCode=U_ZERO_ERROR;
    252                     continue;
    253                 }
    254                 log_verbose("Test %d: format=\"%s\"\n", i, cBuffer);
    255                 switch (testCase->getString("argumentType", errorCode)[0]) {
    256                 case 0x64:  // 'd' double
    257                     dbl = atof(u_austrcpy(cBuffer, argument));
    258                     uBufferLenReturned = u_sprintf_u(uBuffer, format, dbl);
    259                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, dbl);
    260                     break;
    261                 case 0x31:  // '1' int8_t
    262                     i8 = (int8_t)uto64(argument);
    263                     uBufferLenReturned = u_sprintf_u(uBuffer, format, i8);
    264                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i8);
    265                     break;
    266                 case 0x32:  // '2' int16_t
    267                     i16 = (int16_t)uto64(argument);
    268                     uBufferLenReturned = u_sprintf_u(uBuffer, format, i16);
    269                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i16);
    270                     break;
    271                 case 0x34:  // '4' int32_t
    272                     i32 = (int32_t)uto64(argument);
    273                     uBufferLenReturned = u_sprintf_u(uBuffer, format, i32);
    274                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i32);
    275                     break;
    276                 case 0x38:  // '8' int64_t
    277                     i64 = uto64(argument);
    278                     uBufferLenReturned = u_sprintf_u(uBuffer, format, i64);
    279                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i64);
    280                     break;
    281                 case 0x73:  // 's' char *
    282                     u_austrncpy(cBuffer, argument, sizeof(cBuffer));
    283                     uBufferLenReturned = u_sprintf_u(uBuffer, format, cBuffer);
    284                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, cBuffer);
    285                     break;
    286                 case 0x53:  // 'S' UChar *
    287                     uBufferLenReturned = u_sprintf_u(uBuffer, format, argument);
    288                     uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, argument);
    289                     break;
    290                 default:
    291                     uBufferLenReturned = 0;
    292                     uFileBufferLenReturned = 0;
    293                     log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
    294                 }
    295                 if (u_strcmp(uBuffer, expectedResult) != 0) {
    296                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    297                     u_austrncpy(cFormat, format, sizeof(cFormat));
    298                     u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
    299                     cBuffer[sizeof(cBuffer)-1] = 0;
    300                     log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
    301                             i, cFormat, cBuffer, cExpected);
    302                 }
    303                 if (uBufferLenReturned <= 0) {
    304                     log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
    305                             i, cBuffer);
    306                 }
    307                 else if (uBuffer[uBufferLenReturned-1] == 0
    308                     || uBuffer[uBufferLenReturned] != 0
    309                     || uBuffer[uBufferLenReturned+1] != 0x2A
    310                     || uBuffer[uBufferLenReturned+2] != 0x2A)
    311                 {
    312                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    313                     cBuffer[sizeof(cBuffer)-1] = 0;
    314                     log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
    315                             i, cBuffer, uBufferLenReturned);
    316                 }
    317                 testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8"));
    318                 if (testFile.isNull()) {
    319                     log_err("Can't open test file - %s\n",
    320                             STANDARD_TEST_FILE);
    321                 }
    322                 uBuffer[0]=0;
    323                 u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile.getAlias());
    324                 if (u_strcmp(uBuffer, expectedResult) != 0) {
    325                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    326                     u_austrncpy(cFormat, format, sizeof(cFormat));
    327                     u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
    328                     cBuffer[sizeof(cBuffer)-1] = 0;
    329                     log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
    330                             i, cFormat, cBuffer, cExpected);
    331                 }
    332                 if (uFileBufferLenReturned != uBufferLenReturned)
    333                 {
    334                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    335                     cBuffer[sizeof(cBuffer)-1] = 0;
    336                     log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
    337                             uFileBufferLenReturned, uBufferLenReturned);
    338                 }
    339 
    340                 if(U_FAILURE(errorCode)) {
    341                     log_err("error running icuio/printf test case %d - %s\n",
    342                             i, u_errorName(errorCode));
    343                     errorCode=U_ZERO_ERROR;
    344                     continue;
    345                 }
    346             }
    347             delete testData;
    348         }
    349         delete dataModule;
    350     }
    351     else {
    352         log_data_err("Failed: could not load test icuio data\n");
    353     }
    354 #endif
    355 }
    356 U_CDECL_END
    357 
    358 U_CDECL_BEGIN
    359 static void U_CALLCONV DataDrivenScanf(void)
    360 {
    361 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
    362     UErrorCode errorCode;
    363     TestDataModule *dataModule;
    364     TestData *testData;
    365     const DataMap *testCase;
    366     DataDrivenLogger logger;
    367     UChar uBuffer[512];
    368     char cBuffer[512];
    369     char cExpected[sizeof(cBuffer)];
    370     UnicodeString tempStr;
    371     UChar format[512];
    372     UChar expectedResult[512];
    373     UChar argument[512];
    374     int32_t i;
    375     int8_t i8, expected8;
    376     int16_t i16, expected16;
    377     int32_t i32, expected32;
    378     int64_t i64, expected64;
    379     double dbl, expectedDbl;
    380     volatile float flt, expectedFlt; // Use volatile in order to get around an Intel compiler issue.
    381     int32_t uBufferLenReturned;
    382 
    383     //const char *fileLocale = "en_US_POSIX";
    384     //int32_t uFileBufferLenReturned;
    385     //UFILE *testFile;
    386 
    387     errorCode=U_ZERO_ERROR;
    388     dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode);
    389     if(U_SUCCESS(errorCode)) {
    390         testData=dataModule->createTestData("scanf", errorCode);
    391         if(U_SUCCESS(errorCode)) {
    392             for(i=0; testData->nextCase(testCase, errorCode); ++i) {
    393                 if(U_FAILURE(errorCode)) {
    394                     log_err("error retrieving icuio/printf test case %d - %s\n",
    395                             i, u_errorName(errorCode));
    396                     errorCode=U_ZERO_ERROR;
    397                     continue;
    398                 }
    399 /*                testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
    400                 if (!testFile) {
    401                     log_err("Can't open test file - %s\n",
    402                             STANDARD_TEST_FILE);
    403                 }*/
    404                 u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0]));
    405                 uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0;
    406                 tempStr=testCase->getString("format", errorCode);
    407                 tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode);
    408                 tempStr=testCase->getString("result", errorCode);
    409                 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode);
    410                 tempStr=testCase->getString("argument", errorCode);
    411                 tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode);
    412                 u_austrncpy(cBuffer, format, sizeof(cBuffer));
    413                 if(U_FAILURE(errorCode)) {
    414                     log_err("error retrieving icuio/printf test case %d - %s\n",
    415                             i, u_errorName(errorCode));
    416                     errorCode=U_ZERO_ERROR;
    417                     continue;
    418                 }
    419                 log_verbose("Test %d: format=\"%s\"\n", i, cBuffer);
    420                 switch (testCase->getString("argumentType", errorCode)[0]) {
    421                 case 0x64:  // 'd' double
    422                     expectedDbl = atof(u_austrcpy(cBuffer, expectedResult));
    423                     uBufferLenReturned = u_sscanf_u(argument, format, &dbl);
    424                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, dbl);
    425                     if (dbl != expectedDbl) {
    426                         log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
    427                                 i, dbl, expectedDbl);
    428                     }
    429                     break;
    430                 case 0x66:  // 'f' float
    431                     expectedFlt = (float)atof(u_austrcpy(cBuffer, expectedResult));
    432                     uBufferLenReturned = u_sscanf_u(argument, format, &flt);
    433                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, flt);
    434                     if (flt != expectedFlt) {
    435                         log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
    436                                 i, flt, expectedFlt);
    437                     }
    438                     break;
    439                 case 0x31:  // '1' int8_t
    440                     expected8 = (int8_t)uto64(expectedResult);
    441                     uBufferLenReturned = u_sscanf_u(argument, format, &i8);
    442                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8);
    443                     if (i8 != expected8) {
    444                         log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n",
    445                                 i, i8, expected8);
    446                     }
    447                     break;
    448                 case 0x32:  // '2' int16_t
    449                     expected16 = (int16_t)uto64(expectedResult);
    450                     uBufferLenReturned = u_sscanf_u(argument, format, &i16);
    451                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16);
    452                     if (i16 != expected16) {
    453                         log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n",
    454                                 i, i16, expected16);
    455                     }
    456                     break;
    457                 case 0x34:  // '4' int32_t
    458                     expected32 = (int32_t)uto64(expectedResult);
    459                     uBufferLenReturned = u_sscanf_u(argument, format, &i32);
    460                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32);
    461                     if (i32 != expected32) {
    462                         log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n",
    463                                 i, i32, expected32);
    464                     }
    465                     break;
    466                 case 0x38:  // '8' int64_t
    467                     expected64 = uto64(expectedResult);
    468                     uBufferLenReturned = u_sscanf_u(argument, format, &i64);
    469                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, i64);
    470                     if (i64 != expected64) {
    471                         log_err("error in scanf 64-bit. Test case = %d\n", i);
    472                     }
    473                     break;
    474                 case 0x73:  // 's' char *
    475                     u_austrcpy(cExpected, expectedResult);
    476                     uBufferLenReturned = u_sscanf_u(argument, format, cBuffer);
    477                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
    478                     if (strcmp(cBuffer, cExpected) != 0) {
    479                         log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer, cExpected, i);
    480                     }
    481                     break;
    482                 case 0x53:  // 'S' UChar *
    483                     uBufferLenReturned = u_sscanf_u(argument, format, uBuffer);
    484                     //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
    485                     if (u_strcmp(uBuffer, expectedResult) != 0) {
    486                         u_austrcpy(cExpected, format);
    487                         u_austrcpy(cBuffer, uBuffer);
    488                         log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected, cBuffer, i);
    489                     }
    490                     break;
    491                 default:
    492                     uBufferLenReturned = 0;
    493                     //uFileBufferLenReturned = 0;
    494                     log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
    495                 }
    496                 if (uBufferLenReturned != 1) {
    497                     log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned, i);
    498                 }
    499 /*                if (u_strcmp(uBuffer, expectedResult) != 0) {
    500                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    501                     u_austrncpy(cFormat, format, sizeof(cFormat));
    502                     u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
    503                     cBuffer[sizeof(cBuffer)-1] = 0;
    504                     log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
    505                             i, cFormat, cBuffer, cExpected);
    506                 }
    507                 if (uBuffer[uBufferLenReturned-1] == 0
    508                     || uBuffer[uBufferLenReturned] != 0
    509                     || uBuffer[uBufferLenReturned+1] != 0x2A
    510                     || uBuffer[uBufferLenReturned+2] != 0x2A)
    511                 {
    512                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    513                     cBuffer[sizeof(cBuffer)-1] = 0;
    514                     log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
    515                             i, cBuffer, uBufferLenReturned);
    516                 }*/
    517 /*                u_fclose(testFile);
    518                 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
    519                 if (!testFile) {
    520                     log_err("Can't open test file - %s\n",
    521                             STANDARD_TEST_FILE);
    522                 }
    523                 uBuffer[0];
    524                 u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile);
    525                 if (u_strcmp(uBuffer, expectedResult) != 0) {
    526                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    527                     u_austrncpy(cFormat, format, sizeof(cFormat));
    528                     u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
    529                     cBuffer[sizeof(cBuffer)-1] = 0;
    530                     log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
    531                             i, cFormat, cBuffer, cExpected);
    532                 }
    533                 if (uFileBufferLenReturned != uBufferLenReturned)
    534                 {
    535                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    536                     cBuffer[sizeof(cBuffer)-1] = 0;
    537                     log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
    538                             uFileBufferLenReturned, uBufferLenReturned);
    539                 }
    540 */
    541                 if(U_FAILURE(errorCode)) {
    542                     log_err("error running icuio/printf test case %d - %s\n",
    543                             i, u_errorName(errorCode));
    544                     errorCode=U_ZERO_ERROR;
    545                     continue;
    546                 }
    547 //                u_fclose(testFile);
    548             }
    549             delete testData;
    550         }
    551         delete dataModule;
    552     }
    553     else {
    554         log_data_err("Failed: could not load test icuio data\n");
    555     }
    556 #endif
    557 }
    558 U_CDECL_END
    559 
    560 U_CDECL_BEGIN
    561 static void U_CALLCONV DataDrivenPrintfPrecision(void)
    562 {
    563 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
    564     UErrorCode errorCode;
    565     TestDataModule *dataModule;
    566     TestData *testData;
    567     const DataMap *testCase;
    568     DataDrivenLogger logger;
    569     UChar uBuffer[512];
    570     char cBuffer[512];
    571     char cFormat[sizeof(cBuffer)];
    572     char cExpected[sizeof(cBuffer)];
    573     UnicodeString tempStr;
    574     UChar format[512];
    575     UChar expectedResult[512];
    576     UChar argument[512];
    577     int32_t precision;
    578     int32_t i;
    579     int8_t i8;
    580     int16_t i16;
    581     int32_t i32;
    582     int64_t i64;
    583     double dbl;
    584     int32_t uBufferLenReturned;
    585 
    586     errorCode=U_ZERO_ERROR;
    587     dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode);
    588     if(U_SUCCESS(errorCode)) {
    589         testData=dataModule->createTestData("printfPrecision", errorCode);
    590         if(U_SUCCESS(errorCode)) {
    591             for(i=0; testData->nextCase(testCase, errorCode); ++i) {
    592                 if(U_FAILURE(errorCode)) {
    593                     log_err("error retrieving icuio/printf test case %d - %s\n",
    594                             i, u_errorName(errorCode));
    595                     errorCode=U_ZERO_ERROR;
    596                     continue;
    597                 }
    598                 u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0]));
    599                 uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0;
    600                 tempStr=testCase->getString("format", errorCode);
    601                 tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode);
    602                 tempStr=testCase->getString("result", errorCode);
    603                 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode);
    604                 tempStr=testCase->getString("argument", errorCode);
    605                 tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode);
    606                 precision=testCase->getInt28("precision", errorCode);
    607                 u_austrncpy(cBuffer, format, sizeof(cBuffer));
    608                 if(U_FAILURE(errorCode)) {
    609                     log_err("error retrieving icuio/printf test case %d - %s\n",
    610                             i, u_errorName(errorCode));
    611                     errorCode=U_ZERO_ERROR;
    612                     continue;
    613                 }
    614                 log_verbose("Test %d: format=\"%s\"\n", i, cBuffer);
    615                 switch (testCase->getString("argumentType", errorCode)[0]) {
    616                 case 0x64:  // 'd' double
    617                     dbl = atof(u_austrcpy(cBuffer, argument));
    618                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, dbl);
    619                     break;
    620                 case 0x31:  // '1' int8_t
    621                     i8 = (int8_t)uto64(argument);
    622                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i8);
    623                     break;
    624                 case 0x32:  // '2' int16_t
    625                     i16 = (int16_t)uto64(argument);
    626                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i16);
    627                     break;
    628                 case 0x34:  // '4' int32_t
    629                     i32 = (int32_t)uto64(argument);
    630                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i32);
    631                     break;
    632                 case 0x38:  // '8' int64_t
    633                     i64 = uto64(argument);
    634                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i64);
    635                     break;
    636                 case 0x73:  // 's' char *
    637                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    638                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, cBuffer);
    639                     break;
    640                 case 0x53:  // 'S' UChar *
    641                     uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, argument);
    642                     break;
    643                 default:
    644                     uBufferLenReturned = 0;
    645                     log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
    646                 }
    647                 if (u_strcmp(uBuffer, expectedResult) != 0) {
    648                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    649                     u_austrncpy(cFormat, format, sizeof(cFormat));
    650                     u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
    651                     cBuffer[sizeof(cBuffer)-1] = 0;
    652                     log_err("FAILURE test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
    653                             i, cFormat, cBuffer, cExpected);
    654                 }
    655                 if (uBufferLenReturned <= 0) {
    656                     log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
    657                             i, cBuffer);
    658                 }
    659                 else if (uBuffer[uBufferLenReturned-1] == 0
    660                     || uBuffer[uBufferLenReturned] != 0
    661                     || uBuffer[uBufferLenReturned+1] != 0x2A
    662                     || uBuffer[uBufferLenReturned+2] != 0x2A)
    663                 {
    664                     u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
    665                     cBuffer[sizeof(cBuffer)-1] = 0;
    666                     log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
    667                             i, cBuffer, uBufferLenReturned);
    668                 }
    669                 if(U_FAILURE(errorCode)) {
    670                     log_err("error running icuio/printf test case %d - %s\n",
    671                             i, u_errorName(errorCode));
    672                     errorCode=U_ZERO_ERROR;
    673                     continue;
    674                 }
    675             }
    676             delete testData;
    677         }
    678         delete dataModule;
    679     }
    680     else {
    681         log_data_err("Failed: could not load test icuio data\n");
    682     }
    683 #endif
    684 }
    685 U_CDECL_END
    686 
    687 static void addAllTests(TestNode** root) {
    688     addFileTest(root);
    689     addStringTest(root);
    690     addTranslitTest(root);
    691 
    692 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_LEGACY_CONVERSION
    693     addTest(root, &DataDrivenPrintf, "datadriv/DataDrivenPrintf");
    694     addTest(root, &DataDrivenPrintfPrecision, "datadriv/DataDrivenPrintfPrecision");
    695     addTest(root, &DataDrivenScanf, "datadriv/DataDrivenScanf");
    696 #endif
    697 #if U_IOSTREAM_SOURCE
    698     addStreamTests(root);
    699 #endif
    700 }
    701 
    702 /* returns the path to icu/source/data/out */
    703 static const char *ctest_dataOutDir()
    704 {
    705     static const char *dataOutDir = NULL;
    706 
    707     if(dataOutDir) {
    708         return dataOutDir;
    709     }
    710 
    711     /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
    712     //              to point to the top of the build hierarchy, which may or
    713     //              may not be the same as the source directory, depending on
    714     //              the configure options used.  At any rate,
    715     //              set the data path to the built data from this directory.
    716     //              The value is complete with quotes, so it can be used
    717     //              as-is as a string constant.
    718     */
    719 #if defined (U_TOPBUILDDIR)
    720     {
    721         dataOutDir = U_TOPBUILDDIR "data"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
    722     }
    723 #else
    724 
    725     /* On Windows, the file name obtained from __FILE__ includes a full path.
    726      *             This file is "wherever\icu\source\test\cintltst\cintltst.c"
    727      *             Change to    "wherever\icu\source\data"
    728      */
    729     {
    730         static char p[sizeof(__FILE__) + 20];
    731         char *pBackSlash;
    732         int i;
    733 
    734         strcpy(p, __FILE__);
    735         /* We want to back over three '\' chars.                            */
    736         /*   Only Windows should end up here, so looking for '\' is safe.   */
    737         for (i=1; i<=3; i++) {
    738             pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
    739             if (pBackSlash != NULL) {
    740                 *pBackSlash = 0;        /* Truncate the string at the '\'   */
    741             }
    742         }
    743 
    744         if (pBackSlash != NULL) {
    745             /* We found and truncated three names from the path.
    746              *  Now append "source\data" and set the environment
    747              */
    748             strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
    749             dataOutDir = p;
    750         }
    751         else {
    752             /* __FILE__ on MSVC7 does not contain the directory */
    753             FILE *file = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
    754             if (file) {
    755                 fclose(file);
    756                 dataOutDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
    757             }
    758             else {
    759                 dataOutDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
    760             }
    761         }
    762     }
    763 #endif
    764 
    765     return dataOutDir;
    766 }
    767 
    768 /*  ctest_setICU_DATA  - if the ICU_DATA environment variable is not already
    769  *                       set, try to deduce the directory in which ICU was built,
    770  *                       and set ICU_DATA to "icu/source/data" in that location.
    771  *                       The intent is to allow the tests to have a good chance
    772  *                       of running without requiring that the user manually set
    773  *                       ICU_DATA.  Common data isn't a problem, since it is
    774  *                       picked up via a static (build time) reference, but the
    775  *                       tests dynamically load some data.
    776  */
    777 static void ctest_setICU_DATA() {
    778 
    779     /* No location for the data dir was identifiable.
    780      *   Add other fallbacks for the test data location here if the need arises
    781      */
    782     if (getenv("ICU_DATA") == NULL) {
    783         /* If ICU_DATA isn't set, set it to the usual location */
    784         u_setDataDirectory(ctest_dataOutDir());
    785     }
    786 }
    787 
    788 U_CDECL_BEGIN
    789 /*
    790  * Note: this assumes that context is a pointer to STANDARD_TEST_FILE. It would be
    791  * cleaner to define an acutal context with a string pointer in it and set STANDARD_TEST_FILE
    792  * after the call to initArgs()...
    793  */
    794 static int U_CALLCONV argHandler(int arg, int /*argc*/, const char * const argv[], void *context)
    795 {
    796     const char **str = (const char **) context;
    797 
    798     if (argv[arg][0] != '/' && argv[arg][0] != '-') {
    799         *str = argv[arg];
    800         return 1;
    801     }
    802 
    803     return 0;
    804 }
    805 U_CDECL_END
    806 
    807 int main(int argc, char* argv[])
    808 {
    809     int32_t nerrors = 0;
    810     TestNode *root = NULL;
    811     UErrorCode errorCode = U_ZERO_ERROR;
    812     UDate startTime, endTime;
    813     int32_t diffTime;
    814 
    815     startTime = uprv_getRawUTCtime();
    816 
    817     /* Check whether ICU will initialize without forcing the build data directory into
    818     *  the ICU_DATA path.  Success here means either the data dll contains data, or that
    819     *  this test program was run with ICU_DATA set externally.  Failure of this check
    820     *  is normal when ICU data is not packaged into a shared library.
    821     *
    822     *  Whether or not this test succeeds, we want to cleanup and reinitialize
    823     *  with a data path so that data loading from individual files can be tested.
    824     */
    825     u_init(&errorCode);
    826     if (U_FAILURE(errorCode)) {
    827         fprintf(stderr,
    828             "#### Note:  ICU Init without build-specific setDataDirectory() failed.\n");
    829     }
    830     u_cleanup();
    831     errorCode = U_ZERO_ERROR;
    832     if (!initArgs(argc, argv, argHandler, (void *) &STANDARD_TEST_FILE)) {
    833         /* Error already displayed. */
    834         return -1;
    835     }
    836 
    837     /* Initialize ICU */
    838     ctest_setICU_DATA();    /* u_setDataDirectory() must happen Before u_init() */
    839     u_init(&errorCode);
    840     if (U_FAILURE(errorCode)) {
    841         fprintf(stderr,
    842             "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
    843             "*** Check the ICU_DATA environment variable and \n"
    844             "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
    845         return 1;
    846     }
    847 
    848     fprintf(stdout, "Default charset for this run is %s\n", ucnv_getDefaultName());
    849 
    850     addAllTests(&root);
    851     nerrors = runTestRequest(root, argc, argv);
    852 
    853 #if 1
    854     {
    855         FILE* fileToRemove = fopen(STANDARD_TEST_FILE, "r");
    856         /* This should delete any temporary files. */
    857         if (fileToRemove) {
    858             fclose(fileToRemove);
    859             log_verbose("Deleting: %s\n", STANDARD_TEST_FILE);
    860             if (remove(STANDARD_TEST_FILE) != 0) {
    861                 /* Maybe someone didn't close the file correctly. */
    862                 fprintf(stderr, "FAIL: Could not delete %s\n", STANDARD_TEST_FILE);
    863                 nerrors += 1;
    864             }
    865         }
    866     }
    867 #endif
    868 
    869     cleanUpTestTree(root);
    870     DataDrivenLogger::cleanUp();
    871     u_cleanup();
    872 
    873     endTime = uprv_getRawUTCtime();
    874     diffTime = (int32_t)(endTime - startTime);
    875     printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
    876         (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
    877         (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
    878         (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
    879         (int)(diffTime%U_MILLIS_PER_SECOND));
    880 
    881     return nerrors;
    882 }
    883