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