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