]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/iotest/iotest.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / test / iotest / iotest.cpp
1 /*
2 **********************************************************************
3 * Copyright (C) 2002-2016, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 * file name: iotest.cpp
7 * encoding: US-ASCII
8 * tab size: 8 (not used)
9 * indentation:4
10 *
11 * created on: 2002feb21
12 * created by: George Rhoten
13 */
14
15
16 #include "unicode/ustdio.h"
17 #include "unicode/uclean.h"
18
19 #include "unicode/ucnv.h"
20 #include "unicode/uchar.h"
21 #include "unicode/unistr.h"
22 #include "unicode/ustring.h"
23 #include "cmemory.h"
24 #include "ustr_cnv.h"
25 #include "iotest.h"
26 #include "unicode/tstdtmod.h"
27 #include "putilimp.h"
28
29 #include <string.h>
30 #include <stdlib.h>
31
32 class DataDrivenLogger : public TestLog {
33 static const char* fgDataDir;
34 static char *fgTestDataPath;
35
36 public:
37 static void cleanUp() {
38 if (fgTestDataPath) {
39 free(fgTestDataPath);
40 fgTestDataPath = NULL;
41 }
42 }
43 virtual void errln( const UnicodeString &message ) {
44 char buffer[4000];
45 message.extract(0, message.length(), buffer, sizeof(buffer));
46 buffer[3999] = 0; /* NULL terminate */
47 log_err(buffer);
48 }
49
50 virtual void logln( const UnicodeString &message ) {
51 char buffer[4000];
52 message.extract(0, message.length(), buffer, sizeof(buffer));
53 buffer[3999] = 0; /* NULL terminate */
54 log_info(buffer);
55 }
56
57 virtual void dataerrln( const UnicodeString &message ) {
58 char buffer[4000];
59 message.extract(0, message.length(), buffer, sizeof(buffer));
60 buffer[3999] = 0; /* NULL terminate */
61 log_data_err(buffer);
62 }
63
64 static const char * pathToDataDirectory(void)
65 {
66
67 if(fgDataDir != NULL) {
68 return fgDataDir;
69 }
70
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.
78 */
79 #if defined (U_TOPSRCDIR)
80 {
81 fgDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
82 }
83 #else
84
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"
88 */
89 {
90 static char p[sizeof(__FILE__) + 10];
91 char *pBackSlash;
92 int i;
93
94 strcpy(p, __FILE__);
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 '\' */
101 }
102 }
103
104 if (pBackSlash != NULL) {
105 /* We found and truncated three names from the path.
106 * Now append "source\data" and set the environment
107 */
108 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
109 fgDataDir = p;
110 }
111 else {
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");
114 if (file) {
115 fclose(file);
116 fgDataDir = ".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
117 }
118 else {
119 fgDataDir = ".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
120 }
121 }
122 }
123 #endif
124
125 return fgDataDir;
126
127 }
128
129 static const char* loadTestData(UErrorCode& err){
130 if( fgTestDataPath == NULL){
131 const char* directory=NULL;
132 UResourceBundle* test =NULL;
133 char* tdpath=NULL;
134 const char* tdrelativepath;
135
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;
139 #else
140 tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
141 directory = pathToDataDirectory();
142 #endif
143
144 tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
145
146
147 /* u_getDataDirectory shoul return \source\data ... set the
148 * directory to ..\source\data\..\test\testdata\out\testdata
149 */
150 strcpy(tdpath, directory);
151 strcat(tdpath, tdrelativepath);
152 strcat(tdpath,"testdata");
153
154 test=ures_open(tdpath, "testtypes", &err);
155
156 if(U_FAILURE(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));
159 return "";
160 }
161 ures_close(test);
162 fgTestDataPath = tdpath;
163 }
164 return fgTestDataPath;
165 }
166
167 virtual const char* getTestDataPath(UErrorCode& err) {
168 return loadTestData(err);
169 }
170 };
171
172 const char* DataDrivenLogger::fgDataDir = NULL;
173 char* DataDrivenLogger::fgTestDataPath = NULL;
174
175 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
176 static int64_t
177 uto64(const UChar *buffer)
178 {
179 int64_t result = 0;
180 /* iterate through buffer */
181 while(*buffer) {
182 /* read the next digit */
183 result *= 16;
184 if (!u_isxdigit(*buffer)) {
185 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar)*buffer);
186 }
187 result += *buffer - 0x0030 - (*buffer >= 0x0041 ? (*buffer >= 0x0061 ? 39 : 7) : 0);
188 buffer++;
189 }
190 return result;
191 }
192 #endif
193
194 U_CDECL_BEGIN
195 static void U_CALLCONV DataDrivenPrintf(void)
196 {
197 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
198 UErrorCode errorCode;
199 TestDataModule *dataModule;
200 TestData *testData;
201 const DataMap *testCase;
202 DataDrivenLogger logger;
203 UChar uBuffer[512];
204 char cBuffer[512];
205 char cFormat[sizeof(cBuffer)];
206 char cExpected[sizeof(cBuffer)];
207 UnicodeString tempStr;
208 UChar format[512];
209 UChar expectedResult[512];
210 UChar argument[512];
211 int32_t i;
212 int8_t i8;
213 int16_t i16;
214 int32_t i32;
215 int64_t i64;
216 double dbl;
217 int32_t uBufferLenReturned;
218
219 const char *fileLocale = "en_US_POSIX";
220 int32_t uFileBufferLenReturned;
221 LocalUFILEPointer testFile;
222
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;
233 continue;
234 }
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",
238 STANDARD_TEST_FILE);
239 continue;
240 }
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;
254 continue;
255 }
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);
262 break;
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);
267 break;
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);
272 break;
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);
277 break;
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);
282 break;
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);
287 break;
288 case 0x53: // 'S' UChar *
289 uBufferLenReturned = u_sprintf_u(uBuffer, format, argument);
290 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, argument);
291 break;
292 default:
293 uBufferLenReturned = 0;
294 uFileBufferLenReturned = 0;
295 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
296 }
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);
304 }
305 if (uBufferLenReturned <= 0) {
306 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
307 i, cBuffer);
308 }
309 else if (uBuffer[uBufferLenReturned-1] == 0
310 || uBuffer[uBufferLenReturned] != 0
311 || uBuffer[uBufferLenReturned+1] != 0x2A
312 || uBuffer[uBufferLenReturned+2] != 0x2A)
313 {
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);
318 }
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",
322 STANDARD_TEST_FILE);
323 }
324 uBuffer[0]=0;
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);
333 }
334 if (uFileBufferLenReturned != uBufferLenReturned)
335 {
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);
340 }
341
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;
346 continue;
347 }
348 }
349 delete testData;
350 }
351 delete dataModule;
352 }
353 else {
354 log_data_err("Failed: could not load test icuio data\n");
355 }
356 #endif
357 }
358 U_CDECL_END
359
360 U_CDECL_BEGIN
361 static void U_CALLCONV DataDrivenScanf(void)
362 {
363 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
364 UErrorCode errorCode;
365 TestDataModule *dataModule;
366 TestData *testData;
367 const DataMap *testCase;
368 DataDrivenLogger logger;
369 UChar uBuffer[512];
370 char cBuffer[512];
371 char cExpected[sizeof(cBuffer)];
372 UnicodeString tempStr;
373 UChar format[512];
374 UChar expectedResult[512];
375 UChar argument[512];
376 int32_t i;
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;
384
385 //const char *fileLocale = "en_US_POSIX";
386 //int32_t uFileBufferLenReturned;
387 //UFILE *testFile;
388
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;
399 continue;
400 }
401 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
402 if (!testFile) {
403 log_err("Can't open test file - %s\n",
404 STANDARD_TEST_FILE);
405 }*/
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;
419 continue;
420 }
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);
430 }
431 break;
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);
439 }
440 break;
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",
447 i, i8, expected8);
448 }
449 break;
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",
456 i, i16, expected16);
457 }
458 break;
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",
465 i, i32, expected32);
466 }
467 break;
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);
474 }
475 break;
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);
482 }
483 break;
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);
491 }
492 break;
493 default:
494 uBufferLenReturned = 0;
495 //uFileBufferLenReturned = 0;
496 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
497 }
498 if (uBufferLenReturned != 1) {
499 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned, i);
500 }
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);
508 }
509 if (uBuffer[uBufferLenReturned-1] == 0
510 || uBuffer[uBufferLenReturned] != 0
511 || uBuffer[uBufferLenReturned+1] != 0x2A
512 || uBuffer[uBufferLenReturned+2] != 0x2A)
513 {
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);
518 }*/
519 /* u_fclose(testFile);
520 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
521 if (!testFile) {
522 log_err("Can't open test file - %s\n",
523 STANDARD_TEST_FILE);
524 }
525 uBuffer[0];
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);
534 }
535 if (uFileBufferLenReturned != uBufferLenReturned)
536 {
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);
541 }
542 */
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;
547 continue;
548 }
549 // u_fclose(testFile);
550 }
551 delete testData;
552 }
553 delete dataModule;
554 }
555 else {
556 log_data_err("Failed: could not load test icuio data\n");
557 }
558 #endif
559 }
560 U_CDECL_END
561
562 U_CDECL_BEGIN
563 static void U_CALLCONV DataDrivenPrintfPrecision(void)
564 {
565 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
566 UErrorCode errorCode;
567 TestDataModule *dataModule;
568 TestData *testData;
569 const DataMap *testCase;
570 DataDrivenLogger logger;
571 UChar uBuffer[512];
572 char cBuffer[512];
573 char cFormat[sizeof(cBuffer)];
574 char cExpected[sizeof(cBuffer)];
575 UnicodeString tempStr;
576 UChar format[512];
577 UChar expectedResult[512];
578 UChar argument[512];
579 int32_t precision;
580 int32_t i;
581 int8_t i8;
582 int16_t i16;
583 int32_t i32;
584 int64_t i64;
585 double dbl;
586 int32_t uBufferLenReturned;
587
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;
598 continue;
599 }
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;
614 continue;
615 }
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);
621 break;
622 case 0x31: // '1' int8_t
623 i8 = (int8_t)uto64(argument);
624 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i8);
625 break;
626 case 0x32: // '2' int16_t
627 i16 = (int16_t)uto64(argument);
628 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i16);
629 break;
630 case 0x34: // '4' int32_t
631 i32 = (int32_t)uto64(argument);
632 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i32);
633 break;
634 case 0x38: // '8' int64_t
635 i64 = uto64(argument);
636 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i64);
637 break;
638 case 0x73: // 's' char *
639 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
640 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, cBuffer);
641 break;
642 case 0x53: // 'S' UChar *
643 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, argument);
644 break;
645 default:
646 uBufferLenReturned = 0;
647 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
648 }
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);
656 }
657 if (uBufferLenReturned <= 0) {
658 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
659 i, cBuffer);
660 }
661 else if (uBuffer[uBufferLenReturned-1] == 0
662 || uBuffer[uBufferLenReturned] != 0
663 || uBuffer[uBufferLenReturned+1] != 0x2A
664 || uBuffer[uBufferLenReturned+2] != 0x2A)
665 {
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);
670 }
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;
675 continue;
676 }
677 }
678 delete testData;
679 }
680 delete dataModule;
681 }
682 else {
683 log_data_err("Failed: could not load test icuio data\n");
684 }
685 #endif
686 }
687 U_CDECL_END
688
689 static void addAllTests(TestNode** root) {
690 addFileTest(root);
691 addStringTest(root);
692 addTranslitTest(root);
693
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");
698 #endif
699 #if U_IOSTREAM_SOURCE >= 199711
700 addStreamTests(root);
701 #endif
702 }
703
704 /* returns the path to icu/source/data/out */
705 static const char *ctest_dataOutDir()
706 {
707 static const char *dataOutDir = NULL;
708
709 if(dataOutDir) {
710 return dataOutDir;
711 }
712
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.
720 */
721 #if defined (U_TOPBUILDDIR)
722 {
723 dataOutDir = U_TOPBUILDDIR "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
724 }
725 #else
726
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"
730 */
731 {
732 static char p[sizeof(__FILE__) + 20];
733 char *pBackSlash;
734 int i;
735
736 strcpy(p, __FILE__);
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 '\' */
743 }
744 }
745
746 if (pBackSlash != NULL) {
747 /* We found and truncated three names from the path.
748 * Now append "source\data" and set the environment
749 */
750 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
751 dataOutDir = p;
752 }
753 else {
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");
756 if (file) {
757 fclose(file);
758 dataOutDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
759 }
760 else {
761 dataOutDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
762 }
763 }
764 }
765 #endif
766
767 return dataOutDir;
768 }
769
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.
778 */
779 static void ctest_setICU_DATA() {
780
781 /* No location for the data dir was identifiable.
782 * Add other fallbacks for the test data location here if the need arises
783 */
784 if (getenv("ICU_DATA") == NULL) {
785 /* If ICU_DATA isn't set, set it to the usual location */
786 u_setDataDirectory(ctest_dataOutDir());
787 }
788 }
789
790 U_CDECL_BEGIN
791 /*
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()...
795 */
796 static int U_CALLCONV argHandler(int arg, int /*argc*/, const char * const argv[], void *context)
797 {
798 const char **str = (const char **) context;
799
800 if (argv[arg][0] != '/' && argv[arg][0] != '-') {
801 *str = argv[arg];
802 return 1;
803 }
804
805 return 0;
806 }
807 U_CDECL_END
808
809 int main(int argc, char* argv[])
810 {
811 int32_t nerrors = 0;
812 TestNode *root = NULL;
813 UErrorCode errorCode = U_ZERO_ERROR;
814 UDate startTime, endTime;
815 int32_t diffTime;
816
817 startTime = uprv_getRawUTCtime();
818
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.
823 *
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.
826 */
827 u_init(&errorCode);
828 if (U_FAILURE(errorCode)) {
829 fprintf(stderr,
830 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
831 }
832 u_cleanup();
833 errorCode = U_ZERO_ERROR;
834 if (!initArgs(argc, argv, argHandler, (void *) &STANDARD_TEST_FILE)) {
835 /* Error already displayed. */
836 return -1;
837 }
838
839 /* Initialize ICU */
840 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
841 u_init(&errorCode);
842 if (U_FAILURE(errorCode)) {
843 fprintf(stderr,
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));
847 return 1;
848 }
849
850 fprintf(stdout, "Default charset for this run is %s\n", ucnv_getDefaultName());
851
852 addAllTests(&root);
853 nerrors = runTestRequest(root, argc, argv);
854
855 #if 1
856 {
857 FILE* fileToRemove = fopen(STANDARD_TEST_FILE, "r");
858 /* This should delete any temporary files. */
859 if (fileToRemove) {
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);
865 nerrors += 1;
866 }
867 }
868 }
869 #endif
870
871 cleanUpTestTree(root);
872 DataDrivenLogger::cleanUp();
873 u_cleanup();
874
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));
882
883 return nerrors;
884 }