]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/test/iotest/iotest.cpp
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / test / iotest / iotest.cpp
... / ...
CommitLineData
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4**********************************************************************
5* Copyright (C) 2002-2016, International Business Machines
6* Corporation and others. All Rights Reserved.
7**********************************************************************
8* file name: iotest.cpp
9* encoding: UTF-8
10* tab size: 8 (not used)
11* indentation:4
12*
13* created on: 2002feb21
14* created by: George Rhoten
15*/
16
17
18#include "unicode/ustdio.h"
19#include "unicode/uclean.h"
20
21#include "unicode/ucnv.h"
22#include "unicode/uchar.h"
23#include "unicode/unistr.h"
24#include "unicode/ustring.h"
25#include "cmemory.h"
26#include "ustr_cnv.h"
27#include "iotest.h"
28#include "unicode/tstdtmod.h"
29#include "putilimp.h"
30
31#include <string.h>
32#include <stdlib.h>
33
34class DataDrivenLogger : public TestLog {
35 static const char* fgDataDir;
36 static char *fgTestDataPath;
37
38public:
39 static void cleanUp() {
40 if (fgTestDataPath) {
41 free(fgTestDataPath);
42 fgTestDataPath = NULL;
43 }
44 }
45 virtual void errln( const UnicodeString &message ) {
46 char buffer[4000];
47 message.extract(0, message.length(), buffer, sizeof(buffer));
48 buffer[3999] = 0; /* NULL terminate */
49 log_err(buffer);
50 }
51
52 virtual void logln( const UnicodeString &message ) {
53 char buffer[4000];
54 message.extract(0, message.length(), buffer, sizeof(buffer));
55 buffer[3999] = 0; /* NULL terminate */
56 log_info(buffer);
57 }
58
59 virtual void dataerrln( const UnicodeString &message ) {
60 char buffer[4000];
61 message.extract(0, message.length(), buffer, sizeof(buffer));
62 buffer[3999] = 0; /* NULL terminate */
63 log_data_err(buffer);
64 }
65
66 static const char * pathToDataDirectory(void)
67 {
68
69 if(fgDataDir != NULL) {
70 return fgDataDir;
71 }
72
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.
80 */
81 #if defined (U_TOPSRCDIR)
82 {
83 fgDataDir = U_TOPSRCDIR U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
84 }
85 #else
86
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"
90 */
91 {
92 static char p[sizeof(__FILE__) + 10];
93 char *pBackSlash;
94 int i;
95
96 strcpy(p, __FILE__);
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 '\' */
103 }
104 }
105
106 if (pBackSlash != NULL) {
107 /* We found and truncated three names from the path.
108 * Now append "source\data" and set the environment
109 */
110 strcpy(pBackSlash, U_FILE_SEP_STRING "data" U_FILE_SEP_STRING );
111 fgDataDir = p;
112 }
113 else {
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");
116 if (file) {
117 fclose(file);
118 fgDataDir = ".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
119 }
120 else {
121 fgDataDir = ".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
122 }
123 }
124 }
125 #endif
126
127 return fgDataDir;
128
129 }
130
131 static const char* loadTestData(UErrorCode& err){
132 if( fgTestDataPath == NULL){
133 const char* directory=NULL;
134 UResourceBundle* test =NULL;
135 char* tdpath=NULL;
136 const char* tdrelativepath;
137
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;
141#else
142 tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
143 directory = pathToDataDirectory();
144#endif
145
146 tdpath = (char*) malloc(sizeof(char) *(( strlen(directory) * strlen(tdrelativepath)) + 100));
147
148
149 /* u_getDataDirectory shoul return \source\data ... set the
150 * directory to ..\source\data\..\test\testdata\out\testdata
151 */
152 strcpy(tdpath, directory);
153 strcat(tdpath, tdrelativepath);
154 strcat(tdpath,"testdata");
155
156 test=ures_open(tdpath, "testtypes", &err);
157
158 if(U_FAILURE(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));
161 return "";
162 }
163 ures_close(test);
164 fgTestDataPath = tdpath;
165 }
166 return fgTestDataPath;
167 }
168
169 virtual const char* getTestDataPath(UErrorCode& err) {
170 return loadTestData(err);
171 }
172};
173
174const char* DataDrivenLogger::fgDataDir = NULL;
175char* DataDrivenLogger::fgTestDataPath = NULL;
176
177#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
178static int64_t
179uto64(const UChar *buffer)
180{
181 int64_t result = 0;
182 /* iterate through buffer */
183 while(*buffer) {
184 /* read the next digit */
185 result *= 16;
186 if (!u_isxdigit(*buffer)) {
187 log_err("\\u%04X is not a valid hex digit for this test\n", (UChar)*buffer);
188 }
189 result += *buffer - 0x0030 - (*buffer >= 0x0041 ? (*buffer >= 0x0061 ? 39 : 7) : 0);
190 buffer++;
191 }
192 return result;
193}
194#endif
195
196U_CDECL_BEGIN
197static void U_CALLCONV DataDrivenPrintf(void)
198{
199#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
200 UErrorCode errorCode;
201 TestDataModule *dataModule;
202 TestData *testData;
203 const DataMap *testCase;
204 DataDrivenLogger logger;
205 UChar uBuffer[512];
206 char cBuffer[512];
207 char cFormat[sizeof(cBuffer)];
208 char cExpected[sizeof(cBuffer)];
209 UnicodeString tempStr;
210 UChar format[512];
211 UChar expectedResult[512];
212 UChar argument[512];
213 int32_t i;
214 int8_t i8;
215 int16_t i16;
216 int32_t i32;
217 int64_t i64;
218 double dbl;
219 int32_t uBufferLenReturned;
220
221 const char *fileLocale = "en_US_POSIX";
222 int32_t uFileBufferLenReturned;
223 LocalUFILEPointer testFile;
224
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;
235 continue;
236 }
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",
240 STANDARD_TEST_FILE);
241 continue;
242 }
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;
256 continue;
257 }
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);
264 break;
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);
269 break;
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);
274 break;
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);
279 break;
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);
284 break;
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);
289 break;
290 case 0x53: // 'S' UChar *
291 uBufferLenReturned = u_sprintf_u(uBuffer, format, argument);
292 uFileBufferLenReturned = u_fprintf_u(testFile.getAlias(), format, argument);
293 break;
294 default:
295 uBufferLenReturned = 0;
296 uFileBufferLenReturned = 0;
297 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
298 }
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);
306 }
307 if (uBufferLenReturned <= 0) {
308 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
309 i, cBuffer);
310 }
311 else if (uBuffer[uBufferLenReturned-1] == 0
312 || uBuffer[uBufferLenReturned] != 0
313 || uBuffer[uBufferLenReturned+1] != 0x2A
314 || uBuffer[uBufferLenReturned+2] != 0x2A)
315 {
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);
320 }
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",
324 STANDARD_TEST_FILE);
325 }
326 uBuffer[0]=0;
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);
335 }
336 if (uFileBufferLenReturned != uBufferLenReturned)
337 {
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);
342 }
343
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;
348 continue;
349 }
350 }
351 delete testData;
352 }
353 delete dataModule;
354 }
355 else {
356 log_data_err("Failed: could not load test icuio data\n");
357 }
358#endif
359}
360U_CDECL_END
361
362U_CDECL_BEGIN
363static void U_CALLCONV DataDrivenScanf(void)
364{
365#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
366 UErrorCode errorCode;
367 TestDataModule *dataModule;
368 TestData *testData;
369 const DataMap *testCase;
370 DataDrivenLogger logger;
371 UChar uBuffer[512];
372 char cBuffer[512];
373 char cExpected[sizeof(cBuffer)];
374 UnicodeString tempStr;
375 UChar format[512];
376 UChar expectedResult[512];
377 UChar argument[512];
378 int32_t i;
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;
386
387 //const char *fileLocale = "en_US_POSIX";
388 //int32_t uFileBufferLenReturned;
389 //UFILE *testFile;
390
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;
401 continue;
402 }
403/* testFile = u_fopen(STANDARD_TEST_FILE, "w", fileLocale, "UTF-8");
404 if (!testFile) {
405 log_err("Can't open test file - %s\n",
406 STANDARD_TEST_FILE);
407 }*/
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;
421 continue;
422 }
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);
432 }
433 break;
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);
441 }
442 break;
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",
449 i, i8, expected8);
450 }
451 break;
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",
458 i, i16, expected16);
459 }
460 break;
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",
467 i, i32, expected32);
468 }
469 break;
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);
476 }
477 break;
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);
484 }
485 break;
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);
493 }
494 break;
495 default:
496 uBufferLenReturned = 0;
497 //uFileBufferLenReturned = 0;
498 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
499 }
500 if (uBufferLenReturned != 1) {
501 log_err("error scanf converted %d arguments. Test case = %d\n", uBufferLenReturned, i);
502 }
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);
510 }
511 if (uBuffer[uBufferLenReturned-1] == 0
512 || uBuffer[uBufferLenReturned] != 0
513 || uBuffer[uBufferLenReturned+1] != 0x2A
514 || uBuffer[uBufferLenReturned+2] != 0x2A)
515 {
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);
520 }*/
521/* u_fclose(testFile);
522 testFile = u_fopen(STANDARD_TEST_FILE, "r", fileLocale, "UTF-8");
523 if (!testFile) {
524 log_err("Can't open test file - %s\n",
525 STANDARD_TEST_FILE);
526 }
527 uBuffer[0];
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);
536 }
537 if (uFileBufferLenReturned != uBufferLenReturned)
538 {
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);
543 }
544*/
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;
549 continue;
550 }
551// u_fclose(testFile);
552 }
553 delete testData;
554 }
555 delete dataModule;
556 }
557 else {
558 log_data_err("Failed: could not load test icuio data\n");
559 }
560#endif
561}
562U_CDECL_END
563
564U_CDECL_BEGIN
565static void U_CALLCONV DataDrivenPrintfPrecision(void)
566{
567#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_FILE_IO
568 UErrorCode errorCode;
569 TestDataModule *dataModule;
570 TestData *testData;
571 const DataMap *testCase;
572 DataDrivenLogger logger;
573 UChar uBuffer[512];
574 char cBuffer[512];
575 char cFormat[sizeof(cBuffer)];
576 char cExpected[sizeof(cBuffer)];
577 UnicodeString tempStr;
578 UChar format[512];
579 UChar expectedResult[512];
580 UChar argument[512];
581 int32_t precision;
582 int32_t i;
583 int8_t i8;
584 int16_t i16;
585 int32_t i32;
586 int64_t i64;
587 double dbl;
588 int32_t uBufferLenReturned;
589
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;
600 continue;
601 }
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;
616 continue;
617 }
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);
623 break;
624 case 0x31: // '1' int8_t
625 i8 = (int8_t)uto64(argument);
626 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i8);
627 break;
628 case 0x32: // '2' int16_t
629 i16 = (int16_t)uto64(argument);
630 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i16);
631 break;
632 case 0x34: // '4' int32_t
633 i32 = (int32_t)uto64(argument);
634 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i32);
635 break;
636 case 0x38: // '8' int64_t
637 i64 = uto64(argument);
638 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, i64);
639 break;
640 case 0x73: // 's' char *
641 u_austrncpy(cBuffer, uBuffer, sizeof(cBuffer));
642 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, cBuffer);
643 break;
644 case 0x53: // 'S' UChar *
645 uBufferLenReturned = u_sprintf_u(uBuffer, format, precision, argument);
646 break;
647 default:
648 uBufferLenReturned = 0;
649 log_err("Unknown type %c for test %d\n", testCase->getString("argumentType", errorCode)[0], i);
650 }
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);
658 }
659 if (uBufferLenReturned <= 0) {
660 log_err("FAILURE test case %d - \"%s\" is an empty string.\n",
661 i, cBuffer);
662 }
663 else if (uBuffer[uBufferLenReturned-1] == 0
664 || uBuffer[uBufferLenReturned] != 0
665 || uBuffer[uBufferLenReturned+1] != 0x2A
666 || uBuffer[uBufferLenReturned+2] != 0x2A)
667 {
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);
672 }
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;
677 continue;
678 }
679 }
680 delete testData;
681 }
682 delete dataModule;
683 }
684 else {
685 log_data_err("Failed: could not load test icuio data\n");
686 }
687#endif
688}
689U_CDECL_END
690
691static void addAllTests(TestNode** root) {
692 addFileTest(root);
693 addStringTest(root);
694 addTranslitTest(root);
695
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");
700#endif
701 addStreamTests(root);
702}
703
704/* returns the path to icu/source/data/out */
705static 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 */
779static 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
790U_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 */
796static 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}
807U_CDECL_END
808
809int 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}