2 **********************************************************************
3 * Copyright (C) 2002-2008, 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 */
48 virtual void dataerrln( const UnicodeString
&message
) {
50 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
51 buffer
[3999] = 0; /* NULL terminate */
55 static const char * pathToDataDirectory(void)
58 if(fgDataDir
!= NULL
) {
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.
70 #if defined (U_TOPSRCDIR)
72 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
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"
81 static char p
[sizeof(__FILE__
) + 10];
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 '\' */
95 if (pBackSlash
!= NULL
) {
96 /* We found and truncated three names from the path.
97 * Now append "source\data" and set the environment
99 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
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");
107 fgDataDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
110 fgDataDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
120 static const char* loadTestData(UErrorCode
& err
){
121 if( fgTestDataPath
== NULL
){
122 const char* directory
=NULL
;
123 UResourceBundle
* test
=NULL
;
125 const char* tdrelativepath
;
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
;
131 tdrelativepath
= ".."U_FILE_SEP_STRING
"test"U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
132 directory
= pathToDataDirectory();
135 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
138 /* u_getDataDirectory shoul return \source\data ... set the
139 * directory to ..\source\data\..\test\testdata\out\testdata
141 strcpy(tdpath
, directory
);
142 strcat(tdpath
, tdrelativepath
);
143 strcat(tdpath
,"testdata");
145 test
=ures_open(tdpath
, "testtypes", &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
));
153 fgTestDataPath
= tdpath
;
155 return fgTestDataPath
;
158 virtual const char* getTestDataPath(UErrorCode
& err
) {
159 return loadTestData(err
);
163 const char* DataDrivenLogger::fgDataDir
= NULL
;
164 char* DataDrivenLogger::fgTestDataPath
= NULL
;
167 uto64(const UChar
*buffer
)
170 /* iterate through buffer */
172 /* read the next digit */
174 if (!u_isxdigit(*buffer
)) {
175 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar
)*buffer
);
177 result
+= *buffer
- 0x0030 - (*buffer
>= 0x0041 ? (*buffer
>= 0x0061 ? 39 : 7) : 0);
185 static void U_CALLCONV
DataDrivenPrintf(void)
187 #if !UCONFIG_NO_FORMATTING
188 UErrorCode errorCode
;
189 TestDataModule
*dataModule
;
191 const DataMap
*testCase
;
192 DataDrivenLogger logger
;
195 char cFormat
[sizeof(cBuffer
)];
196 char cExpected
[sizeof(cBuffer
)];
197 UnicodeString tempStr
;
199 UChar expectedResult
[512];
207 int32_t uBufferLenReturned
;
209 const char *fileLocale
= "en_US_POSIX";
210 int32_t uFileBufferLenReturned
;
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
;
225 testFile
= u_fopen(STANDARD_TEST_FILE
, "w", fileLocale
, "UTF-8");
227 log_err("Can't open test file - %s\n",
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
;
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
);
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
);
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
);
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
);
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
);
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
);
278 case 0x53: // 'S' UChar *
279 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, argument
);
280 uFileBufferLenReturned
= u_fprintf_u(testFile
, format
, argument
);
283 uBufferLenReturned
= 0;
284 uFileBufferLenReturned
= 0;
285 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
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
);
295 if (uBufferLenReturned
<= 0) {
296 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
299 else if (uBuffer
[uBufferLenReturned
-1] == 0
300 || uBuffer
[uBufferLenReturned
] != 0
301 || uBuffer
[uBufferLenReturned
+1] != 0x2A
302 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
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
);
310 testFile
= u_fopen(STANDARD_TEST_FILE
, "r", fileLocale
, "UTF-8");
312 log_err("Can't open test file - %s\n",
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
);
325 if (uFileBufferLenReturned
!= uBufferLenReturned
)
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
);
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
;
346 log_data_err("Failed: could not load test icuio data\n");
353 static void U_CALLCONV
DataDrivenScanf(void)
355 #if !UCONFIG_NO_FORMATTING
356 UErrorCode errorCode
;
357 TestDataModule
*dataModule
;
359 const DataMap
*testCase
;
360 DataDrivenLogger logger
;
363 char cExpected
[sizeof(cBuffer
)];
364 UnicodeString tempStr
;
366 UChar expectedResult
[512];
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
;
377 //const char *fileLocale = "en_US_POSIX";
378 //int32_t uFileBufferLenReturned;
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
;
393 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
395 log_err("Can't open test file - %s\n",
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
;
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
);
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
);
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",
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",
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",
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
);
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
);
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
);
486 uBufferLenReturned
= 0;
487 //uFileBufferLenReturned = 0;
488 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
490 if (uBufferLenReturned
!= 1) {
491 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned
, i
);
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);
501 if (uBuffer[uBufferLenReturned-1] == 0
502 || uBuffer[uBufferLenReturned] != 0
503 || uBuffer[uBufferLenReturned+1] != 0x2A
504 || uBuffer[uBufferLenReturned+2] != 0x2A)
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);
511 /* u_fclose(testFile);
512 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
514 log_err("Can't open test file - %s\n",
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);
527 if (uFileBufferLenReturned != uBufferLenReturned)
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);
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
;
541 // u_fclose(testFile);
548 log_data_err("Failed: could not load test icuio data\n");
555 static void U_CALLCONV
DataDrivenPrintfPrecision(void)
557 #if !UCONFIG_NO_FORMATTING
558 UErrorCode errorCode
;
559 TestDataModule
*dataModule
;
561 const DataMap
*testCase
;
562 DataDrivenLogger logger
;
565 char cFormat
[sizeof(cBuffer
)];
566 char cExpected
[sizeof(cBuffer
)];
567 UnicodeString tempStr
;
569 UChar expectedResult
[512];
578 int32_t uBufferLenReturned
;
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
;
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
;
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
);
614 case 0x31: // '1' int8_t
615 i8
= (int8_t)uto64(argument
);
616 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i8
);
618 case 0x32: // '2' int16_t
619 i16
= (int16_t)uto64(argument
);
620 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i16
);
622 case 0x34: // '4' int32_t
623 i32
= (int32_t)uto64(argument
);
624 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i32
);
626 case 0x38: // '8' int64_t
627 i64
= uto64(argument
);
628 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i64
);
630 case 0x73: // 's' char *
631 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
632 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, cBuffer
);
634 case 0x53: // 'S' UChar *
635 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, argument
);
638 uBufferLenReturned
= 0;
639 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
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
);
649 if (uBufferLenReturned
<= 0) {
650 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
653 else if (uBuffer
[uBufferLenReturned
-1] == 0
654 || uBuffer
[uBufferLenReturned
] != 0
655 || uBuffer
[uBufferLenReturned
+1] != 0x2A
656 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
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
);
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
;
675 log_data_err("Failed: could not load test icuio data\n");
681 static void addAllTests(TestNode
** root
) {
684 addTranslitTest(root
);
686 #if !UCONFIG_NO_FORMATTING
687 addTest(root
, &DataDrivenPrintf
, "datadriv/DataDrivenPrintf");
688 addTest(root
, &DataDrivenPrintfPrecision
, "datadriv/DataDrivenPrintfPrecision");
689 addTest(root
, &DataDrivenScanf
, "datadriv/DataDrivenScanf");
691 addStreamTests(root
);
694 /* returns the path to icu/source/data/out */
695 static const char *ctest_dataOutDir()
697 static const char *dataOutDir
= NULL
;
703 /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
704 // to point to the top of the build hierarchy, which may or
705 // may not be the same as the source directory, depending on
706 // the configure options used. At any rate,
707 // set the data path to the built data from this directory.
708 // The value is complete with quotes, so it can be used
709 // as-is as a string constant.
711 #if defined (U_TOPBUILDDIR)
713 dataOutDir
= U_TOPBUILDDIR
"data"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
717 /* On Windows, the file name obtained from __FILE__ includes a full path.
718 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
719 * Change to "wherever\icu\source\data"
722 static char p
[sizeof(__FILE__
) + 20];
727 /* We want to back over three '\' chars. */
728 /* Only Windows should end up here, so looking for '\' is safe. */
729 for (i
=1; i
<=3; i
++) {
730 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
731 if (pBackSlash
!= NULL
) {
732 *pBackSlash
= 0; /* Truncate the string at the '\' */
736 if (pBackSlash
!= NULL
) {
737 /* We found and truncated three names from the path.
738 * Now append "source\data" and set the environment
740 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
744 /* __FILE__ on MSVC7 does not contain the directory */
745 FILE *file
= fopen(".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
748 dataOutDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
751 dataOutDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
760 /* ctest_setICU_DATA - if the ICU_DATA environment variable is not already
761 * set, try to deduce the directory in which ICU was built,
762 * and set ICU_DATA to "icu/source/data" in that location.
763 * The intent is to allow the tests to have a good chance
764 * of running without requiring that the user manually set
765 * ICU_DATA. Common data isn't a problem, since it is
766 * picked up via a static (build time) reference, but the
767 * tests dynamically load some data.
769 static void ctest_setICU_DATA() {
771 /* No location for the data dir was identifiable.
772 * Add other fallbacks for the test data location here if the need arises
774 if (getenv("ICU_DATA") == NULL
) {
775 /* If ICU_DATA isn't set, set it to the usual location */
776 u_setDataDirectory(ctest_dataOutDir());
782 * Note: this assumes that context is a pointer to STANDARD_TEST_FILE. It would be
783 * cleaner to define an acutal context with a string pointer in it and set STANDARD_TEST_FILE
784 * after the call to initArgs()...
786 static int U_CALLCONV
argHandler(int arg
, int /*argc*/, const char * const argv
[], void *context
)
788 const char **str
= (const char **) context
;
790 if (argv
[arg
][0] != '/' && argv
[arg
][0] != '-') {
799 int main(int argc
, char* argv
[])
802 TestNode
*root
= NULL
;
803 UErrorCode errorCode
= U_ZERO_ERROR
;
804 UDate startTime
, endTime
;
807 startTime
= uprv_getUTCtime();
809 /* Check whether ICU will initialize without forcing the build data directory into
810 * the ICU_DATA path. Success here means either the data dll contains data, or that
811 * this test program was run with ICU_DATA set externally. Failure of this check
812 * is normal when ICU data is not packaged into a shared library.
814 * Whether or not this test succeeds, we want to cleanup and reinitialize
815 * with a data path so that data loading from individual files can be tested.
818 if (U_FAILURE(errorCode
)) {
820 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
823 errorCode
= U_ZERO_ERROR
;
824 if (!initArgs(argc
, argv
, argHandler
, (void *) &STANDARD_TEST_FILE
)) {
825 /* Error already displayed. */
830 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
832 if (U_FAILURE(errorCode
)) {
834 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
835 "*** Check the ICU_DATA environment variable and \n"
836 "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
));
840 fprintf(stdout
, "Default charset for this run is %s\n", ucnv_getDefaultName());
843 nerrors
= runTestRequest(root
, argc
, argv
);
847 FILE* fileToRemove
= fopen(STANDARD_TEST_FILE
, "r");
848 /* This should delete any temporary files. */
850 fclose(fileToRemove
);
851 if (remove(STANDARD_TEST_FILE
) != 0) {
852 /* Maybe someone didn't close the file correctly. */
853 fprintf(stderr
, "FAIL: Could not delete %s\n", STANDARD_TEST_FILE
);
860 cleanUpTestTree(root
);
861 DataDrivenLogger::cleanUp();
864 endTime
= uprv_getUTCtime();
865 diffTime
= (int32_t)(endTime
- startTime
);
866 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
867 (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
),
868 (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
),
869 (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
),
870 (int)(diffTime%U_MILLIS_PER_SECOND
));