2 **********************************************************************
3 * Copyright (C) 2002-2011, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 * file name: iotest.cpp
8 * tab size: 8 (not used)
11 * created on: 2002feb21
12 * created by: George Rhoten
16 #include "unicode/ustdio.h"
17 #include "unicode/uclean.h"
19 #include "unicode/ucnv.h"
20 #include "unicode/uchar.h"
21 #include "unicode/unistr.h"
22 #include "unicode/ustring.h"
25 #include "unicode/tstdtmod.h"
31 class DataDrivenLogger
: public TestLog
{
32 static const char* fgDataDir
;
33 static char *fgTestDataPath
;
36 static void cleanUp() {
39 fgTestDataPath
= NULL
;
42 virtual void errln( const UnicodeString
&message
) {
44 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
45 buffer
[3999] = 0; /* NULL terminate */
49 virtual void logln( const UnicodeString
&message
) {
51 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
52 buffer
[3999] = 0; /* NULL terminate */
56 virtual void dataerrln( const UnicodeString
&message
) {
58 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
59 buffer
[3999] = 0; /* NULL terminate */
63 static const char * pathToDataDirectory(void)
66 if(fgDataDir
!= NULL
) {
70 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
71 // to point to the top of the build hierarchy, which may or
72 // may not be the same as the source directory, depending on
73 // the configure options used. At any rate,
74 // set the data path to the built data from this directory.
75 // The value is complete with quotes, so it can be used
76 // as-is as a string constant.
78 #if defined (U_TOPSRCDIR)
80 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
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"
89 static char p
[sizeof(__FILE__
) + 10];
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 '\' */
103 if (pBackSlash
!= NULL
) {
104 /* We found and truncated three names from the path.
105 * Now append "source\data" and set the environment
107 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
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");
115 fgDataDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
118 fgDataDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
128 static const char* loadTestData(UErrorCode
& err
){
129 if( fgTestDataPath
== NULL
){
130 const char* directory
=NULL
;
131 UResourceBundle
* test
=NULL
;
133 const char* tdrelativepath
;
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
;
139 tdrelativepath
= ".."U_FILE_SEP_STRING
"test"U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
140 directory
= pathToDataDirectory();
143 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
146 /* u_getDataDirectory shoul return \source\data ... set the
147 * directory to ..\source\data\..\test\testdata\out\testdata
149 strcpy(tdpath
, directory
);
150 strcat(tdpath
, tdrelativepath
);
151 strcat(tdpath
,"testdata");
153 test
=ures_open(tdpath
, "testtypes", &err
);
156 err
= U_FILE_ACCESS_ERROR
;
157 log_data_err("Could not load testtypes.res in testdata bundle with path %s - %s\n", tdpath
, u_errorName(err
));
161 fgTestDataPath
= tdpath
;
163 return fgTestDataPath
;
166 virtual const char* getTestDataPath(UErrorCode
& err
) {
167 return loadTestData(err
);
171 const char* DataDrivenLogger::fgDataDir
= NULL
;
172 char* DataDrivenLogger::fgTestDataPath
= NULL
;
175 uto64(const UChar
*buffer
)
178 /* iterate through buffer */
180 /* read the next digit */
182 if (!u_isxdigit(*buffer
)) {
183 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar
)*buffer
);
185 result
+= *buffer
- 0x0030 - (*buffer
>= 0x0041 ? (*buffer
>= 0x0061 ? 39 : 7) : 0);
193 static void U_CALLCONV
DataDrivenPrintf(void)
195 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
196 UErrorCode errorCode
;
197 TestDataModule
*dataModule
;
199 const DataMap
*testCase
;
200 DataDrivenLogger logger
;
203 char cFormat
[sizeof(cBuffer
)];
204 char cExpected
[sizeof(cBuffer
)];
205 UnicodeString tempStr
;
207 UChar expectedResult
[512];
215 int32_t uBufferLenReturned
;
217 const char *fileLocale
= "en_US_POSIX";
218 int32_t uFileBufferLenReturned
;
219 LocalUFILEPointer testFile
;
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
;
233 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "w", fileLocale
, "UTF-8"));
234 if (testFile
.isNull()) {
235 log_err("Can't open test file - %s\n",
239 u_memset(uBuffer
, 0x2A, sizeof(uBuffer
)/sizeof(uBuffer
[0]));
240 uBuffer
[sizeof(uBuffer
)/sizeof(uBuffer
[0])-1] = 0;
241 tempStr
=testCase
->getString("format", errorCode
);
242 tempStr
.extract(format
, sizeof(format
)/sizeof(format
[0]), errorCode
);
243 tempStr
=testCase
->getString("result", errorCode
);
244 tempStr
.extract(expectedResult
, sizeof(expectedResult
)/sizeof(expectedResult
[0]), errorCode
);
245 tempStr
=testCase
->getString("argument", errorCode
);
246 tempStr
.extract(argument
, sizeof(argument
)/sizeof(argument
[0]), errorCode
);
247 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
248 if(U_FAILURE(errorCode
)) {
249 log_err("error retrieving icuio/printf test case %d - %s\n",
250 i
, u_errorName(errorCode
));
251 errorCode
=U_ZERO_ERROR
;
254 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
255 switch (testCase
->getString("argumentType", errorCode
)[0]) {
256 case 0x64: // 'd' double
257 dbl
= atof(u_austrcpy(cBuffer
, argument
));
258 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, dbl
);
259 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, dbl
);
261 case 0x31: // '1' int8_t
262 i8
= (int8_t)uto64(argument
);
263 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i8
);
264 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i8
);
266 case 0x32: // '2' int16_t
267 i16
= (int16_t)uto64(argument
);
268 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i16
);
269 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i16
);
271 case 0x34: // '4' int32_t
272 i32
= (int32_t)uto64(argument
);
273 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i32
);
274 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i32
);
276 case 0x38: // '8' int64_t
277 i64
= uto64(argument
);
278 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i64
);
279 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i64
);
281 case 0x73: // 's' char *
282 u_austrncpy(cBuffer
, argument
, sizeof(cBuffer
));
283 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, cBuffer
);
284 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, cBuffer
);
286 case 0x53: // 'S' UChar *
287 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, argument
);
288 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, argument
);
291 uBufferLenReturned
= 0;
292 uFileBufferLenReturned
= 0;
293 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
295 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
296 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
297 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
298 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
299 cBuffer
[sizeof(cBuffer
)-1] = 0;
300 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
301 i
, cFormat
, cBuffer
, cExpected
);
303 if (uBufferLenReturned
<= 0) {
304 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
307 else if (uBuffer
[uBufferLenReturned
-1] == 0
308 || uBuffer
[uBufferLenReturned
] != 0
309 || uBuffer
[uBufferLenReturned
+1] != 0x2A
310 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
312 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
313 cBuffer
[sizeof(cBuffer
)-1] = 0;
314 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
315 i
, cBuffer
, uBufferLenReturned
);
317 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "r", fileLocale
, "UTF-8"));
318 if (testFile
.isNull()) {
319 log_err("Can't open test file - %s\n",
323 u_fgets(uBuffer
, sizeof(uBuffer
)/sizeof(uBuffer
[0]), testFile
.getAlias());
324 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
325 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
326 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
327 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
328 cBuffer
[sizeof(cBuffer
)-1] = 0;
329 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
330 i
, cFormat
, cBuffer
, cExpected
);
332 if (uFileBufferLenReturned
!= uBufferLenReturned
)
334 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
335 cBuffer
[sizeof(cBuffer
)-1] = 0;
336 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
337 uFileBufferLenReturned
, uBufferLenReturned
);
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
;
352 log_data_err("Failed: could not load test icuio data\n");
359 static void U_CALLCONV
DataDrivenScanf(void)
361 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
362 UErrorCode errorCode
;
363 TestDataModule
*dataModule
;
365 const DataMap
*testCase
;
366 DataDrivenLogger logger
;
369 char cExpected
[sizeof(cBuffer
)];
370 UnicodeString tempStr
;
372 UChar expectedResult
[512];
375 int8_t i8
, expected8
;
376 int16_t i16
, expected16
;
377 int32_t i32
, expected32
;
378 int64_t i64
, expected64
;
379 double dbl
, expectedDbl
;
380 volatile float flt
, expectedFlt
; // Use volatile in order to get around an Intel compiler issue.
381 int32_t uBufferLenReturned
;
383 //const char *fileLocale = "en_US_POSIX";
384 //int32_t uFileBufferLenReturned;
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
;
399 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
401 log_err("Can't open test file - %s\n",
404 u_memset(uBuffer
, 0x2A, sizeof(uBuffer
)/sizeof(uBuffer
[0]));
405 uBuffer
[sizeof(uBuffer
)/sizeof(uBuffer
[0])-1] = 0;
406 tempStr
=testCase
->getString("format", errorCode
);
407 tempStr
.extract(format
, sizeof(format
)/sizeof(format
[0]), errorCode
);
408 tempStr
=testCase
->getString("result", errorCode
);
409 tempStr
.extract(expectedResult
, sizeof(expectedResult
)/sizeof(expectedResult
[0]), errorCode
);
410 tempStr
=testCase
->getString("argument", errorCode
);
411 tempStr
.extract(argument
, sizeof(argument
)/sizeof(argument
[0]), errorCode
);
412 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
413 if(U_FAILURE(errorCode
)) {
414 log_err("error retrieving icuio/printf test case %d - %s\n",
415 i
, u_errorName(errorCode
));
416 errorCode
=U_ZERO_ERROR
;
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
);
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
);
439 case 0x31: // '1' int8_t
440 expected8
= (int8_t)uto64(expectedResult
);
441 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i8
);
442 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8);
443 if (i8
!= expected8
) {
444 log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n",
448 case 0x32: // '2' int16_t
449 expected16
= (int16_t)uto64(expectedResult
);
450 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i16
);
451 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16);
452 if (i16
!= expected16
) {
453 log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n",
457 case 0x34: // '4' int32_t
458 expected32
= (int32_t)uto64(expectedResult
);
459 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i32
);
460 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32);
461 if (i32
!= expected32
) {
462 log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n",
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
);
474 case 0x73: // 's' char *
475 u_austrcpy(cExpected
, expectedResult
);
476 uBufferLenReturned
= u_sscanf_u(argument
, format
, cBuffer
);
477 //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
478 if (strcmp(cBuffer
, cExpected
) != 0) {
479 log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer
, cExpected
, i
);
482 case 0x53: // 'S' UChar *
483 uBufferLenReturned
= u_sscanf_u(argument
, format
, uBuffer
);
484 //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
485 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
486 u_austrcpy(cExpected
, format
);
487 u_austrcpy(cBuffer
, uBuffer
);
488 log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected
, cBuffer
, i
);
492 uBufferLenReturned
= 0;
493 //uFileBufferLenReturned = 0;
494 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
496 if (uBufferLenReturned
!= 1) {
497 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned
, i
);
499 /* if (u_strcmp(uBuffer, expectedResult) != 0) {
500 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
501 u_austrncpy(cFormat, format, sizeof(cFormat));
502 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
503 cBuffer[sizeof(cBuffer)-1] = 0;
504 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
505 i, cFormat, cBuffer, cExpected);
507 if (uBuffer[uBufferLenReturned-1] == 0
508 || uBuffer[uBufferLenReturned] != 0
509 || uBuffer[uBufferLenReturned+1] != 0x2A
510 || uBuffer[uBufferLenReturned+2] != 0x2A)
512 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
513 cBuffer[sizeof(cBuffer)-1] = 0;
514 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
515 i, cBuffer, uBufferLenReturned);
517 /* u_fclose(testFile);
518 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
520 log_err("Can't open test file - %s\n",
524 u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile);
525 if (u_strcmp(uBuffer, expectedResult) != 0) {
526 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
527 u_austrncpy(cFormat, format, sizeof(cFormat));
528 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
529 cBuffer[sizeof(cBuffer)-1] = 0;
530 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
531 i, cFormat, cBuffer, cExpected);
533 if (uFileBufferLenReturned != uBufferLenReturned)
535 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
536 cBuffer[sizeof(cBuffer)-1] = 0;
537 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
538 uFileBufferLenReturned, uBufferLenReturned);
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
;
547 // u_fclose(testFile);
554 log_data_err("Failed: could not load test icuio data\n");
561 static void U_CALLCONV
DataDrivenPrintfPrecision(void)
563 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
564 UErrorCode errorCode
;
565 TestDataModule
*dataModule
;
567 const DataMap
*testCase
;
568 DataDrivenLogger logger
;
571 char cFormat
[sizeof(cBuffer
)];
572 char cExpected
[sizeof(cBuffer
)];
573 UnicodeString tempStr
;
575 UChar expectedResult
[512];
584 int32_t uBufferLenReturned
;
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
;
598 u_memset(uBuffer
, 0x2A, sizeof(uBuffer
)/sizeof(uBuffer
[0]));
599 uBuffer
[sizeof(uBuffer
)/sizeof(uBuffer
[0])-1] = 0;
600 tempStr
=testCase
->getString("format", errorCode
);
601 tempStr
.extract(format
, sizeof(format
)/sizeof(format
[0]), errorCode
);
602 tempStr
=testCase
->getString("result", errorCode
);
603 tempStr
.extract(expectedResult
, sizeof(expectedResult
)/sizeof(expectedResult
[0]), errorCode
);
604 tempStr
=testCase
->getString("argument", errorCode
);
605 tempStr
.extract(argument
, sizeof(argument
)/sizeof(argument
[0]), errorCode
);
606 precision
=testCase
->getInt28("precision", errorCode
);
607 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
608 if(U_FAILURE(errorCode
)) {
609 log_err("error retrieving icuio/printf test case %d - %s\n",
610 i
, u_errorName(errorCode
));
611 errorCode
=U_ZERO_ERROR
;
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
);
620 case 0x31: // '1' int8_t
621 i8
= (int8_t)uto64(argument
);
622 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i8
);
624 case 0x32: // '2' int16_t
625 i16
= (int16_t)uto64(argument
);
626 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i16
);
628 case 0x34: // '4' int32_t
629 i32
= (int32_t)uto64(argument
);
630 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i32
);
632 case 0x38: // '8' int64_t
633 i64
= uto64(argument
);
634 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i64
);
636 case 0x73: // 's' char *
637 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
638 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, cBuffer
);
640 case 0x53: // 'S' UChar *
641 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, argument
);
644 uBufferLenReturned
= 0;
645 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
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
);
655 if (uBufferLenReturned
<= 0) {
656 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
659 else if (uBuffer
[uBufferLenReturned
-1] == 0
660 || uBuffer
[uBufferLenReturned
] != 0
661 || uBuffer
[uBufferLenReturned
+1] != 0x2A
662 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
664 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
665 cBuffer
[sizeof(cBuffer
)-1] = 0;
666 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
667 i
, cBuffer
, uBufferLenReturned
);
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
;
681 log_data_err("Failed: could not load test icuio data\n");
687 static void addAllTests(TestNode
** root
) {
690 addTranslitTest(root
);
692 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_LEGACY_CONVERSION
693 addTest(root
, &DataDrivenPrintf
, "datadriv/DataDrivenPrintf");
694 addTest(root
, &DataDrivenPrintfPrecision
, "datadriv/DataDrivenPrintfPrecision");
695 addTest(root
, &DataDrivenScanf
, "datadriv/DataDrivenScanf");
697 #if U_IOSTREAM_SOURCE >= 199711
698 addStreamTests(root
);
702 /* returns the path to icu/source/data/out */
703 static const char *ctest_dataOutDir()
705 static const char *dataOutDir
= NULL
;
711 /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
712 // to point to the top of the build hierarchy, which may or
713 // may not be the same as the source directory, depending on
714 // the configure options used. At any rate,
715 // set the data path to the built data from this directory.
716 // The value is complete with quotes, so it can be used
717 // as-is as a string constant.
719 #if defined (U_TOPBUILDDIR)
721 dataOutDir
= U_TOPBUILDDIR
"data"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
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"
730 static char p
[sizeof(__FILE__
) + 20];
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 '\' */
744 if (pBackSlash
!= NULL
) {
745 /* We found and truncated three names from the path.
746 * Now append "source\data" and set the environment
748 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
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");
756 dataOutDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
759 dataOutDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
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.
777 static void ctest_setICU_DATA() {
779 /* No location for the data dir was identifiable.
780 * Add other fallbacks for the test data location here if the need arises
782 if (getenv("ICU_DATA") == NULL
) {
783 /* If ICU_DATA isn't set, set it to the usual location */
784 u_setDataDirectory(ctest_dataOutDir());
790 * Note: this assumes that context is a pointer to STANDARD_TEST_FILE. It would be
791 * cleaner to define an acutal context with a string pointer in it and set STANDARD_TEST_FILE
792 * after the call to initArgs()...
794 static int U_CALLCONV
argHandler(int arg
, int /*argc*/, const char * const argv
[], void *context
)
796 const char **str
= (const char **) context
;
798 if (argv
[arg
][0] != '/' && argv
[arg
][0] != '-') {
807 int main(int argc
, char* argv
[])
810 TestNode
*root
= NULL
;
811 UErrorCode errorCode
= U_ZERO_ERROR
;
812 UDate startTime
, endTime
;
815 startTime
= uprv_getRawUTCtime();
817 /* Check whether ICU will initialize without forcing the build data directory into
818 * the ICU_DATA path. Success here means either the data dll contains data, or that
819 * this test program was run with ICU_DATA set externally. Failure of this check
820 * is normal when ICU data is not packaged into a shared library.
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.
826 if (U_FAILURE(errorCode
)) {
828 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
831 errorCode
= U_ZERO_ERROR
;
832 if (!initArgs(argc
, argv
, argHandler
, (void *) &STANDARD_TEST_FILE
)) {
833 /* Error already displayed. */
838 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
840 if (U_FAILURE(errorCode
)) {
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
));
848 fprintf(stdout
, "Default charset for this run is %s\n", ucnv_getDefaultName());
851 nerrors
= runTestRequest(root
, argc
, argv
);
855 FILE* fileToRemove
= fopen(STANDARD_TEST_FILE
, "r");
856 /* This should delete any temporary files. */
858 fclose(fileToRemove
);
859 log_verbose("Deleting: %s\n", STANDARD_TEST_FILE
);
860 if (remove(STANDARD_TEST_FILE
) != 0) {
861 /* Maybe someone didn't close the file correctly. */
862 fprintf(stderr
, "FAIL: Could not delete %s\n", STANDARD_TEST_FILE
);
869 cleanUpTestTree(root
);
870 DataDrivenLogger::cleanUp();
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
));