]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/iotest/iotest.cpp
ICU-491.11.3.tar.gz
[apple/icu.git] / icuSources / test / iotest / iotest.cpp
1 /*
2 **********************************************************************
3 * Copyright (C) 2002-2011, 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 "ustr_cnv.h"
24 #include "iotest.h"
25 #include "unicode/tstdtmod.h"
26 #include "putilimp.h"
27
28 #include <string.h>
29 #include <stdlib.h>
30
31 class DataDrivenLogger : public TestLog {
32 static const char* fgDataDir;
33 static char *fgTestDataPath;
34
35 public:
36 static void cleanUp() {
37 if (fgTestDataPath) {
38 free(fgTestDataPath);
39 fgTestDataPath = NULL;
40 }
41 }
42 virtual void errln( const UnicodeString &message ) {
43 char buffer[4000];
44 message.extract(0, message.length(), buffer, sizeof(buffer));
45 buffer[3999] = 0; /* NULL terminate */
46 log_err(buffer);
47 }
48
49 virtual void logln( const UnicodeString &message ) {
50 char buffer[4000];
51 message.extract(0, message.length(), buffer, sizeof(buffer));
52 buffer[3999] = 0; /* NULL terminate */
53 log_info(buffer);
54 }
55
56 virtual void dataerrln( const UnicodeString &message ) {
57 char buffer[4000];
58 message.extract(0, message.length(), buffer, sizeof(buffer));
59 buffer[3999] = 0; /* NULL terminate */
60 log_data_err(buffer);
61 }
62
63 static const char * pathToDataDirectory(void)
64 {
65
66 if(fgDataDir != NULL) {
67 return fgDataDir;
68 }
69
70 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
71 // to point to the top of the build hierarchy, which may or
72 // may not be the same as the source directory, depending on
73 // the configure options used. At any rate,
74 // set the data path to the built data from this directory.
75 // The value is complete with quotes, so it can be used
76 // as-is as a string constant.
77 */
78 #if defined (U_TOPSRCDIR)
79 {
80 fgDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
81 }
82 #else
83
84 /* On Windows, the file name obtained from __FILE__ includes a full path.
85 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
86 * Change to "wherever\icu\source\data"
87 */
88 {
89 static char p[sizeof(__FILE__) + 10];
90 char *pBackSlash;
91 int i;
92
93 strcpy(p, __FILE__);
94 /* We want to back over three '\' chars. */
95 /* Only Windows should end up here, so looking for '\' is safe. */
96 for (i=1; i<=3; i++) {
97 pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
98 if (pBackSlash != NULL) {
99 *pBackSlash = 0; /* Truncate the string at the '\' */
100 }
101 }
102
103 if (pBackSlash != NULL) {
104 /* We found and truncated three names from the path.
105 * Now append "source\data" and set the environment
106 */
107 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
108 fgDataDir = p;
109 }
110 else {
111 /* __FILE__ on MSVC7 does not contain the directory */
112 FILE *file = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
113 if (file) {
114 fclose(file);
115 fgDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
116 }
117 else {
118 fgDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
119 }
120 }
121 }
122 #endif
123
124 return fgDataDir;
125
126 }
127
128 static const char* loadTestData(UErrorCode& err){
129 if( fgTestDataPath == NULL){
130 const char* directory=NULL;
131 UResourceBundle* test =NULL;
132 char* tdpath=NULL;
133 const char* tdrelativepath;
134
135 #if defined (U_TOPBUILDDIR)
136 tdrelativepath = "test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
137 directory = U_TOPBUILDDIR;
138 #else
139 tdrelativepath = ".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
140 directory = pathToDataDirectory();
141 #endif
142
143 tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
144
145
146 /* u_getDataDirectory shoul return \source\data ... set the
147 * directory to ..\source\data\..\test\testdata\out\testdata
148 */
149 strcpy(tdpath, directory);
150 strcat(tdpath, tdrelativepath);
151 strcat(tdpath,"testdata");
152
153 test=ures_open(tdpath, "testtypes", &err);
154
155 if(U_FAILURE(err)){
156 err = U_FILE_ACCESS_ERROR;
157 log_data_err("Could not load testtypes.res in testdata bundle with path %s - %s\n", tdpath, u_errorName(err));
158 return "";
159 }
160 ures_close(test);
161 fgTestDataPath = tdpath;
162 }
163 return fgTestDataPath;
164 }
165
166 virtual const char* getTestDataPath(UErrorCode& err) {
167 return loadTestData(err);
168 }
169 };
170
171 const char* DataDrivenLogger::fgDataDir = NULL;
172 char* DataDrivenLogger::fgTestDataPath = NULL;
173
174 static int64_t
175 uto64(const UChar *buffer)
176 {
177 int64_t result = 0;
178 /* iterate through buffer */
179 while(*buffer) {
180 /* read the next digit */
181 result *= 16;
182 if (!u_isxdigit(*buffer)) {
183 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar)*buffer);
184 }
185 result += *buffer - 0x0030 - (*buffer >= 0x0041 ? (*buffer >= 0x0061 ? 39 : 7) : 0);
186 buffer++;
187 }
188 return result;
189 }
190
191
192 U_CDECL_BEGIN
193 static void U_CALLCONV DataDrivenPrintf(void)
194 {
195 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
196 UErrorCode errorCode;
197 TestDataModule *dataModule;
198 TestData *testData;
199 const DataMap *testCase;
200 DataDrivenLogger logger;
201 UChar uBuffer[512];
202 char cBuffer[512];
203 char cFormat[sizeof(cBuffer)];
204 char cExpected[sizeof(cBuffer)];
205 UnicodeString tempStr;
206 UChar format[512];
207 UChar expectedResult[512];
208 UChar argument[512];
209 int32_t i;
210 int8_t i8;
211 int16_t i16;
212 int32_t i32;
213 int64_t i64;
214 double dbl;
215 int32_t uBufferLenReturned;
216
217 const char *fileLocale = "en_US_POSIX";
218 int32_t uFileBufferLenReturned;
219 LocalUFILEPointer testFile;
220
221 errorCode=U_ZERO_ERROR;
222 dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode);
223 if(U_SUCCESS(errorCode)) {
224 testData=dataModule->createTestData("printf", errorCode);
225 if(U_SUCCESS(errorCode)) {
226 for(i=0; testData->nextCase(testCase, errorCode); ++i) {
227 if(U_FAILURE(errorCode)) {
228 log_err("error retrieving icuio/printf test case %d - %s\n",
229 i, u_errorName(errorCode));
230 errorCode=U_ZERO_ERROR;
231 continue;
232 }
233 testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8"));
234 if (testFile.isNull()) {
235 log_err("Can't open test file - %s\n",
236 STANDARD_TEST_FILE);
237 continue;
238 }
239 u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0]));
240 uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0;
241 tempStr=testCase->getString("format", errorCode);
242 tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode);
243 tempStr=testCase->getString("result", errorCode);
244 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode);
245 tempStr=testCase->getString("argument", errorCode);
246 tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode);
247 u_austrncpy(cBuffer, format, sizeof(cBuffer));
248 if(U_FAILURE(errorCode)) {
249 log_err("error retrieving icuio/printf test case %d - %s\n",
250 i, u_errorName(errorCode));
251 errorCode=U_ZERO_ERROR;
252 continue;
253 }
254 log_verbose("Test %d: format=\"%s\"\n", i, cBuffer);
255 switch (testCase->getString("argumentType", errorCode)[0]) {
256 case 0x64: // 'd' double
257 dbl = atof(u_austrcpy(cBuffer, argument));
258 uBufferLenReturned = u_sprintf_u(uBuffer, format, dbl);
259 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, dbl);
260 break;
261 case 0x31: // '1' int8_t
262 i8 = (int8_t)uto64(argument);
263 uBufferLenReturned = u_sprintf_u(uBuffer, format, i8);
264 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i8);
265 break;
266 case 0x32: // '2' int16_t
267 i16 = (int16_t)uto64(argument);
268 uBufferLenReturned = u_sprintf_u(uBuffer, format, i16);
269 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i16);
270 break;
271 case 0x34: // '4' int32_t
272 i32 = (int32_t)uto64(argument);
273 uBufferLenReturned = u_sprintf_u(uBuffer, format, i32);
274 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i32);
275 break;
276 case 0x38: // '8' int64_t
277 i64 = uto64(argument);
278 uBufferLenReturned = u_sprintf_u(uBuffer, format, i64);
279 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, i64);
280 break;
281 case 0x73: // 's' char *
282 u_austrncpy(cBuffer, argument, sizeof(cBuffer));
283 uBufferLenReturned = u_sprintf_u(uBuffer, format, cBuffer);
284 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, cBuffer);
285 break;
286 case 0x53: // 'S' UChar *
287 uBufferLenReturned = u_sprintf_u(uBuffer, format, argument);
288 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, argument);
289 break;
290 default:
291 uBufferLenReturned = 0;
292 uFileBufferLenReturned = 0;
293 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
294 }
295 if (u_strcmp(uBuffer, expectedResult) != 0) {
296 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
297 u_austrncpy(cFormat, format, sizeof(cFormat));
298 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
299 cBuffer[sizeof(cBuffer)-1] = 0;
300 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
301 i, cFormat, cBuffer, cExpected);
302 }
303 if (uBufferLenReturned <= 0) {
304 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
305 i, cBuffer);
306 }
307 else if (uBuffer[uBufferLenReturned-1] == 0
308 || uBuffer[uBufferLenReturned] != 0
309 || uBuffer[uBufferLenReturned+1] != 0x2A
310 || uBuffer[uBufferLenReturned+2] != 0x2A)
311 {
312 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
313 cBuffer[sizeof(cBuffer)-1] = 0;
314 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
315 i, cBuffer, uBufferLenReturned);
316 }
317 testFile.adoptInstead(u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8"));
318 if (testFile.isNull()) {
319 log_err("Can't open test file - %s\n",
320 STANDARD_TEST_FILE);
321 }
322 uBuffer[0]=0;
323 u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile.getAlias());
324 if (u_strcmp(uBuffer, expectedResult) != 0) {
325 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
326 u_austrncpy(cFormat, format, sizeof(cFormat));
327 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
328 cBuffer[sizeof(cBuffer)-1] = 0;
329 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
330 i, cFormat, cBuffer, cExpected);
331 }
332 if (uFileBufferLenReturned != uBufferLenReturned)
333 {
334 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
335 cBuffer[sizeof(cBuffer)-1] = 0;
336 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
337 uFileBufferLenReturned, uBufferLenReturned);
338 }
339
340 if(U_FAILURE(errorCode)) {
341 log_err("error running icuio/printf test case %d - %s\n",
342 i, u_errorName(errorCode));
343 errorCode=U_ZERO_ERROR;
344 continue;
345 }
346 }
347 delete testData;
348 }
349 delete dataModule;
350 }
351 else {
352 log_data_err("Failed: could not load test icuio data\n");
353 }
354 #endif
355 }
356 U_CDECL_END
357
358 U_CDECL_BEGIN
359 static void U_CALLCONV DataDrivenScanf(void)
360 {
361 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
362 UErrorCode errorCode;
363 TestDataModule *dataModule;
364 TestData *testData;
365 const DataMap *testCase;
366 DataDrivenLogger logger;
367 UChar uBuffer[512];
368 char cBuffer[512];
369 char cExpected[sizeof(cBuffer)];
370 UnicodeString tempStr;
371 UChar format[512];
372 UChar expectedResult[512];
373 UChar argument[512];
374 int32_t i;
375 int8_t i8, expected8;
376 int16_t i16, expected16;
377 int32_t i32, expected32;
378 int64_t i64, expected64;
379 double dbl, expectedDbl;
380 volatile float flt, expectedFlt; // Use volatile in order to get around an Intel compiler issue.
381 int32_t uBufferLenReturned;
382
383 //const char *fileLocale = "en_US_POSIX";
384 //int32_t uFileBufferLenReturned;
385 //UFILE *testFile;
386
387 errorCode=U_ZERO_ERROR;
388 dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode);
389 if(U_SUCCESS(errorCode)) {
390 testData=dataModule->createTestData("scanf", errorCode);
391 if(U_SUCCESS(errorCode)) {
392 for(i=0; testData->nextCase(testCase, errorCode); ++i) {
393 if(U_FAILURE(errorCode)) {
394 log_err("error retrieving icuio/printf test case %d - %s\n",
395 i, u_errorName(errorCode));
396 errorCode=U_ZERO_ERROR;
397 continue;
398 }
399 /* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
400 if (!testFile) {
401 log_err("Can't open test file - %s\n",
402 STANDARD_TEST_FILE);
403 }*/
404 u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0]));
405 uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0;
406 tempStr=testCase->getString("format", errorCode);
407 tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode);
408 tempStr=testCase->getString("result", errorCode);
409 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode);
410 tempStr=testCase->getString("argument", errorCode);
411 tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode);
412 u_austrncpy(cBuffer, format, sizeof(cBuffer));
413 if(U_FAILURE(errorCode)) {
414 log_err("error retrieving icuio/printf test case %d - %s\n",
415 i, u_errorName(errorCode));
416 errorCode=U_ZERO_ERROR;
417 continue;
418 }
419 log_verbose("Test %d: format=\"%s\"\n", i, cBuffer);
420 switch (testCase->getString("argumentType", errorCode)[0]) {
421 case 0x64: // 'd' double
422 expectedDbl = atof(u_austrcpy(cBuffer, expectedResult));
423 uBufferLenReturned = u_sscanf_u(argument, format, &dbl);
424 //uFileBufferLenReturned = u_fscanf_u(testFile, format, dbl);
425 if (dbl != expectedDbl) {
426 log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
427 i, dbl, expectedDbl);
428 }
429 break;
430 case 0x66: // 'f' float
431 expectedFlt = (float)atof(u_austrcpy(cBuffer, expectedResult));
432 uBufferLenReturned = u_sscanf_u(argument, format, &flt);
433 //uFileBufferLenReturned = u_fscanf_u(testFile, format, flt);
434 if (flt != expectedFlt) {
435 log_err("error in scanf test case[%d] Got: %f Exp: %f\n",
436 i, flt, expectedFlt);
437 }
438 break;
439 case 0x31: // '1' int8_t
440 expected8 = (int8_t)uto64(expectedResult);
441 uBufferLenReturned = u_sscanf_u(argument, format, &i8);
442 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i8);
443 if (i8 != expected8) {
444 log_err("error in scanf test case[%d] Got: %02X Exp: %02X\n",
445 i, i8, expected8);
446 }
447 break;
448 case 0x32: // '2' int16_t
449 expected16 = (int16_t)uto64(expectedResult);
450 uBufferLenReturned = u_sscanf_u(argument, format, &i16);
451 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i16);
452 if (i16 != expected16) {
453 log_err("error in scanf test case[%d] Got: %04X Exp: %04X\n",
454 i, i16, expected16);
455 }
456 break;
457 case 0x34: // '4' int32_t
458 expected32 = (int32_t)uto64(expectedResult);
459 uBufferLenReturned = u_sscanf_u(argument, format, &i32);
460 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i32);
461 if (i32 != expected32) {
462 log_err("error in scanf test case[%d] Got: %08X Exp: %08X\n",
463 i, i32, expected32);
464 }
465 break;
466 case 0x38: // '8' int64_t
467 expected64 = uto64(expectedResult);
468 uBufferLenReturned = u_sscanf_u(argument, format, &i64);
469 //uFileBufferLenReturned = u_fscanf_u(testFile, format, i64);
470 if (i64 != expected64) {
471 log_err("error in scanf 64-bit. Test case = %d\n", i);
472 }
473 break;
474 case 0x73: // 's' char *
475 u_austrcpy(cExpected, expectedResult);
476 uBufferLenReturned = u_sscanf_u(argument, format, cBuffer);
477 //uFileBufferLenReturned = u_fscanf_u(testFile, format, cBuffer);
478 if (strcmp(cBuffer, cExpected) != 0) {
479 log_err("error in scanf char * string. Got \"%s\" Expected \"%s\". Test case = %d\n", cBuffer, cExpected, i);
480 }
481 break;
482 case 0x53: // 'S' UChar *
483 uBufferLenReturned = u_sscanf_u(argument, format, uBuffer);
484 //uFileBufferLenReturned = u_fscanf_u(testFile, format, argument);
485 if (u_strcmp(uBuffer, expectedResult) != 0) {
486 u_austrcpy(cExpected, format);
487 u_austrcpy(cBuffer, uBuffer);
488 log_err("error in scanf UChar * string %s Got: \"%s\". Test case = %d\n", cExpected, cBuffer, i);
489 }
490 break;
491 default:
492 uBufferLenReturned = 0;
493 //uFileBufferLenReturned = 0;
494 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
495 }
496 if (uBufferLenReturned != 1) {
497 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned, i);
498 }
499 /* if (u_strcmp(uBuffer, expectedResult) != 0) {
500 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
501 u_austrncpy(cFormat, format, sizeof(cFormat));
502 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
503 cBuffer[sizeof(cBuffer)-1] = 0;
504 log_err("FAILURE string test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
505 i, cFormat, cBuffer, cExpected);
506 }
507 if (uBuffer[uBufferLenReturned-1] == 0
508 || uBuffer[uBufferLenReturned] != 0
509 || uBuffer[uBufferLenReturned+1] != 0x2A
510 || uBuffer[uBufferLenReturned+2] != 0x2A)
511 {
512 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
513 cBuffer[sizeof(cBuffer)-1] = 0;
514 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
515 i, cBuffer, uBufferLenReturned);
516 }*/
517 /* u_fclose(testFile);
518 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
519 if (!testFile) {
520 log_err("Can't open test file - %s\n",
521 STANDARD_TEST_FILE);
522 }
523 uBuffer[0];
524 u_fgets(uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]), testFile);
525 if (u_strcmp(uBuffer, expectedResult) != 0) {
526 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
527 u_austrncpy(cFormat, format, sizeof(cFormat));
528 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
529 cBuffer[sizeof(cBuffer)-1] = 0;
530 log_err("FAILURE file test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
531 i, cFormat, cBuffer, cExpected);
532 }
533 if (uFileBufferLenReturned != uBufferLenReturned)
534 {
535 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
536 cBuffer[sizeof(cBuffer)-1] = 0;
537 log_err("FAILURE uFileBufferLenReturned(%d) != uBufferLenReturned(%d)\n",
538 uFileBufferLenReturned, uBufferLenReturned);
539 }
540 */
541 if(U_FAILURE(errorCode)) {
542 log_err("error running icuio/printf test case %d - %s\n",
543 i, u_errorName(errorCode));
544 errorCode=U_ZERO_ERROR;
545 continue;
546 }
547 // u_fclose(testFile);
548 }
549 delete testData;
550 }
551 delete dataModule;
552 }
553 else {
554 log_data_err("Failed: could not load test icuio data\n");
555 }
556 #endif
557 }
558 U_CDECL_END
559
560 U_CDECL_BEGIN
561 static void U_CALLCONV DataDrivenPrintfPrecision(void)
562 {
563 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
564 UErrorCode errorCode;
565 TestDataModule *dataModule;
566 TestData *testData;
567 const DataMap *testCase;
568 DataDrivenLogger logger;
569 UChar uBuffer[512];
570 char cBuffer[512];
571 char cFormat[sizeof(cBuffer)];
572 char cExpected[sizeof(cBuffer)];
573 UnicodeString tempStr;
574 UChar format[512];
575 UChar expectedResult[512];
576 UChar argument[512];
577 int32_t precision;
578 int32_t i;
579 int8_t i8;
580 int16_t i16;
581 int32_t i32;
582 int64_t i64;
583 double dbl;
584 int32_t uBufferLenReturned;
585
586 errorCode=U_ZERO_ERROR;
587 dataModule=TestDataModule::getTestDataModule("icuio", logger, errorCode);
588 if(U_SUCCESS(errorCode)) {
589 testData=dataModule->createTestData("printfPrecision", errorCode);
590 if(U_SUCCESS(errorCode)) {
591 for(i=0; testData->nextCase(testCase, errorCode); ++i) {
592 if(U_FAILURE(errorCode)) {
593 log_err("error retrieving icuio/printf test case %d - %s\n",
594 i, u_errorName(errorCode));
595 errorCode=U_ZERO_ERROR;
596 continue;
597 }
598 u_memset(uBuffer, 0x2A, sizeof(uBuffer)/sizeof(uBuffer[0]));
599 uBuffer[sizeof(uBuffer)/sizeof(uBuffer[0])-1] = 0;
600 tempStr=testCase->getString("format", errorCode);
601 tempStr.extract(format, sizeof(format)/sizeof(format[0]), errorCode);
602 tempStr=testCase->getString("result", errorCode);
603 tempStr.extract(expectedResult, sizeof(expectedResult)/sizeof(expectedResult[0]), errorCode);
604 tempStr=testCase->getString("argument", errorCode);
605 tempStr.extract(argument, sizeof(argument)/sizeof(argument[0]), errorCode);
606 precision=testCase->getInt28("precision", errorCode);
607 u_austrncpy(cBuffer, format, sizeof(cBuffer));
608 if(U_FAILURE(errorCode)) {
609 log_err("error retrieving icuio/printf test case %d - %s\n",
610 i, u_errorName(errorCode));
611 errorCode=U_ZERO_ERROR;
612 continue;
613 }
614 log_verbose("Test %d: format=\"%s\"\n", i, cBuffer);
615 switch (testCase->getString("argumentType", errorCode)[0]) {
616 case 0x64: // 'd' double
617 dbl = atof(u_austrcpy(cBuffer, argument));
618 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, dbl);
619 break;
620 case 0x31: // '1' int8_t
621 i8 = (int8_t)uto64(argument);
622 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i8);
623 break;
624 case 0x32: // '2' int16_t
625 i16 = (int16_t)uto64(argument);
626 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i16);
627 break;
628 case 0x34: // '4' int32_t
629 i32 = (int32_t)uto64(argument);
630 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i32);
631 break;
632 case 0x38: // '8' int64_t
633 i64 = uto64(argument);
634 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i64);
635 break;
636 case 0x73: // 's' char *
637 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
638 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, cBuffer);
639 break;
640 case 0x53: // 'S' UChar *
641 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, argument);
642 break;
643 default:
644 uBufferLenReturned = 0;
645 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
646 }
647 if (u_strcmp(uBuffer, expectedResult) != 0) {
648 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
649 u_austrncpy(cFormat, format, sizeof(cFormat));
650 u_austrncpy(cExpected, expectedResult, sizeof(cExpected));
651 cBuffer[sizeof(cBuffer)-1] = 0;
652 log_err("FAILURE test case %d \"%s\" - Got: \"%s\" Expected: \"%s\"\n",
653 i, cFormat, cBuffer, cExpected);
654 }
655 if (uBufferLenReturned <= 0) {
656 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
657 i, cBuffer);
658 }
659 else if (uBuffer[uBufferLenReturned-1] == 0
660 || uBuffer[uBufferLenReturned] != 0
661 || uBuffer[uBufferLenReturned+1] != 0x2A
662 || uBuffer[uBufferLenReturned+2] != 0x2A)
663 {
664 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
665 cBuffer[sizeof(cBuffer)-1] = 0;
666 log_err("FAILURE test case %d - \"%s\" wrong amount of characters was written. Got %d.\n",
667 i, cBuffer, uBufferLenReturned);
668 }
669 if(U_FAILURE(errorCode)) {
670 log_err("error running icuio/printf test case %d - %s\n",
671 i, u_errorName(errorCode));
672 errorCode=U_ZERO_ERROR;
673 continue;
674 }
675 }
676 delete testData;
677 }
678 delete dataModule;
679 }
680 else {
681 log_data_err("Failed: could not load test icuio data\n");
682 }
683 #endif
684 }
685 U_CDECL_END
686
687 static void addAllTests(TestNode** root) {
688 addFileTest(root);
689 addStringTest(root);
690 addTranslitTest(root);
691
692 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_LEGACY_CONVERSION
693 addTest(root, &DataDrivenPrintf, "datadriv/DataDrivenPrintf");
694 addTest(root, &DataDrivenPrintfPrecision, "datadriv/DataDrivenPrintfPrecision");
695 addTest(root, &DataDrivenScanf, "datadriv/DataDrivenScanf");
696 #endif
697 #if U_IOSTREAM_SOURCE >= 199711
698 addStreamTests(root);
699 #endif
700 }
701
702 /* returns the path to icu/source/data/out */
703 static const char *ctest_dataOutDir()
704 {
705 static const char *dataOutDir = NULL;
706
707 if(dataOutDir) {
708 return dataOutDir;
709 }
710
711 /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
712 // to point to the top of the build hierarchy, which may or
713 // may not be the same as the source directory, depending on
714 // the configure options used. At any rate,
715 // set the data path to the built data from this directory.
716 // The value is complete with quotes, so it can be used
717 // as-is as a string constant.
718 */
719 #if defined (U_TOPBUILDDIR)
720 {
721 dataOutDir = U_TOPBUILDDIR "data"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
722 }
723 #else
724
725 /* On Windows, the file name obtained from __FILE__ includes a full path.
726 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
727 * Change to "wherever\icu\source\data"
728 */
729 {
730 static char p[sizeof(__FILE__) + 20];
731 char *pBackSlash;
732 int i;
733
734 strcpy(p, __FILE__);
735 /* We want to back over three '\' chars. */
736 /* Only Windows should end up here, so looking for '\' is safe. */
737 for (i=1; i<=3; i++) {
738 pBackSlash = strrchr(p, U_FILE_SEP_CHAR);
739 if (pBackSlash != NULL) {
740 *pBackSlash = 0; /* Truncate the string at the '\' */
741 }
742 }
743
744 if (pBackSlash != NULL) {
745 /* We found and truncated three names from the path.
746 * Now append "source\data" and set the environment
747 */
748 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
749 dataOutDir = p;
750 }
751 else {
752 /* __FILE__ on MSVC7 does not contain the directory */
753 FILE *file = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
754 if (file) {
755 fclose(file);
756 dataOutDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
757 }
758 else {
759 dataOutDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
760 }
761 }
762 }
763 #endif
764
765 return dataOutDir;
766 }
767
768 /* ctest_setICU_DATA - if the ICU_DATA environment variable is not already
769 * set, try to deduce the directory in which ICU was built,
770 * and set ICU_DATA to "icu/source/data" in that location.
771 * The intent is to allow the tests to have a good chance
772 * of running without requiring that the user manually set
773 * ICU_DATA. Common data isn't a problem, since it is
774 * picked up via a static (build time) reference, but the
775 * tests dynamically load some data.
776 */
777 static void ctest_setICU_DATA() {
778
779 /* No location for the data dir was identifiable.
780 * Add other fallbacks for the test data location here if the need arises
781 */
782 if (getenv("ICU_DATA") == NULL) {
783 /* If ICU_DATA isn't set, set it to the usual location */
784 u_setDataDirectory(ctest_dataOutDir());
785 }
786 }
787
788 U_CDECL_BEGIN
789 /*
790 * Note: this assumes that context is a pointer to STANDARD_TEST_FILE. It would be
791 * cleaner to define an acutal context with a string pointer in it and set STANDARD_TEST_FILE
792 * after the call to initArgs()...
793 */
794 static int U_CALLCONV argHandler(int arg, int /*argc*/, const char * const argv[], void *context)
795 {
796 const char **str = (const char **) context;
797
798 if (argv[arg][0] != '/' && argv[arg][0] != '-') {
799 *str = argv[arg];
800 return 1;
801 }
802
803 return 0;
804 }
805 U_CDECL_END
806
807 int main(int argc, char* argv[])
808 {
809 int32_t nerrors = 0;
810 TestNode *root = NULL;
811 UErrorCode errorCode = U_ZERO_ERROR;
812 UDate startTime, endTime;
813 int32_t diffTime;
814
815 startTime = uprv_getRawUTCtime();
816
817 /* Check whether ICU will initialize without forcing the build data directory into
818 * the ICU_DATA path. Success here means either the data dll contains data, or that
819 * this test program was run with ICU_DATA set externally. Failure of this check
820 * is normal when ICU data is not packaged into a shared library.
821 *
822 * Whether or not this test succeeds, we want to cleanup and reinitialize
823 * with a data path so that data loading from individual files can be tested.
824 */
825 u_init(&errorCode);
826 if (U_FAILURE(errorCode)) {
827 fprintf(stderr,
828 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
829 }
830 u_cleanup();
831 errorCode = U_ZERO_ERROR;
832 if (!initArgs(argc, argv, argHandler, (void *) &STANDARD_TEST_FILE)) {
833 /* Error already displayed. */
834 return -1;
835 }
836
837 /* Initialize ICU */
838 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
839 u_init(&errorCode);
840 if (U_FAILURE(errorCode)) {
841 fprintf(stderr,
842 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
843 "*** Check the ICU_DATA environment variable and \n"
844 "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
845 return 1;
846 }
847
848 fprintf(stdout, "Default charset for this run is %s\n", ucnv_getDefaultName());
849
850 addAllTests(&root);
851 nerrors = runTestRequest(root, argc, argv);
852
853 #if 1
854 {
855 FILE* fileToRemove = fopen(STANDARD_TEST_FILE, "r");
856 /* This should delete any temporary files. */
857 if (fileToRemove) {
858 fclose(fileToRemove);
859 log_verbose("Deleting: %s\n", STANDARD_TEST_FILE);
860 if (remove(STANDARD_TEST_FILE) != 0) {
861 /* Maybe someone didn't close the file correctly. */
862 fprintf(stderr, "FAIL: Could not delete %s\n", STANDARD_TEST_FILE);
863 nerrors += 1;
864 }
865 }
866 }
867 #endif
868
869 cleanUpTestTree(root);
870 DataDrivenLogger::cleanUp();
871 u_cleanup();
872
873 endTime = uprv_getRawUTCtime();
874 diffTime = (int32_t)(endTime - startTime);
875 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
876 (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
877 (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
878 (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
879 (int)(diffTime%U_MILLIS_PER_SECOND));
880
881 return nerrors;
882 }