| OLD | NEW |
| (Empty) |
| 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 o
n | |
| 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 "da
ta" 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_STRI
NG "out" U_FILE_SEP_STRING; | |
| 137 directory = U_TOPBUILDDIR; | |
| 138 #else | |
| 139 tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "te
stdata" 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 wi
th 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 ? 3
9 : 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", fileLocal
e, "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]), errorC
ode); | |
| 244 tempStr=testCase->getString("result", errorCode); | |
| 245 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(ex
pectedResult[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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, cBuffer); | |
| 286 break; | |
| 287 case 0x53: // 'S' UChar * | |
| 288 uBufferLenReturned = u_sprintf_u(uBuffer, format, argument); | |
| 289 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), fo
rmat, 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\" Ex
pected: \"%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 chara
cters was written. Got %d.\n", | |
| 316 i, cBuffer, uBufferLenReturned); | |
| 317 } | |
| 318 testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "r", fileLocal
e, "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.ge
tAlias()); | |
| 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\" Expe
cted: \"%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) != uBufferLenRet
urned(%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 I
ntel 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]), errorC
ode); | |
| 409 tempStr=testCase->getString("result", errorCode); | |
| 410 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(ex
pectedResult[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: %02
X\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: %04
X\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: %08
X\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, cBuf
fer); | |
| 479 if (strcmp(cBuffer, cExpected) != 0) { | |
| 480 log_err("error in scanf char * string. Got \"%s\" Expect
ed \"%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, argu
ment); | |
| 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\". T
est 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\" Ex
pected: \"%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 chara
cters 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\" Expe
cted: \"%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) != uBufferLenRet
urned(%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]), errorC
ode); | |
| 603 tempStr=testCase->getString("result", errorCode); | |
| 604 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(ex
pectedResult[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 chara
cters 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/DataDrivenPrintfPrecisio
n"); | |
| 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 an
d 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_STR
ING; | |
| 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 "da
ta" 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 STAND
ARD_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 director
y 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() fail
ed.\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_FIL
E); | |
| 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 } | |
| OLD | NEW |