2 **********************************************************************
3 * Copyright (C) 2002-2012, 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
;
174 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
176 uto64(const UChar
*buffer
)
179 /* iterate through buffer */
181 /* read the next digit */
183 if (!u_isxdigit(*buffer
)) {
184 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar
)*buffer
);
186 result
+= *buffer
- 0x0030 - (*buffer
>= 0x0041 ? (*buffer
>= 0x0061 ? 39 : 7) : 0);
194 static void U_CALLCONV
DataDrivenPrintf(void)
196 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
197 UErrorCode errorCode
;
198 TestDataModule
*dataModule
;
200 const DataMap
*testCase
;
201 DataDrivenLogger logger
;
204 char cFormat
[sizeof(cBuffer
)];
205 char cExpected
[sizeof(cBuffer
)];
206 UnicodeString tempStr
;
208 UChar expectedResult
[512];
216 int32_t uBufferLenReturned
;
218 const char *fileLocale
= "en_US_POSIX";
219 int32_t uFileBufferLenReturned
;
220 LocalUFILEPointer testFile
;
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
;
234 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "w", fileLocale
, "UTF-8"));
235 if (testFile
.isNull()) {
236 log_err("Can't open test file - %s\n",
240 u_memset(uBuffer
, 0x2A, sizeof(uBuffer
)/sizeof(uBuffer
[0]));
241 uBuffer
[sizeof(uBuffer
)/sizeof(uBuffer
[0])-1] = 0;
242 tempStr
=testCase
->getString("format", errorCode
);
243 tempStr
.extract(format
, sizeof(format
)/sizeof(format
[0]), errorCode
);
244 tempStr
=testCase
->getString("result", errorCode
);
245 tempStr
.extract(expectedResult
, sizeof(expectedResult
)/sizeof(expectedResult
[0]), errorCode
);
246 tempStr
=testCase
->getString("argument", errorCode
);
247 tempStr
.extract(argument
, sizeof(argument
)/sizeof(argument
[0]), errorCode
);
248 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
249 if(U_FAILURE(errorCode
)) {
250 log_err("error retrieving icuio/printf test case %d - %s\n",
251 i
, u_errorName(errorCode
));
252 errorCode
=U_ZERO_ERROR
;
255 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
256 switch (testCase
->getString("argumentType", errorCode
)[0]) {
257 case 0x64: // 'd' double
258 dbl
= atof(u_austrcpy(cBuffer
, argument
));
259 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, dbl
);
260 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, dbl
);
262 case 0x31: // '1' int8_t
263 i8
= (int8_t)uto64(argument
);
264 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i8
);
265 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i8
);
267 case 0x32: // '2' int16_t
268 i16
= (int16_t)uto64(argument
);
269 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i16
);
270 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i16
);
272 case 0x34: // '4' int32_t
273 i32
= (int32_t)uto64(argument
);
274 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i32
);
275 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i32
);
277 case 0x38: // '8' int64_t
278 i64
= uto64(argument
);
279 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i64
);
280 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i64
);
282 case 0x73: // 's' char *
283 u_austrncpy(cBuffer
, argument
, sizeof(cBuffer
));
284 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, cBuffer
);
285 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, cBuffer
);
287 case 0x53: // 'S' UChar *
288 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, argument
);
289 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, argument
);
292 uBufferLenReturned
= 0;
293 uFileBufferLenReturned
= 0;
294 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
296 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
297 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
298 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
299 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
300 cBuffer
[sizeof(cBuffer
)-1] = 0;
301 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
302 i
, cFormat
, cBuffer
, cExpected
);
304 if (uBufferLenReturned
<= 0) {
305 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
308 else if (uBuffer
[uBufferLenReturned
-1] == 0
309 || uBuffer
[uBufferLenReturned
] != 0
310 || uBuffer
[uBufferLenReturned
+1] != 0x2A
311 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
313 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
314 cBuffer
[sizeof(cBuffer
)-1] = 0;
315 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
316 i
, cBuffer
, uBufferLenReturned
);
318 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "r", fileLocale
, "UTF-8"));
319 if (testFile
.isNull()) {
320 log_err("Can't open test file - %s\n",
324 u_fgets(uBuffer
, sizeof(uBuffer
)/sizeof(uBuffer
[0]), testFile
.getAlias());
325 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
326 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
327 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
328 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
329 cBuffer
[sizeof(cBuffer
)-1] = 0;
330 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
331 i
, cFormat
, cBuffer
, cExpected
);
333 if (uFileBufferLenReturned
!= uBufferLenReturned
)
335 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
336 cBuffer
[sizeof(cBuffer
)-1] = 0;
337 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
338 uFileBufferLenReturned
, uBufferLenReturned
);
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
;
353 log_data_err("Failed: could not load test icuio data\n");
360 static void U_CALLCONV
DataDrivenScanf(void)
362 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
363 UErrorCode errorCode
;
364 TestDataModule
*dataModule
;
366 const DataMap
*testCase
;
367 DataDrivenLogger logger
;
370 char cExpected
[sizeof(cBuffer
)];
371 UnicodeString tempStr
;
373 UChar expectedResult
[512];
376 int8_t i8
, expected8
;
377 int16_t i16
, expected16
;
378 int32_t i32
, expected32
;
379 int64_t i64
, expected64
;
380 double dbl
, expectedDbl
;
381 volatile float flt
, expectedFlt
; // Use volatile in order to get around an Intel compiler issue.
382 int32_t uBufferLenReturned
;
384 //const char *fileLocale = "en_US_POSIX";
385 //int32_t uFileBufferLenReturned;
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
;
400 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
402 log_err("Can't open test file - %s\n",
405 u_memset(uBuffer
, 0x2A, sizeof(uBuffer
)/sizeof(uBuffer
[0]));
406 uBuffer
[sizeof(uBuffer
)/sizeof(uBuffer
[0])-1] = 0;
407 tempStr
=testCase
->getString("format", errorCode
);
408 tempStr
.extract(format
, sizeof(format
)/sizeof(format
[0]), errorCode
);
409 tempStr
=testCase
->getString("result", errorCode
);
410 tempStr
.extract(expectedResult
, sizeof(expectedResult
)/sizeof(expectedResult
[0]), errorCode
);
411 tempStr
=testCase
->getString("argument", errorCode
);
412 tempStr
.extract(argument
, sizeof(argument
)/sizeof(argument
[0]), errorCode
);
413 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
414 if(U_FAILURE(errorCode
)) {
415 log_err("error retrieving icuio/printf test case %d - %s\n",
416 i
, u_errorName(errorCode
));
417 errorCode
=U_ZERO_ERROR
;
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
);
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
);
440 case 0x31: // '1' int8_t
441 expected8
= (int8_t)uto64(expectedResult
);
442 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i8
);
443 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8);
444 if (i8
!= expected8
) {
445 log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n",
449 case 0x32: // '2' int16_t
450 expected16
= (int16_t)uto64(expectedResult
);
451 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i16
);
452 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16);
453 if (i16
!= expected16
) {
454 log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n",
458 case 0x34: // '4' int32_t
459 expected32
= (int32_t)uto64(expectedResult
);
460 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i32
);
461 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32);
462 if (i32
!= expected32
) {
463 log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n",
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
);
475 case 0x73: // 's' char *
476 u_austrcpy(cExpected
, expectedResult
);
477 uBufferLenReturned
= u_sscanf_u(argument
, format
, cBuffer
);
478 //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
479 if (strcmp(cBuffer
, cExpected
) != 0) {
480 log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer
, cExpected
, i
);
483 case 0x53: // 'S' UChar *
484 uBufferLenReturned
= u_sscanf_u(argument
, format
, uBuffer
);
485 //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
486 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
487 u_austrcpy(cExpected
, format
);
488 u_austrcpy(cBuffer
, uBuffer
);
489 log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected
, cBuffer
, i
);
493 uBufferLenReturned
= 0;
494 //uFileBufferLenReturned = 0;
495 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
497 if (uBufferLenReturned
!= 1) {
498 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned
, i
);
500 /* if (u_strcmp(uBuffer, expectedResult) != 0) {
501 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
502 u_austrncpy(cFormat, format, sizeof(cFormat));
503 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
504 cBuffer[sizeof(cBuffer)-1] = 0;
505 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
506 i, cFormat, cBuffer, cExpected);
508 if (uBuffer[uBufferLenReturned-1] == 0
509 || uBuffer[uBufferLenReturned] != 0
510 || uBuffer[uBufferLenReturned+1] != 0x2A
511 || uBuffer[uBufferLenReturned+2] != 0x2A)
513 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
514 cBuffer[sizeof(cBuffer)-1] = 0;
515 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
516 i, cBuffer, uBufferLenReturned);
518 /* u_fclose(testFile);
519 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
521 log_err("Can't open test file - %s\n",
525 u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile);
526 if (u_strcmp(uBuffer, expectedResult) != 0) {
527 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
528 u_austrncpy(cFormat, format, sizeof(cFormat));
529 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
530 cBuffer[sizeof(cBuffer)-1] = 0;
531 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
532 i, cFormat, cBuffer, cExpected);
534 if (uFileBufferLenReturned != uBufferLenReturned)
536 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
537 cBuffer[sizeof(cBuffer)-1] = 0;
538 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
539 uFileBufferLenReturned, uBufferLenReturned);
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
;
548 // u_fclose(testFile);
555 log_data_err("Failed: could not load test icuio data\n");
562 static void U_CALLCONV
DataDrivenPrintfPrecision(void)
564 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
565 UErrorCode errorCode
;
566 TestDataModule
*dataModule
;
568 const DataMap
*testCase
;
569 DataDrivenLogger logger
;
572 char cFormat
[sizeof(cBuffer
)];
573 char cExpected
[sizeof(cBuffer
)];
574 UnicodeString tempStr
;
576 UChar expectedResult
[512];
585 int32_t uBufferLenReturned
;
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
;
599 u_memset(uBuffer
, 0x2A, sizeof(uBuffer
)/sizeof(uBuffer
[0]));
600 uBuffer
[sizeof(uBuffer
)/sizeof(uBuffer
[0])-1] = 0;
601 tempStr
=testCase
->getString("format", errorCode
);
602 tempStr
.extract(format
, sizeof(format
)/sizeof(format
[0]), errorCode
);
603 tempStr
=testCase
->getString("result", errorCode
);
604 tempStr
.extract(expectedResult
, sizeof(expectedResult
)/sizeof(expectedResult
[0]), errorCode
);
605 tempStr
=testCase
->getString("argument", errorCode
);
606 tempStr
.extract(argument
, sizeof(argument
)/sizeof(argument
[0]), errorCode
);
607 precision
=testCase
->getInt28("precision", errorCode
);
608 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
609 if(U_FAILURE(errorCode
)) {
610 log_err("error retrieving icuio/printf test case %d - %s\n",
611 i
, u_errorName(errorCode
));
612 errorCode
=U_ZERO_ERROR
;
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
);
621 case 0x31: // '1' int8_t
622 i8
= (int8_t)uto64(argument
);
623 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i8
);
625 case 0x32: // '2' int16_t
626 i16
= (int16_t)uto64(argument
);
627 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i16
);
629 case 0x34: // '4' int32_t
630 i32
= (int32_t)uto64(argument
);
631 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i32
);
633 case 0x38: // '8' int64_t
634 i64
= uto64(argument
);
635 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i64
);
637 case 0x73: // 's' char *
638 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
639 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, cBuffer
);
641 case 0x53: // 'S' UChar *
642 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, argument
);
645 uBufferLenReturned
= 0;
646 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
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
);
656 if (uBufferLenReturned
<= 0) {
657 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
660 else if (uBuffer
[uBufferLenReturned
-1] == 0
661 || uBuffer
[uBufferLenReturned
] != 0
662 || uBuffer
[uBufferLenReturned
+1] != 0x2A
663 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
665 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
666 cBuffer
[sizeof(cBuffer
)-1] = 0;
667 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
668 i
, cBuffer
, uBufferLenReturned
);
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
;
682 log_data_err("Failed: could not load test icuio data\n");
688 static void addAllTests(TestNode
** root
) {
691 addTranslitTest(root
);
693 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_LEGACY_CONVERSION
694 addTest(root
, &DataDrivenPrintf
, "datadriv/DataDrivenPrintf");
695 addTest(root
, &DataDrivenPrintfPrecision
, "datadriv/DataDrivenPrintfPrecision");
696 addTest(root
, &DataDrivenScanf
, "datadriv/DataDrivenScanf");
698 #if U_IOSTREAM_SOURCE >= 199711
699 addStreamTests(root
);
703 /* returns the path to icu/source/data/out */
704 static const char *ctest_dataOutDir()
706 static const char *dataOutDir
= NULL
;
712 /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
713 // to point to the top of the build hierarchy, which may or
714 // may not be the same as the source directory, depending on
715 // the configure options used. At any rate,
716 // set the data path to the built data from this directory.
717 // The value is complete with quotes, so it can be used
718 // as-is as a string constant.
720 #if defined (U_TOPBUILDDIR)
722 dataOutDir
= U_TOPBUILDDIR
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
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"
731 static char p
[sizeof(__FILE__
) + 20];
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 '\' */
745 if (pBackSlash
!= NULL
) {
746 /* We found and truncated three names from the path.
747 * Now append "source\data" and set the environment
749 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
753 /* __FILE__ on MSVC7 does not contain the directory */
754 FILE *file
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
757 dataOutDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
760 dataOutDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
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.
778 static void ctest_setICU_DATA() {
780 /* No location for the data dir was identifiable.
781 * Add other fallbacks for the test data location here if the need arises
783 if (getenv("ICU_DATA") == NULL
) {
784 /* If ICU_DATA isn't set, set it to the usual location */
785 u_setDataDirectory(ctest_dataOutDir());
791 * Note: this assumes that context is a pointer to STANDARD_TEST_FILE. It would be
792 * cleaner to define an acutal context with a string pointer in it and set STANDARD_TEST_FILE
793 * after the call to initArgs()...
795 static int U_CALLCONV
argHandler(int arg
, int /*argc*/, const char * const argv
[], void *context
)
797 const char **str
= (const char **) context
;
799 if (argv
[arg
][0] != '/' && argv
[arg
][0] != '-') {
808 int main(int argc
, char* argv
[])
811 TestNode
*root
= NULL
;
812 UErrorCode errorCode
= U_ZERO_ERROR
;
813 UDate startTime
, endTime
;
816 startTime
= uprv_getRawUTCtime();
818 /* Check whether ICU will initialize without forcing the build data directory into
819 * the ICU_DATA path. Success here means either the data dll contains data, or that
820 * this test program was run with ICU_DATA set externally. Failure of this check
821 * is normal when ICU data is not packaged into a shared library.
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.
827 if (U_FAILURE(errorCode
)) {
829 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
832 errorCode
= U_ZERO_ERROR
;
833 if (!initArgs(argc
, argv
, argHandler
, (void *) &STANDARD_TEST_FILE
)) {
834 /* Error already displayed. */
839 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
841 if (U_FAILURE(errorCode
)) {
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
));
849 fprintf(stdout
, "Default charset for this run is %s\n", ucnv_getDefaultName());
852 nerrors
= runTestRequest(root
, argc
, argv
);
856 FILE* fileToRemove
= fopen(STANDARD_TEST_FILE
, "r");
857 /* This should delete any temporary files. */
859 fclose(fileToRemove
);
860 log_verbose("Deleting: %s\n", STANDARD_TEST_FILE
);
861 if (remove(STANDARD_TEST_FILE
) != 0) {
862 /* Maybe someone didn't close the file correctly. */
863 fprintf(stderr
, "FAIL: Could not delete %s\n", STANDARD_TEST_FILE
);
870 cleanUpTestTree(root
);
871 DataDrivenLogger::cleanUp();
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
));