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