2 **********************************************************************
3 * Copyright (C) 2002-2016, 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"
26 #include "unicode/tstdtmod.h"
32 class DataDrivenLogger
: public TestLog
{
33 static const char* fgDataDir
;
34 static char *fgTestDataPath
;
37 static void cleanUp() {
40 fgTestDataPath
= NULL
;
43 virtual void errln( const UnicodeString
&message
) {
45 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
46 buffer
[3999] = 0; /* NULL terminate */
50 virtual void logln( const UnicodeString
&message
) {
52 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
53 buffer
[3999] = 0; /* NULL terminate */
57 virtual void dataerrln( const UnicodeString
&message
) {
59 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
60 buffer
[3999] = 0; /* NULL terminate */
64 static const char * pathToDataDirectory(void)
67 if(fgDataDir
!= NULL
) {
71 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
72 // to point to the top of the build hierarchy, which may or
73 // may not be the same as the source directory, depending on
74 // the configure options used. At any rate,
75 // set the data path to the built data from this directory.
76 // The value is complete with quotes, so it can be used
77 // as-is as a string constant.
79 #if defined (U_TOPSRCDIR)
81 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
85 /* On Windows, the file name obtained from __FILE__ includes a full path.
86 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
87 * Change to "wherever\icu\source\data"
90 static char p
[sizeof(__FILE__
) + 10];
95 /* We want to back over three '\' chars. */
96 /* Only Windows should end up here, so looking for '\' is safe. */
97 for (i
=1; i
<=3; i
++) {
98 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
99 if (pBackSlash
!= NULL
) {
100 *pBackSlash
= 0; /* Truncate the string at the '\' */
104 if (pBackSlash
!= NULL
) {
105 /* We found and truncated three names from the path.
106 * Now append "source\data" and set the environment
108 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
112 /* __FILE__ on MSVC7 does not contain the directory */
113 FILE *file
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
116 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
119 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
129 static const char* loadTestData(UErrorCode
& err
){
130 if( fgTestDataPath
== NULL
){
131 const char* directory
=NULL
;
132 UResourceBundle
* test
=NULL
;
134 const char* tdrelativepath
;
136 #if defined (U_TOPBUILDDIR)
137 tdrelativepath
= "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
138 directory
= U_TOPBUILDDIR
;
140 tdrelativepath
= ".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
141 directory
= pathToDataDirectory();
144 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
147 /* u_getDataDirectory shoul return \source\data ... set the
148 * directory to ..\source\data\..\test\testdata\out\testdata
150 strcpy(tdpath
, directory
);
151 strcat(tdpath
, tdrelativepath
);
152 strcat(tdpath
,"testdata");
154 test
=ures_open(tdpath
, "testtypes", &err
);
157 err
= U_FILE_ACCESS_ERROR
;
158 log_data_err("Could not load testtypes.res in testdata bundle with path %s - %s\n", tdpath
, u_errorName(err
));
162 fgTestDataPath
= tdpath
;
164 return fgTestDataPath
;
167 virtual const char* getTestDataPath(UErrorCode
& err
) {
168 return loadTestData(err
);
172 const char* DataDrivenLogger::fgDataDir
= NULL
;
173 char* DataDrivenLogger::fgTestDataPath
= NULL
;
175 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
177 uto64(const UChar
*buffer
)
180 /* iterate through buffer */
182 /* read the next digit */
184 if (!u_isxdigit(*buffer
)) {
185 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar
)*buffer
);
187 result
+= *buffer
- 0x0030 - (*buffer
>= 0x0041 ? (*buffer
>= 0x0061 ? 39 : 7) : 0);
195 static void U_CALLCONV
DataDrivenPrintf(void)
197 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
198 UErrorCode errorCode
;
199 TestDataModule
*dataModule
;
201 const DataMap
*testCase
;
202 DataDrivenLogger logger
;
205 char cFormat
[sizeof(cBuffer
)];
206 char cExpected
[sizeof(cBuffer
)];
207 UnicodeString tempStr
;
209 UChar expectedResult
[512];
217 int32_t uBufferLenReturned
;
219 const char *fileLocale
= "en_US_POSIX";
220 int32_t uFileBufferLenReturned
;
221 LocalUFILEPointer testFile
;
223 errorCode
=U_ZERO_ERROR
;
224 dataModule
=TestDataModule::getTestDataModule("icuio", logger
, errorCode
);
225 if(U_SUCCESS(errorCode
)) {
226 testData
=dataModule
->createTestData("printf", errorCode
);
227 if(U_SUCCESS(errorCode
)) {
228 for(i
=0; testData
->nextCase(testCase
, errorCode
); ++i
) {
229 if(U_FAILURE(errorCode
)) {
230 log_err("error retrieving icuio/printf test case %d - %s\n",
231 i
, u_errorName(errorCode
));
232 errorCode
=U_ZERO_ERROR
;
235 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "w", fileLocale
, "UTF-8"));
236 if (testFile
.isNull()) {
237 log_err("Can't open test file - %s\n",
241 u_memset(uBuffer
, 0x2A, UPRV_LENGTHOF(uBuffer
));
242 uBuffer
[UPRV_LENGTHOF(uBuffer
)-1] = 0;
243 tempStr
=testCase
->getString("format", errorCode
);
244 tempStr
.extract(format
, UPRV_LENGTHOF(format
), errorCode
);
245 tempStr
=testCase
->getString("result", errorCode
);
246 tempStr
.extract(expectedResult
, UPRV_LENGTHOF(expectedResult
), errorCode
);
247 tempStr
=testCase
->getString("argument", errorCode
);
248 tempStr
.extract(argument
, UPRV_LENGTHOF(argument
), errorCode
);
249 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
250 if(U_FAILURE(errorCode
)) {
251 log_err("error retrieving icuio/printf test case %d - %s\n",
252 i
, u_errorName(errorCode
));
253 errorCode
=U_ZERO_ERROR
;
256 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
257 switch (testCase
->getString("argumentType", errorCode
)[0]) {
258 case 0x64: // 'd' double
259 dbl
= atof(u_austrcpy(cBuffer
, argument
));
260 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, dbl
);
261 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, dbl
);
263 case 0x31: // '1' int8_t
264 i8
= (int8_t)uto64(argument
);
265 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i8
);
266 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i8
);
268 case 0x32: // '2' int16_t
269 i16
= (int16_t)uto64(argument
);
270 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i16
);
271 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i16
);
273 case 0x34: // '4' int32_t
274 i32
= (int32_t)uto64(argument
);
275 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i32
);
276 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i32
);
278 case 0x38: // '8' int64_t
279 i64
= uto64(argument
);
280 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i64
);
281 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i64
);
283 case 0x73: // 's' char *
284 u_austrncpy(cBuffer
, argument
, sizeof(cBuffer
));
285 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, cBuffer
);
286 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, cBuffer
);
288 case 0x53: // 'S' UChar *
289 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, argument
);
290 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, argument
);
293 uBufferLenReturned
= 0;
294 uFileBufferLenReturned
= 0;
295 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
297 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
298 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
299 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
300 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
301 cBuffer
[sizeof(cBuffer
)-1] = 0;
302 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
303 i
, cFormat
, cBuffer
, cExpected
);
305 if (uBufferLenReturned
<= 0) {
306 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
309 else if (uBuffer
[uBufferLenReturned
-1] == 0
310 || uBuffer
[uBufferLenReturned
] != 0
311 || uBuffer
[uBufferLenReturned
+1] != 0x2A
312 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
314 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
315 cBuffer
[sizeof(cBuffer
)-1] = 0;
316 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
317 i
, cBuffer
, uBufferLenReturned
);
319 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "r", fileLocale
, "UTF-8"));
320 if (testFile
.isNull()) {
321 log_err("Can't open test file - %s\n",
325 u_fgets(uBuffer
, UPRV_LENGTHOF(uBuffer
), testFile
.getAlias());
326 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
327 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
328 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
329 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
330 cBuffer
[sizeof(cBuffer
)-1] = 0;
331 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
332 i
, cFormat
, cBuffer
, cExpected
);
334 if (uFileBufferLenReturned
!= uBufferLenReturned
)
336 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
337 cBuffer
[sizeof(cBuffer
)-1] = 0;
338 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
339 uFileBufferLenReturned
, uBufferLenReturned
);
342 if(U_FAILURE(errorCode
)) {
343 log_err("error running icuio/printf test case %d - %s\n",
344 i
, u_errorName(errorCode
));
345 errorCode
=U_ZERO_ERROR
;
354 log_data_err("Failed: could not load test icuio data\n");
361 static void U_CALLCONV
DataDrivenScanf(void)
363 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
364 UErrorCode errorCode
;
365 TestDataModule
*dataModule
;
367 const DataMap
*testCase
;
368 DataDrivenLogger logger
;
371 char cExpected
[sizeof(cBuffer
)];
372 UnicodeString tempStr
;
374 UChar expectedResult
[512];
377 int8_t i8
, expected8
;
378 int16_t i16
, expected16
;
379 int32_t i32
, expected32
;
380 int64_t i64
, expected64
;
381 double dbl
, expectedDbl
;
382 volatile float flt
, expectedFlt
; // Use volatile in order to get around an Intel compiler issue.
383 int32_t uBufferLenReturned
;
385 //const char *fileLocale = "en_US_POSIX";
386 //int32_t uFileBufferLenReturned;
389 errorCode
=U_ZERO_ERROR
;
390 dataModule
=TestDataModule::getTestDataModule("icuio", logger
, errorCode
);
391 if(U_SUCCESS(errorCode
)) {
392 testData
=dataModule
->createTestData("scanf", errorCode
);
393 if(U_SUCCESS(errorCode
)) {
394 for(i
=0; testData
->nextCase(testCase
, errorCode
); ++i
) {
395 if(U_FAILURE(errorCode
)) {
396 log_err("error retrieving icuio/printf test case %d - %s\n",
397 i
, u_errorName(errorCode
));
398 errorCode
=U_ZERO_ERROR
;
401 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
403 log_err("Can't open test file - %s\n",
406 u_memset(uBuffer
, 0x2A, UPRV_LENGTHOF(uBuffer
));
407 uBuffer
[UPRV_LENGTHOF(uBuffer
)-1] = 0;
408 tempStr
=testCase
->getString("format", errorCode
);
409 tempStr
.extract(format
, UPRV_LENGTHOF(format
), errorCode
);
410 tempStr
=testCase
->getString("result", errorCode
);
411 tempStr
.extract(expectedResult
, UPRV_LENGTHOF(expectedResult
), errorCode
);
412 tempStr
=testCase
->getString("argument", errorCode
);
413 tempStr
.extract(argument
, UPRV_LENGTHOF(argument
), errorCode
);
414 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
415 if(U_FAILURE(errorCode
)) {
416 log_err("error retrieving icuio/printf test case %d - %s\n",
417 i
, u_errorName(errorCode
));
418 errorCode
=U_ZERO_ERROR
;
421 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
422 switch (testCase
->getString("argumentType", errorCode
)[0]) {
423 case 0x64: // 'd' double
424 expectedDbl
= atof(u_austrcpy(cBuffer
, expectedResult
));
425 uBufferLenReturned
= u_sscanf_u(argument
, format
, &dbl
);
426 //uFileBufferLenReturned = u_fscanf_u(testFile, format, dbl);
427 if (dbl
!= expectedDbl
) {
428 log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
429 i
, dbl
, expectedDbl
);
432 case 0x66: // 'f' float
433 expectedFlt
= (float)atof(u_austrcpy(cBuffer
, expectedResult
));
434 uBufferLenReturned
= u_sscanf_u(argument
, format
, &flt
);
435 //uFileBufferLenReturned = u_fscanf_u(testFile, format, flt);
436 if (flt
!= expectedFlt
) {
437 log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
438 i
, flt
, expectedFlt
);
441 case 0x31: // '1' int8_t
442 expected8
= (int8_t)uto64(expectedResult
);
443 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i8
);
444 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8);
445 if (i8
!= expected8
) {
446 log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n",
450 case 0x32: // '2' int16_t
451 expected16
= (int16_t)uto64(expectedResult
);
452 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i16
);
453 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16);
454 if (i16
!= expected16
) {
455 log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n",
459 case 0x34: // '4' int32_t
460 expected32
= (int32_t)uto64(expectedResult
);
461 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i32
);
462 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32);
463 if (i32
!= expected32
) {
464 log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n",
468 case 0x38: // '8' int64_t
469 expected64
= uto64(expectedResult
);
470 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i64
);
471 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i64);
472 if (i64
!= expected64
) {
473 log_err("error in scanf 64-bit. Test case = %d\n", i
);
476 case 0x73: // 's' char *
477 u_austrcpy(cExpected
, expectedResult
);
478 uBufferLenReturned
= u_sscanf_u(argument
, format
, cBuffer
);
479 //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
480 if (strcmp(cBuffer
, cExpected
) != 0) {
481 log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer
, cExpected
, i
);
484 case 0x53: // 'S' UChar *
485 uBufferLenReturned
= u_sscanf_u(argument
, format
, uBuffer
);
486 //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
487 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
488 u_austrcpy(cExpected
, format
);
489 u_austrcpy(cBuffer
, uBuffer
);
490 log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected
, cBuffer
, i
);
494 uBufferLenReturned
= 0;
495 //uFileBufferLenReturned = 0;
496 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
498 if (uBufferLenReturned
!= 1) {
499 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned
, i
);
501 /* if (u_strcmp(uBuffer, expectedResult) != 0) {
502 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
503 u_austrncpy(cFormat, format, sizeof(cFormat));
504 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
505 cBuffer[sizeof(cBuffer)-1] = 0;
506 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
507 i, cFormat, cBuffer, cExpected);
509 if (uBuffer[uBufferLenReturned-1] == 0
510 || uBuffer[uBufferLenReturned] != 0
511 || uBuffer[uBufferLenReturned+1] != 0x2A
512 || uBuffer[uBufferLenReturned+2] != 0x2A)
514 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
515 cBuffer[sizeof(cBuffer)-1] = 0;
516 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
517 i, cBuffer, uBufferLenReturned);
519 /* u_fclose(testFile);
520 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
522 log_err("Can't open test file - %s\n",
526 u_fgets(uBuffer, UPRV_LENGTHOF(uBuffer), testFile);
527 if (u_strcmp(uBuffer, expectedResult) != 0) {
528 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
529 u_austrncpy(cFormat, format, sizeof(cFormat));
530 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
531 cBuffer[sizeof(cBuffer)-1] = 0;
532 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
533 i, cFormat, cBuffer, cExpected);
535 if (uFileBufferLenReturned != uBufferLenReturned)
537 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
538 cBuffer[sizeof(cBuffer)-1] = 0;
539 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
540 uFileBufferLenReturned, uBufferLenReturned);
543 if(U_FAILURE(errorCode
)) {
544 log_err("error running icuio/printf test case %d - %s\n",
545 i
, u_errorName(errorCode
));
546 errorCode
=U_ZERO_ERROR
;
549 // u_fclose(testFile);
556 log_data_err("Failed: could not load test icuio data\n");
563 static void U_CALLCONV
DataDrivenPrintfPrecision(void)
565 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
566 UErrorCode errorCode
;
567 TestDataModule
*dataModule
;
569 const DataMap
*testCase
;
570 DataDrivenLogger logger
;
573 char cFormat
[sizeof(cBuffer
)];
574 char cExpected
[sizeof(cBuffer
)];
575 UnicodeString tempStr
;
577 UChar expectedResult
[512];
586 int32_t uBufferLenReturned
;
588 errorCode
=U_ZERO_ERROR
;
589 dataModule
=TestDataModule::getTestDataModule("icuio", logger
, errorCode
);
590 if(U_SUCCESS(errorCode
)) {
591 testData
=dataModule
->createTestData("printfPrecision", errorCode
);
592 if(U_SUCCESS(errorCode
)) {
593 for(i
=0; testData
->nextCase(testCase
, errorCode
); ++i
) {
594 if(U_FAILURE(errorCode
)) {
595 log_err("error retrieving icuio/printf test case %d - %s\n",
596 i
, u_errorName(errorCode
));
597 errorCode
=U_ZERO_ERROR
;
600 u_memset(uBuffer
, 0x2A, UPRV_LENGTHOF(uBuffer
));
601 uBuffer
[UPRV_LENGTHOF(uBuffer
)-1] = 0;
602 tempStr
=testCase
->getString("format", errorCode
);
603 tempStr
.extract(format
, UPRV_LENGTHOF(format
), errorCode
);
604 tempStr
=testCase
->getString("result", errorCode
);
605 tempStr
.extract(expectedResult
, UPRV_LENGTHOF(expectedResult
), errorCode
);
606 tempStr
=testCase
->getString("argument", errorCode
);
607 tempStr
.extract(argument
, UPRV_LENGTHOF(argument
), errorCode
);
608 precision
=testCase
->getInt28("precision", errorCode
);
609 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
610 if(U_FAILURE(errorCode
)) {
611 log_err("error retrieving icuio/printf test case %d - %s\n",
612 i
, u_errorName(errorCode
));
613 errorCode
=U_ZERO_ERROR
;
616 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
617 switch (testCase
->getString("argumentType", errorCode
)[0]) {
618 case 0x64: // 'd' double
619 dbl
= atof(u_austrcpy(cBuffer
, argument
));
620 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, dbl
);
622 case 0x31: // '1' int8_t
623 i8
= (int8_t)uto64(argument
);
624 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i8
);
626 case 0x32: // '2' int16_t
627 i16
= (int16_t)uto64(argument
);
628 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i16
);
630 case 0x34: // '4' int32_t
631 i32
= (int32_t)uto64(argument
);
632 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i32
);
634 case 0x38: // '8' int64_t
635 i64
= uto64(argument
);
636 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i64
);
638 case 0x73: // 's' char *
639 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
640 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, cBuffer
);
642 case 0x53: // 'S' UChar *
643 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, argument
);
646 uBufferLenReturned
= 0;
647 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
649 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
650 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
651 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
652 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
653 cBuffer
[sizeof(cBuffer
)-1] = 0;
654 log_err("FAILURE test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
655 i
, cFormat
, cBuffer
, cExpected
);
657 if (uBufferLenReturned
<= 0) {
658 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
661 else if (uBuffer
[uBufferLenReturned
-1] == 0
662 || uBuffer
[uBufferLenReturned
] != 0
663 || uBuffer
[uBufferLenReturned
+1] != 0x2A
664 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
666 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
667 cBuffer
[sizeof(cBuffer
)-1] = 0;
668 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
669 i
, cBuffer
, uBufferLenReturned
);
671 if(U_FAILURE(errorCode
)) {
672 log_err("error running icuio/printf test case %d - %s\n",
673 i
, u_errorName(errorCode
));
674 errorCode
=U_ZERO_ERROR
;
683 log_data_err("Failed: could not load test icuio data\n");
689 static void addAllTests(TestNode
** root
) {
692 addTranslitTest(root
);
694 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_LEGACY_CONVERSION
695 addTest(root
, &DataDrivenPrintf
, "datadriv/DataDrivenPrintf");
696 addTest(root
, &DataDrivenPrintfPrecision
, "datadriv/DataDrivenPrintfPrecision");
697 addTest(root
, &DataDrivenScanf
, "datadriv/DataDrivenScanf");
699 #if U_IOSTREAM_SOURCE >= 199711
700 addStreamTests(root
);
704 /* returns the path to icu/source/data/out */
705 static const char *ctest_dataOutDir()
707 static const char *dataOutDir
= NULL
;
713 /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
714 // to point to the top of the build hierarchy, which may or
715 // may not be the same as the source directory, depending on
716 // the configure options used. At any rate,
717 // set the data path to the built data from this directory.
718 // The value is complete with quotes, so it can be used
719 // as-is as a string constant.
721 #if defined (U_TOPBUILDDIR)
723 dataOutDir
= U_TOPBUILDDIR
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
727 /* On Windows, the file name obtained from __FILE__ includes a full path.
728 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
729 * Change to "wherever\icu\source\data"
732 static char p
[sizeof(__FILE__
) + 20];
737 /* We want to back over three '\' chars. */
738 /* Only Windows should end up here, so looking for '\' is safe. */
739 for (i
=1; i
<=3; i
++) {
740 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
741 if (pBackSlash
!= NULL
) {
742 *pBackSlash
= 0; /* Truncate the string at the '\' */
746 if (pBackSlash
!= NULL
) {
747 /* We found and truncated three names from the path.
748 * Now append "source\data" and set the environment
750 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
754 /* __FILE__ on MSVC7 does not contain the directory */
755 FILE *file
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
758 dataOutDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
761 dataOutDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
770 /* ctest_setICU_DATA - if the ICU_DATA environment variable is not already
771 * set, try to deduce the directory in which ICU was built,
772 * and set ICU_DATA to "icu/source/data" in that location.
773 * The intent is to allow the tests to have a good chance
774 * of running without requiring that the user manually set
775 * ICU_DATA. Common data isn't a problem, since it is
776 * picked up via a static (build time) reference, but the
777 * tests dynamically load some data.
779 static void ctest_setICU_DATA() {
781 /* No location for the data dir was identifiable.
782 * Add other fallbacks for the test data location here if the need arises
784 if (getenv("ICU_DATA") == NULL
) {
785 /* If ICU_DATA isn't set, set it to the usual location */
786 u_setDataDirectory(ctest_dataOutDir());
792 * Note: this assumes that context is a pointer to STANDARD_TEST_FILE. It would be
793 * cleaner to define an acutal context with a string pointer in it and set STANDARD_TEST_FILE
794 * after the call to initArgs()...
796 static int U_CALLCONV
argHandler(int arg
, int /*argc*/, const char * const argv
[], void *context
)
798 const char **str
= (const char **) context
;
800 if (argv
[arg
][0] != '/' && argv
[arg
][0] != '-') {
809 int main(int argc
, char* argv
[])
812 TestNode
*root
= NULL
;
813 UErrorCode errorCode
= U_ZERO_ERROR
;
814 UDate startTime
, endTime
;
817 startTime
= uprv_getRawUTCtime();
819 /* Check whether ICU will initialize without forcing the build data directory into
820 * the ICU_DATA path. Success here means either the data dll contains data, or that
821 * this test program was run with ICU_DATA set externally. Failure of this check
822 * is normal when ICU data is not packaged into a shared library.
824 * Whether or not this test succeeds, we want to cleanup and reinitialize
825 * with a data path so that data loading from individual files can be tested.
828 if (U_FAILURE(errorCode
)) {
830 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
833 errorCode
= U_ZERO_ERROR
;
834 if (!initArgs(argc
, argv
, argHandler
, (void *) &STANDARD_TEST_FILE
)) {
835 /* Error already displayed. */
840 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
842 if (U_FAILURE(errorCode
)) {
844 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
845 "*** Check the ICU_DATA environment variable and \n"
846 "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
));
850 fprintf(stdout
, "Default charset for this run is %s\n", ucnv_getDefaultName());
853 nerrors
= runTestRequest(root
, argc
, argv
);
857 FILE* fileToRemove
= fopen(STANDARD_TEST_FILE
, "r");
858 /* This should delete any temporary files. */
860 fclose(fileToRemove
);
861 log_verbose("Deleting: %s\n", STANDARD_TEST_FILE
);
862 if (remove(STANDARD_TEST_FILE
) != 0) {
863 /* Maybe someone didn't close the file correctly. */
864 fprintf(stderr
, "FAIL: Could not delete %s\n", STANDARD_TEST_FILE
);
871 cleanUpTestTree(root
);
872 DataDrivenLogger::cleanUp();
875 endTime
= uprv_getRawUTCtime();
876 diffTime
= (int32_t)(endTime
- startTime
);
877 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
878 (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
),
879 (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
),
880 (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
),
881 (int)(diffTime%U_MILLIS_PER_SECOND
));