1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 **********************************************************************
5 * Copyright (C) 2002-2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 **********************************************************************
8 * file name: iotest.cpp
10 * tab size: 8 (not used)
13 * created on: 2002feb21
14 * created by: George Rhoten
18 #include "unicode/ustdio.h"
19 #include "unicode/uclean.h"
21 #include "unicode/ucnv.h"
22 #include "unicode/uchar.h"
23 #include "unicode/unistr.h"
24 #include "unicode/ustring.h"
28 #include "unicode/tstdtmod.h"
34 class DataDrivenLogger
: public TestLog
{
35 static const char* fgDataDir
;
36 static char *fgTestDataPath
;
39 static void cleanUp() {
42 fgTestDataPath
= NULL
;
45 virtual void errln( const UnicodeString
&message
) {
47 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
48 buffer
[3999] = 0; /* NULL terminate */
52 virtual void logln( const UnicodeString
&message
) {
54 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
55 buffer
[3999] = 0; /* NULL terminate */
59 virtual void dataerrln( const UnicodeString
&message
) {
61 message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
62 buffer
[3999] = 0; /* NULL terminate */
66 static const char * pathToDataDirectory(void)
69 if(fgDataDir
!= NULL
) {
73 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
74 // to point to the top of the build hierarchy, which may or
75 // may not be the same as the source directory, depending on
76 // the configure options used. At any rate,
77 // set the data path to the built data from this directory.
78 // The value is complete with quotes, so it can be used
79 // as-is as a string constant.
81 #if defined (U_TOPSRCDIR)
83 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
87 /* On Windows, the file name obtained from __FILE__ includes a full path.
88 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
89 * Change to "wherever\icu\source\data"
92 static char p
[sizeof(__FILE__
) + 10];
97 /* We want to back over three '\' chars. */
98 /* Only Windows should end up here, so looking for '\' is safe. */
99 for (i
=1; i
<=3; i
++) {
100 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
101 if (pBackSlash
!= NULL
) {
102 *pBackSlash
= 0; /* Truncate the string at the '\' */
106 if (pBackSlash
!= NULL
) {
107 /* We found and truncated three names from the path.
108 * Now append "source\data" and set the environment
110 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
114 /* __FILE__ on MSVC7 does not contain the directory */
115 FILE *file
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
118 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
121 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
131 static const char* loadTestData(UErrorCode
& err
){
132 if( fgTestDataPath
== NULL
){
133 const char* directory
=NULL
;
134 UResourceBundle
* test
=NULL
;
136 const char* tdrelativepath
;
138 #if defined (U_TOPBUILDDIR)
139 tdrelativepath
= "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
140 directory
= U_TOPBUILDDIR
;
142 tdrelativepath
= ".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
143 directory
= pathToDataDirectory();
146 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
149 /* u_getDataDirectory shoul return \source\data ... set the
150 * directory to ..\source\data\..\test\testdata\out\testdata
152 strcpy(tdpath
, directory
);
153 strcat(tdpath
, tdrelativepath
);
154 strcat(tdpath
,"testdata");
156 test
=ures_open(tdpath
, "testtypes", &err
);
159 err
= U_FILE_ACCESS_ERROR
;
160 log_data_err("Could not load testtypes.res in testdata bundle with path %s - %s\n", tdpath
, u_errorName(err
));
164 fgTestDataPath
= tdpath
;
166 return fgTestDataPath
;
169 virtual const char* getTestDataPath(UErrorCode
& err
) {
170 return loadTestData(err
);
174 const char* DataDrivenLogger::fgDataDir
= NULL
;
175 char* DataDrivenLogger::fgTestDataPath
= NULL
;
177 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
179 uto64(const UChar
*buffer
)
182 /* iterate through buffer */
184 /* read the next digit */
186 if (!u_isxdigit(*buffer
)) {
187 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar
)*buffer
);
189 result
+= *buffer
- 0x0030 - (*buffer
>= 0x0041 ? (*buffer
>= 0x0061 ? 39 : 7) : 0);
197 static void U_CALLCONV
DataDrivenPrintf(void)
199 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
200 UErrorCode errorCode
;
201 TestDataModule
*dataModule
;
203 const DataMap
*testCase
;
204 DataDrivenLogger logger
;
207 char cFormat
[sizeof(cBuffer
)];
208 char cExpected
[sizeof(cBuffer
)];
209 UnicodeString tempStr
;
211 UChar expectedResult
[512];
219 int32_t uBufferLenReturned
;
221 const char *fileLocale
= "en_US_POSIX";
222 int32_t uFileBufferLenReturned
;
223 LocalUFILEPointer testFile
;
225 errorCode
=U_ZERO_ERROR
;
226 dataModule
=TestDataModule::getTestDataModule("icuio", logger
, errorCode
);
227 if(U_SUCCESS(errorCode
)) {
228 testData
=dataModule
->createTestData("printf", errorCode
);
229 if(U_SUCCESS(errorCode
)) {
230 for(i
=0; testData
->nextCase(testCase
, errorCode
); ++i
) {
231 if(U_FAILURE(errorCode
)) {
232 log_err("error retrieving icuio/printf test case %d - %s\n",
233 i
, u_errorName(errorCode
));
234 errorCode
=U_ZERO_ERROR
;
237 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "w", fileLocale
, "UTF-8"));
238 if (testFile
.isNull()) {
239 log_err("Can't open test file - %s\n",
243 u_memset(uBuffer
, 0x2A, UPRV_LENGTHOF(uBuffer
));
244 uBuffer
[UPRV_LENGTHOF(uBuffer
)-1] = 0;
245 tempStr
=testCase
->getString("format", errorCode
);
246 tempStr
.extract(format
, UPRV_LENGTHOF(format
), errorCode
);
247 tempStr
=testCase
->getString("result", errorCode
);
248 tempStr
.extract(expectedResult
, UPRV_LENGTHOF(expectedResult
), errorCode
);
249 tempStr
=testCase
->getString("argument", errorCode
);
250 tempStr
.extract(argument
, UPRV_LENGTHOF(argument
), errorCode
);
251 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
252 if(U_FAILURE(errorCode
)) {
253 log_err("error retrieving icuio/printf test case %d - %s\n",
254 i
, u_errorName(errorCode
));
255 errorCode
=U_ZERO_ERROR
;
258 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
259 switch (testCase
->getString("argumentType", errorCode
)[0]) {
260 case 0x64: // 'd' double
261 dbl
= atof(u_austrcpy(cBuffer
, argument
));
262 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, dbl
);
263 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, dbl
);
265 case 0x31: // '1' int8_t
266 i8
= (int8_t)uto64(argument
);
267 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i8
);
268 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i8
);
270 case 0x32: // '2' int16_t
271 i16
= (int16_t)uto64(argument
);
272 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i16
);
273 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i16
);
275 case 0x34: // '4' int32_t
276 i32
= (int32_t)uto64(argument
);
277 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i32
);
278 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i32
);
280 case 0x38: // '8' int64_t
281 i64
= uto64(argument
);
282 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, i64
);
283 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, i64
);
285 case 0x73: // 's' char *
286 u_austrncpy(cBuffer
, argument
, sizeof(cBuffer
));
287 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, cBuffer
);
288 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, cBuffer
);
290 case 0x53: // 'S' UChar *
291 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, argument
);
292 uFileBufferLenReturned
= u_fprintf_u(testFile
.getAlias(), format
, argument
);
295 uBufferLenReturned
= 0;
296 uFileBufferLenReturned
= 0;
297 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
299 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
300 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
301 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
302 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
303 cBuffer
[sizeof(cBuffer
)-1] = 0;
304 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
305 i
, cFormat
, cBuffer
, cExpected
);
307 if (uBufferLenReturned
<= 0) {
308 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
311 else if (uBuffer
[uBufferLenReturned
-1] == 0
312 || uBuffer
[uBufferLenReturned
] != 0
313 || uBuffer
[uBufferLenReturned
+1] != 0x2A
314 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
316 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
317 cBuffer
[sizeof(cBuffer
)-1] = 0;
318 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
319 i
, cBuffer
, uBufferLenReturned
);
321 testFile
.adoptInstead(u_fopen(STANDARD_TEST_FILE
, "r", fileLocale
, "UTF-8"));
322 if (testFile
.isNull()) {
323 log_err("Can't open test file - %s\n",
327 u_fgets(uBuffer
, UPRV_LENGTHOF(uBuffer
), testFile
.getAlias());
328 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
329 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
330 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
331 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
332 cBuffer
[sizeof(cBuffer
)-1] = 0;
333 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
334 i
, cFormat
, cBuffer
, cExpected
);
336 if (uFileBufferLenReturned
!= uBufferLenReturned
)
338 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
339 cBuffer
[sizeof(cBuffer
)-1] = 0;
340 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
341 uFileBufferLenReturned
, uBufferLenReturned
);
344 if(U_FAILURE(errorCode
)) {
345 log_err("error running icuio/printf test case %d - %s\n",
346 i
, u_errorName(errorCode
));
347 errorCode
=U_ZERO_ERROR
;
356 log_data_err("Failed: could not load test icuio data\n");
363 static void U_CALLCONV
DataDrivenScanf(void)
365 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
366 UErrorCode errorCode
;
367 TestDataModule
*dataModule
;
369 const DataMap
*testCase
;
370 DataDrivenLogger logger
;
373 char cExpected
[sizeof(cBuffer
)];
374 UnicodeString tempStr
;
376 UChar expectedResult
[512];
379 int8_t i8
, expected8
;
380 int16_t i16
, expected16
;
381 int32_t i32
, expected32
;
382 int64_t i64
, expected64
;
383 double dbl
, expectedDbl
;
384 volatile float flt
, expectedFlt
; // Use volatile in order to get around an Intel compiler issue.
385 int32_t uBufferLenReturned
;
387 //const char *fileLocale = "en_US_POSIX";
388 //int32_t uFileBufferLenReturned;
391 errorCode
=U_ZERO_ERROR
;
392 dataModule
=TestDataModule::getTestDataModule("icuio", logger
, errorCode
);
393 if(U_SUCCESS(errorCode
)) {
394 testData
=dataModule
->createTestData("scanf", errorCode
);
395 if(U_SUCCESS(errorCode
)) {
396 for(i
=0; testData
->nextCase(testCase
, errorCode
); ++i
) {
397 if(U_FAILURE(errorCode
)) {
398 log_err("error retrieving icuio/printf test case %d - %s\n",
399 i
, u_errorName(errorCode
));
400 errorCode
=U_ZERO_ERROR
;
403 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
405 log_err("Can't open test file - %s\n",
408 u_memset(uBuffer
, 0x2A, UPRV_LENGTHOF(uBuffer
));
409 uBuffer
[UPRV_LENGTHOF(uBuffer
)-1] = 0;
410 tempStr
=testCase
->getString("format", errorCode
);
411 tempStr
.extract(format
, UPRV_LENGTHOF(format
), errorCode
);
412 tempStr
=testCase
->getString("result", errorCode
);
413 tempStr
.extract(expectedResult
, UPRV_LENGTHOF(expectedResult
), errorCode
);
414 tempStr
=testCase
->getString("argument", errorCode
);
415 tempStr
.extract(argument
, UPRV_LENGTHOF(argument
), errorCode
);
416 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
417 if(U_FAILURE(errorCode
)) {
418 log_err("error retrieving icuio/printf test case %d - %s\n",
419 i
, u_errorName(errorCode
));
420 errorCode
=U_ZERO_ERROR
;
423 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
424 switch (testCase
->getString("argumentType", errorCode
)[0]) {
425 case 0x64: // 'd' double
426 expectedDbl
= atof(u_austrcpy(cBuffer
, expectedResult
));
427 uBufferLenReturned
= u_sscanf_u(argument
, format
, &dbl
);
428 //uFileBufferLenReturned = u_fscanf_u(testFile, format, dbl);
429 if (dbl
!= expectedDbl
) {
430 log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
431 i
, dbl
, expectedDbl
);
434 case 0x66: // 'f' float
435 expectedFlt
= (float)atof(u_austrcpy(cBuffer
, expectedResult
));
436 uBufferLenReturned
= u_sscanf_u(argument
, format
, &flt
);
437 //uFileBufferLenReturned = u_fscanf_u(testFile, format, flt);
438 if (flt
!= expectedFlt
) {
439 log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
440 i
, flt
, expectedFlt
);
443 case 0x31: // '1' int8_t
444 expected8
= (int8_t)uto64(expectedResult
);
445 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i8
);
446 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8);
447 if (i8
!= expected8
) {
448 log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n",
452 case 0x32: // '2' int16_t
453 expected16
= (int16_t)uto64(expectedResult
);
454 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i16
);
455 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16);
456 if (i16
!= expected16
) {
457 log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n",
461 case 0x34: // '4' int32_t
462 expected32
= (int32_t)uto64(expectedResult
);
463 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i32
);
464 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32);
465 if (i32
!= expected32
) {
466 log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n",
470 case 0x38: // '8' int64_t
471 expected64
= uto64(expectedResult
);
472 uBufferLenReturned
= u_sscanf_u(argument
, format
, &i64
);
473 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i64);
474 if (i64
!= expected64
) {
475 log_err("error in scanf 64-bit. Test case = %d\n", i
);
478 case 0x73: // 's' char *
479 u_austrcpy(cExpected
, expectedResult
);
480 uBufferLenReturned
= u_sscanf_u(argument
, format
, cBuffer
);
481 //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
482 if (strcmp(cBuffer
, cExpected
) != 0) {
483 log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer
, cExpected
, i
);
486 case 0x53: // 'S' UChar *
487 uBufferLenReturned
= u_sscanf_u(argument
, format
, uBuffer
);
488 //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
489 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
490 u_austrcpy(cExpected
, format
);
491 u_austrcpy(cBuffer
, uBuffer
);
492 log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected
, cBuffer
, i
);
496 uBufferLenReturned
= 0;
497 //uFileBufferLenReturned = 0;
498 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
500 if (uBufferLenReturned
!= 1) {
501 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned
, i
);
503 /* if (u_strcmp(uBuffer, expectedResult) != 0) {
504 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
505 u_austrncpy(cFormat, format, sizeof(cFormat));
506 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
507 cBuffer[sizeof(cBuffer)-1] = 0;
508 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
509 i, cFormat, cBuffer, cExpected);
511 if (uBuffer[uBufferLenReturned-1] == 0
512 || uBuffer[uBufferLenReturned] != 0
513 || uBuffer[uBufferLenReturned+1] != 0x2A
514 || uBuffer[uBufferLenReturned+2] != 0x2A)
516 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
517 cBuffer[sizeof(cBuffer)-1] = 0;
518 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
519 i, cBuffer, uBufferLenReturned);
521 /* u_fclose(testFile);
522 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
524 log_err("Can't open test file - %s\n",
528 u_fgets(uBuffer, UPRV_LENGTHOF(uBuffer), testFile);
529 if (u_strcmp(uBuffer, expectedResult) != 0) {
530 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
531 u_austrncpy(cFormat, format, sizeof(cFormat));
532 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
533 cBuffer[sizeof(cBuffer)-1] = 0;
534 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
535 i, cFormat, cBuffer, cExpected);
537 if (uFileBufferLenReturned != uBufferLenReturned)
539 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
540 cBuffer[sizeof(cBuffer)-1] = 0;
541 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
542 uFileBufferLenReturned, uBufferLenReturned);
545 if(U_FAILURE(errorCode
)) {
546 log_err("error running icuio/printf test case %d - %s\n",
547 i
, u_errorName(errorCode
));
548 errorCode
=U_ZERO_ERROR
;
551 // u_fclose(testFile);
558 log_data_err("Failed: could not load test icuio data\n");
565 static void U_CALLCONV
DataDrivenPrintfPrecision(void)
567 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
568 UErrorCode errorCode
;
569 TestDataModule
*dataModule
;
571 const DataMap
*testCase
;
572 DataDrivenLogger logger
;
575 char cFormat
[sizeof(cBuffer
)];
576 char cExpected
[sizeof(cBuffer
)];
577 UnicodeString tempStr
;
579 UChar expectedResult
[512];
588 int32_t uBufferLenReturned
;
590 errorCode
=U_ZERO_ERROR
;
591 dataModule
=TestDataModule::getTestDataModule("icuio", logger
, errorCode
);
592 if(U_SUCCESS(errorCode
)) {
593 testData
=dataModule
->createTestData("printfPrecision", errorCode
);
594 if(U_SUCCESS(errorCode
)) {
595 for(i
=0; testData
->nextCase(testCase
, errorCode
); ++i
) {
596 if(U_FAILURE(errorCode
)) {
597 log_err("error retrieving icuio/printf test case %d - %s\n",
598 i
, u_errorName(errorCode
));
599 errorCode
=U_ZERO_ERROR
;
602 u_memset(uBuffer
, 0x2A, UPRV_LENGTHOF(uBuffer
));
603 uBuffer
[UPRV_LENGTHOF(uBuffer
)-1] = 0;
604 tempStr
=testCase
->getString("format", errorCode
);
605 tempStr
.extract(format
, UPRV_LENGTHOF(format
), errorCode
);
606 tempStr
=testCase
->getString("result", errorCode
);
607 tempStr
.extract(expectedResult
, UPRV_LENGTHOF(expectedResult
), errorCode
);
608 tempStr
=testCase
->getString("argument", errorCode
);
609 tempStr
.extract(argument
, UPRV_LENGTHOF(argument
), errorCode
);
610 precision
=testCase
->getInt28("precision", errorCode
);
611 u_austrncpy(cBuffer
, format
, sizeof(cBuffer
));
612 if(U_FAILURE(errorCode
)) {
613 log_err("error retrieving icuio/printf test case %d - %s\n",
614 i
, u_errorName(errorCode
));
615 errorCode
=U_ZERO_ERROR
;
618 log_verbose("Test %d: format=\"%s\"\n", i
, cBuffer
);
619 switch (testCase
->getString("argumentType", errorCode
)[0]) {
620 case 0x64: // 'd' double
621 dbl
= atof(u_austrcpy(cBuffer
, argument
));
622 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, dbl
);
624 case 0x31: // '1' int8_t
625 i8
= (int8_t)uto64(argument
);
626 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i8
);
628 case 0x32: // '2' int16_t
629 i16
= (int16_t)uto64(argument
);
630 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i16
);
632 case 0x34: // '4' int32_t
633 i32
= (int32_t)uto64(argument
);
634 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i32
);
636 case 0x38: // '8' int64_t
637 i64
= uto64(argument
);
638 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, i64
);
640 case 0x73: // 's' char *
641 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
642 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, cBuffer
);
644 case 0x53: // 'S' UChar *
645 uBufferLenReturned
= u_sprintf_u(uBuffer
, format
, precision
, argument
);
648 uBufferLenReturned
= 0;
649 log_err("Unknown type %c for test %d\n", testCase
->getString("argumentType", errorCode
)[0], i
);
651 if (u_strcmp(uBuffer
, expectedResult
) != 0) {
652 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
653 u_austrncpy(cFormat
, format
, sizeof(cFormat
));
654 u_austrncpy(cExpected
, expectedResult
, sizeof(cExpected
));
655 cBuffer
[sizeof(cBuffer
)-1] = 0;
656 log_err("FAILURE test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
657 i
, cFormat
, cBuffer
, cExpected
);
659 if (uBufferLenReturned
<= 0) {
660 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
663 else if (uBuffer
[uBufferLenReturned
-1] == 0
664 || uBuffer
[uBufferLenReturned
] != 0
665 || uBuffer
[uBufferLenReturned
+1] != 0x2A
666 || uBuffer
[uBufferLenReturned
+2] != 0x2A)
668 u_austrncpy(cBuffer
, uBuffer
, sizeof(cBuffer
));
669 cBuffer
[sizeof(cBuffer
)-1] = 0;
670 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
671 i
, cBuffer
, uBufferLenReturned
);
673 if(U_FAILURE(errorCode
)) {
674 log_err("error running icuio/printf test case %d - %s\n",
675 i
, u_errorName(errorCode
));
676 errorCode
=U_ZERO_ERROR
;
685 log_data_err("Failed: could not load test icuio data\n");
691 static void addAllTests(TestNode
** root
) {
694 addTranslitTest(root
);
696 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_LEGACY_CONVERSION
697 addTest(root
, &DataDrivenPrintf
, "datadriv/DataDrivenPrintf");
698 addTest(root
, &DataDrivenPrintfPrecision
, "datadriv/DataDrivenPrintfPrecision");
699 addTest(root
, &DataDrivenScanf
, "datadriv/DataDrivenScanf");
701 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
));