OLD | NEW |
(Empty) | |
| 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 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 "d
ata" 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"testda
ta"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 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 ? 3
9 : 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", fileLocal
e, "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]), errorC
ode); |
| 243 tempStr=testCase->getString("result", errorCode); |
| 244 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(ex
pectedResult[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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, 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(), fo
rmat, cBuffer); |
| 285 break; |
| 286 case 0x53: // 'S' UChar * |
| 287 uBufferLenReturned = u_sprintf_u(uBuffer, format, argument); |
| 288 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), fo
rmat, 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\" Ex
pected: \"%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 chara
cters was written. Got %d.\n", |
| 315 i, cBuffer, uBufferLenReturned); |
| 316 } |
| 317 testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "r", fileLocal
e, "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.ge
tAlias()); |
| 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\" Expe
cted: \"%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) != uBufferLenRet
urned(%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 I
ntel 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]), errorC
ode); |
| 408 tempStr=testCase->getString("result", errorCode); |
| 409 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(ex
pectedResult[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: %02
X\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: %04
X\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: %08
X\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, cBuf
fer); |
| 478 if (strcmp(cBuffer, cExpected) != 0) { |
| 479 log_err("error in scanf char * string. Got \"%s\" Expect
ed \"%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, argu
ment); |
| 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\". T
est 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\" Ex
pected: \"%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 chara
cters 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\" Expe
cted: \"%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) != uBufferLenRet
urned(%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]), errorC
ode); |
| 602 tempStr=testCase->getString("result", errorCode); |
| 603 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(ex
pectedResult[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 chara
cters 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/DataDrivenPrintfPrecisio
n"); |
| 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 an
d 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_FIL
E_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 STAND
ARD_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 director
y 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() fail
ed.\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_FIL
E); |
| 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 } |
OLD | NEW |