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