]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/iotest/strtst.c
ICU-6.2.16.tar.gz
[apple/icu.git] / icuSources / test / iotest / strtst.c
CommitLineData
374ca955
A
1/*
2**********************************************************************
3* Copyright (C) 2004-2004, International Business Machines
4* Corporation and others. All Rights Reserved.
5**********************************************************************
6* file name: strtst.c
7* encoding: US-ASCII
8* tab size: 8 (not used)
9* indentation:4
10*
11* created on: 2004apr06
12* created by: George Rhoten
13*/
14
15#include "unicode/ustdio.h"
16#include "unicode/ustring.h"
17#include "iotest.h"
18
19#include <string.h>
20
21static void TestString(void) {
22#if !UCONFIG_NO_FORMATTING
23 int32_t n[1];
24 float myFloat = -1234.0;
25 int32_t newValuePtr[1];
26 double newDoubleValuePtr[1];
27 UChar myUString[512];
28 UChar uStringBuf[512];
29 char myString[512] = "";
30 int32_t retVal;
31 void *origPtr, *ptr;
32 U_STRING_DECL(myStringOrig, "My-String", 9);
33
34 U_STRING_INIT(myStringOrig, "My-String", 9);
35 u_memset(myUString, 0x0a, sizeof(myUString)/ sizeof(*myUString));
36 u_memset(uStringBuf, 0x0a, sizeof(uStringBuf) / sizeof(*uStringBuf));
37
38 *n = -1234;
39 if (sizeof(void *) == 4) {
40 origPtr = (void *)0xdeadbeef;
41 } else if (sizeof(void *) == 8) {
42 origPtr = (void *) INT64_C(0x1000200030004000);
43 } else if (sizeof(void *) == 16) {
44 /* iSeries */
45 int32_t massiveBigEndianPtr[] = { 0x10002000, 0x30004000, 0x50006000, 0x70008000 };
46 origPtr = *((void **)massiveBigEndianPtr);
47 } else {
48 log_err("sizeof(void*)=%d hasn't been tested before", (int)sizeof(void*));
49 }
50
51 /* Test sprintf */
52 u_sprintf(uStringBuf, "Signed decimal integer d: %d", *n);
53 *newValuePtr = 1;
54 u_sscanf(uStringBuf, "Signed decimal integer d: %d", newValuePtr);
55 if (*n != *newValuePtr) {
56 log_err("%%d Got: %d, Expected: %d\n", *newValuePtr, *n);
57 }
58
59 u_sprintf(uStringBuf, "Signed decimal integer i: %i", *n);
60 *newValuePtr = 1;
61 u_sscanf(uStringBuf, "Signed decimal integer i: %i", newValuePtr);
62 if (*n != *newValuePtr) {
63 log_err("%%i Got: %i, Expected: %i\n", *newValuePtr, *n);
64 }
65
66 u_sprintf(uStringBuf, "Unsigned octal integer o: %o", *n);
67 *newValuePtr = 1;
68 u_sscanf(uStringBuf, "Unsigned octal integer o: %o", newValuePtr);
69 if (*n != *newValuePtr) {
70 log_err("%%o Got: %o, Expected: %o\n", *newValuePtr, *n);
71 }
72
73 u_sprintf(uStringBuf, "Unsigned decimal integer %%u: %u", *n);
74 *newValuePtr = 1;
75 u_sscanf(uStringBuf, "Unsigned decimal integer %%u: %u", newValuePtr);
76 if (*n != *newValuePtr) {
77 log_err("%%u Got: %u, Expected: %u\n", *newValuePtr, *n);
78 }
79
80 u_sprintf(uStringBuf, "Lowercase unsigned hexadecimal integer x: %x", *n);
81 *newValuePtr = 1;
82 u_sscanf(uStringBuf, "Lowercase unsigned hexadecimal integer x: %x", newValuePtr);
83 if (*n != *newValuePtr) {
84 log_err("%%x Got: %x, Expected: %x\n", *newValuePtr, *n);
85 }
86
87 u_sprintf(uStringBuf, "Uppercase unsigned hexadecimal integer X: %X", *n);
88 *newValuePtr = 1;
89 u_sscanf(uStringBuf, "Uppercase unsigned hexadecimal integer X: %X", newValuePtr);
90 if (*n != *newValuePtr) {
91 log_err("%%X Got: %X, Expected: %X\n", *newValuePtr, *n);
92 }
93
94 u_sprintf(uStringBuf, "Float f: %f", myFloat);
95 *newDoubleValuePtr = -1.0;
96 u_sscanf(uStringBuf, "Float f: %f", newDoubleValuePtr);
97 if (myFloat != *newDoubleValuePtr) {
98 log_err("%%f Got: %f, Expected: %f\n", *newDoubleValuePtr, myFloat);
99 }
100
101 u_sprintf(uStringBuf, "Lowercase float e: %e", myFloat);
102 *newDoubleValuePtr = -1.0;
103 u_sscanf(uStringBuf, "Lowercase float e: %e", newDoubleValuePtr);
104 if (myFloat != *newDoubleValuePtr) {
105 log_err("%%e Got: %e, Expected: %e\n", *newDoubleValuePtr, myFloat);
106 }
107
108 u_sprintf(uStringBuf, "Uppercase float E: %E", myFloat);
109 *newDoubleValuePtr = -1.0;
110 u_sscanf(uStringBuf, "Uppercase float E: %E", newDoubleValuePtr);
111 if (myFloat != *newDoubleValuePtr) {
112 log_err("%%E Got: %E, Expected: %E\n", *newDoubleValuePtr, myFloat);
113 }
114
115 u_sprintf(uStringBuf, "Lowercase float g: %g", myFloat);
116 *newDoubleValuePtr = -1.0;
117 u_sscanf(uStringBuf, "Lowercase float g: %g", newDoubleValuePtr);
118 if (myFloat != *newDoubleValuePtr) {
119 log_err("%%g Got: %g, Expected: %g\n", *newDoubleValuePtr, myFloat);
120 }
121
122 u_sprintf(uStringBuf, "Uppercase float G: %G", myFloat);
123 *newDoubleValuePtr = -1.0;
124 u_sscanf(uStringBuf, "Uppercase float G: %G", newDoubleValuePtr);
125 if (myFloat != *newDoubleValuePtr) {
126 log_err("%%G Got: %G, Expected: %G\n", *newDoubleValuePtr, myFloat);
127 }
128
129 ptr = NULL;
130 u_sprintf(uStringBuf, "Pointer %%p: %p\n", origPtr);
131 u_sscanf(uStringBuf, "Pointer %%p: %p\n", &ptr);
132 if (ptr != origPtr || u_strlen(uStringBuf) != 13+(sizeof(void*)*2)) {
133 log_err("%%p Got: %p, Expected: %p\n", ptr, origPtr);
134 }
135
136 u_sprintf(uStringBuf, "Char c: %c", 'A');
137 u_sscanf(uStringBuf, "Char c: %c", myString);
138 if (*myString != 'A') {
139 log_err("%%c Got: %c, Expected: A\n", *myString);
140 }
141
142 u_sprintf(uStringBuf, "UChar %%C: %C", (UChar)0x0041); /*'A'*/
143 u_sscanf(uStringBuf, "UChar %%C: %C", myUString);
144 if (*myUString != (UChar)0x0041) { /*'A'*/
145 log_err("%%C Got: %C, Expected: A\n", *myUString);
146 }
147
148 u_sprintf(uStringBuf, "String %%s: %s", "My-String");
149 u_sscanf(uStringBuf, "String %%s: %s", myString);
150 if (strcmp(myString, "My-String")) {
151 log_err("%%s Got: %s, Expected: My-String\n", myString);
152 }
153 if (uStringBuf[20] != 0) {
154 log_err("String not terminated. Got %c\n", uStringBuf[20] );
155 }
156 u_sprintf(uStringBuf, "NULL String %%s: %s", NULL);
157 u_sscanf(uStringBuf, "NULL String %%s: %s", myString);
158 if (strcmp(myString, "(null)")) {
159 log_err("%%s Got: %s, Expected: My-String\n", myString);
160 }
161
162 u_sprintf(uStringBuf, "Unicode String %%S: %S", myStringOrig);
163 u_sscanf(uStringBuf, "Unicode String %%S: %S", myUString);
164 u_austrncpy(myString, myUString, sizeof(myString)/sizeof(*myString));
165 if (strcmp(myString, "My-String")) {
166 log_err("%%S Got: %s, Expected: My String\n", myString);
167 }
168
169 u_sprintf(uStringBuf, "NULL Unicode String %%S: %S", NULL);
170 u_sscanf(uStringBuf, "NULL Unicode String %%S: %S", myUString);
171 u_austrncpy(myString, myUString, sizeof(myString)/sizeof(*myString));
172 if (strcmp(myString, "(null)")) {
173 log_err("%%S Got: %s, Expected: (null)\n", myString);
174 }
175
176 u_sprintf(uStringBuf, "Percent %%P (non-ANSI): %P", myFloat);
177 *newDoubleValuePtr = -1.0;
178 u_sscanf(uStringBuf, "Percent %%P (non-ANSI): %P", newDoubleValuePtr);
179 if (myFloat != *newDoubleValuePtr) {
180 log_err("%%P Got: %P, Expected: %P\n", *newDoubleValuePtr, myFloat);
181 }
182
183 u_sprintf(uStringBuf, "Spell Out %%V (non-ANSI): %V", myFloat);
184 *newDoubleValuePtr = -1.0;
185 u_sscanf(uStringBuf, "Spell Out %%V (non-ANSI): %V", newDoubleValuePtr);
186 if (myFloat != *newDoubleValuePtr) {
187 log_err("%%V Got: %f, Expected: %f\n", *newDoubleValuePtr, myFloat);
188 }
189
190 *newValuePtr = 1;
191 u_sprintf(uStringBuf, "\t\nPointer to integer (Count) %%n: n=%d %n n=%d\n", *newValuePtr, newValuePtr, *newValuePtr);
192 if (*newValuePtr != 37) {
193 log_err("%%V Got: %f, Expected: %f\n", *newDoubleValuePtr, myFloat);
194 }
195
196/* u_sscanf(uStringBuf, "Pointer %%p: %p\n", myFile);*/
197
198 {
199 static const char longStr[] = "This is a long test12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
200
201 retVal = u_sprintf(uStringBuf, longStr);
202 u_austrncpy(myString, uStringBuf, sizeof(uStringBuf)/sizeof(*uStringBuf));
203 if (strcmp(myString, longStr)) {
204 log_err("%%S Got: %s, Expected: %s\n", myString, longStr);
205 }
206 if (retVal != (int32_t)strlen(longStr)) {
207 log_err("%%S returned different sizes. Got: %d Expected: %d\n", retVal, strlen(longStr));
208 }
209
210 retVal = u_sprintf(uStringBuf, "%s", longStr);
211 u_austrncpy(myString, uStringBuf, sizeof(uStringBuf)/sizeof(*uStringBuf));
212 if (strcmp(myString, longStr)) {
213 log_err("%%S Got: %s, Expected: %s\n", myString, longStr);
214 }
215 if (retVal != (int32_t)strlen(longStr)) {
216 log_err("%%S returned different sizes. Got: %d Expected: %d\n", retVal, strlen(longStr));
217 }
218
219 u_uastrncpy(myUString, longStr, sizeof(longStr)/sizeof(*longStr));
220 u_sprintf_u(uStringBuf, myUString);
221 if (u_strcmp(myUString, uStringBuf)) {
222 log_err("%%S Long strings differ. Expected: %s\n", longStr);
223 }
224
225 u_uastrncpy(myUString, longStr, sizeof(longStr)/sizeof(*longStr));
226 retVal = u_sprintf_u(uStringBuf, myUString+10);
227 if (u_strcmp(myUString+10, uStringBuf)) {
228 log_err("%%S Long strings differ. Expected: %s\n", longStr + 10);
229 }
230 if (retVal != (int32_t)strlen(longStr + 10)) {
231 log_err("%%S returned different sizes. Got: %d Expected: %d\n", retVal, strlen(longStr));
232 }
233
234 u_memset(uStringBuf, 1, sizeof(longStr)/sizeof(*longStr));
235 u_uastrncpy(myUString, longStr, sizeof(longStr)/sizeof(*longStr));
236 retVal = u_snprintf_u(uStringBuf, 10, myUString);
237 if (u_strncmp(myUString, uStringBuf, 10) || uStringBuf[10] != 1 || retVal != 10) {
238 log_err("%%S Long strings differ. Expected the first 10 characters of %s\n", longStr);
239 }
240 }
241#endif
242}
243
244static void TestLocalizedString(void) {
245#if !UCONFIG_NO_FORMATTING
246 UChar testStr[256];
247 UChar uBuffer[256];
248 char cBuffer[256];
249 int32_t numResult = -1;
250 const char *locale;
251 UFILE *strFile = u_fstropen(testStr, sizeof(testStr)/sizeof(testStr[0]), "en_US");
252
253 if (!strFile) {
254 log_err("u_fstropen failed to work\n");
255 return;
256 }
257 u_fprintf(strFile, "%d", 1234);
258 u_frewind(strFile);
259 u_fscanf(strFile, "%d", &numResult);
260 u_uastrcpy(uBuffer,"1,234");
261 u_austrcpy(cBuffer,testStr);
262 if (u_strcmp(testStr, uBuffer) != 0) {
263 log_err("u_fprintf failed to work on an en string Got: %s\n", cBuffer);
264 }
265 if (numResult != 1234) {
266 log_err("u_fscanf failed to work on an en string Got: %d\n", numResult);
267 }
268
269 u_frewind(strFile);
270 locale = u_fgetlocale(strFile);
271 if (locale == NULL || strcmp(locale, "en_US") != 0) {
272 log_err("u_fgetlocale didn't return \"en\" Got: %d\n", u_fgetlocale(strFile));
273 }
274 u_fsetlocale(strFile, "de_DE");
275 locale = u_fgetlocale(strFile);
276 if (locale == NULL || strcmp(locale, "de_DE") != 0) {
277 log_err("u_fgetlocale didn't return \"de\" Got: %d\n", u_fgetlocale(strFile));
278 }
279
280 u_fprintf(strFile, "%d", 1234);
281 u_frewind(strFile);
282 u_fscanf(strFile, "%d", &numResult);
283 u_fclose(strFile);
284 u_uastrcpy(uBuffer,"1.234");
285 u_austrcpy(cBuffer,testStr);
286 if (u_strcmp(testStr, uBuffer) != 0) {
287 log_err("u_fprintf failed to work on a de string Got: %s\n", cBuffer);
288 }
289 if (numResult != 1234) {
290 log_err("u_fscanf failed to work on a de string Got: %d\n", numResult);
291 }
292#endif
293}
294
295#if !UCONFIG_NO_FORMATTING
296#define Test_u_snprintf(limit, format, value, expectedSize, expectedStr) \
297 u_uastrncpy(testStr, "xxxxxxxxxxxxxx", sizeof(testStr)/sizeof(testStr[0]));\
298 size = u_snprintf(testStr, limit, format, value);\
299 u_austrncpy(cTestResult, testStr, sizeof(cTestResult)/sizeof(cTestResult[0]));\
300 if (size != expectedSize || strcmp(cTestResult, expectedStr) != 0) {\
301 log_err("Unexpected formatting. size=%d expectedSize=%d cTestResult=%s expectedStr=%s\n",\
302 size, expectedSize, cTestResult, expectedStr);\
303 }\
304 else {\
305 log_verbose("Got: %s\n", cTestResult);\
306 }\
307
308#endif
309
310static void TestSnprintf(void) {
311#if !UCONFIG_NO_FORMATTING
312 UChar testStr[256];
313 char cTestResult[256];
314 int32_t size;
315
316 Test_u_snprintf(0, "%d", 123, 0, "xxxxxxxxxxxxxx");
317 Test_u_snprintf(2, "%d", 123, 2, "12xxxxxxxxxxxx");
318 Test_u_snprintf(3, "%d", 123, 3, "123xxxxxxxxxxx");
319 Test_u_snprintf(4, "%d", 123, 3, "123");
320
321 Test_u_snprintf(0, "%s", "abcd", 0, "xxxxxxxxxxxxxx");
322 Test_u_snprintf(3, "%s", "abcd", 3, "abcxxxxxxxxxxx");
323 Test_u_snprintf(4, "%s", "abcd", 4, "abcdxxxxxxxxxx");
324 Test_u_snprintf(5, "%s", "abcd", 4, "abcd");
325
326 Test_u_snprintf(0, "%e", 12.34, 0, "xxxxxxxxxxxxxx");
327 Test_u_snprintf(1, "%e", 12.34, 1, "1xxxxxxxxxxxxx");
328 Test_u_snprintf(2, "%e", 12.34, 2, "1.xxxxxxxxxxxx");
329 Test_u_snprintf(3, "%e", 12.34, 3, "1.2xxxxxxxxxxx");
330 Test_u_snprintf(5, "%e", 12.34, 5, "1.234xxxxxxxxx");
331 Test_u_snprintf(6, "%e", 12.34, 6, "1.2340xxxxxxxx");
332 Test_u_snprintf(8, "%e", 12.34, 8, "1.234000xxxxxx");
333 Test_u_snprintf(9, "%e", 12.34, 9, "1.234000exxxxx");
334 Test_u_snprintf(10, "%e", 12.34, 10, "1.234000e+xxxx");
335 Test_u_snprintf(11, "%e", 12.34, 11, "1.234000e+0xxx");
336 Test_u_snprintf(13, "%e", 12.34, 13, "1.234000e+001x");
337 Test_u_snprintf(14, "%e", 12.34, 13, "1.234000e+001");
338#endif
339}
340
341#define TestSPrintFormat(uFormat, uValue, cFormat, cValue) \
342 /* Reinitialize the buffer to verify null termination works. */\
343 u_memset(uBuffer, 0x2a, sizeof(uBuffer)/sizeof(*uBuffer));\
344 memset(buffer, '*', sizeof(buffer)/sizeof(*buffer));\
345 \
346 uNumPrinted = u_sprintf(uBuffer, uFormat, uValue);\
347 u_austrncpy(compBuffer, uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]));\
348 cNumPrinted = sprintf(buffer, cFormat, cValue);\
349 if (strcmp(buffer, compBuffer) != 0) {\
350 log_err("%" uFormat " Got: \"%s\", Expected: \"%s\"\n", compBuffer, buffer);\
351 }\
352 if (cNumPrinted != uNumPrinted) {\
353 log_err("%" uFormat " number printed Got: %d, Expected: %d\n", uNumPrinted, cNumPrinted);\
354 }\
355 if (buffer[uNumPrinted+1] != '*') {\
356 log_err("%" uFormat " too much stored\n");\
357 }\
358
359static void TestSprintfFormat(void) {
360#if !UCONFIG_NO_FORMATTING
361 static const UChar abcUChars[] = {0x61,0x62,0x63,0};
362 static const char abcChars[] = "abc";
363 UChar uBuffer[256];
364 char buffer[256];
365 char compBuffer[256];
366 int32_t uNumPrinted;
367 int32_t cNumPrinted;
368
369
370 TestSPrintFormat("%8S", abcUChars, "%8s", abcChars);
371 TestSPrintFormat("%-8S", abcUChars, "%-8s", abcChars);
372 TestSPrintFormat("%.2S", abcUChars, "%.2s", abcChars); /* strlen is 3 */
373
374 TestSPrintFormat("%8s", abcChars, "%8s", abcChars);
375 TestSPrintFormat("%-8s", abcChars, "%-8s", abcChars);
376 TestSPrintFormat("%.2s", abcChars, "%.2s", abcChars); /* strlen is 3 */
377
378 TestSPrintFormat("%8c", (char)'e', "%8c", (char)'e');
379 TestSPrintFormat("%-8c", (char)'e', "%-8c", (char)'e');
380
381 TestSPrintFormat("%8C", (UChar)0x65, "%8c", (char)'e');
382 TestSPrintFormat("%-8C", (UChar)0x65, "%-8c", (char)'e');
383
384 TestSPrintFormat("%f", 1.23456789, "%f", 1.23456789);
385 TestSPrintFormat("%f", 12345.6789, "%f", 12345.6789);
386 TestSPrintFormat("%f", 123456.789, "%f", 123456.789);
387 TestSPrintFormat("%f", 1234567.89, "%f", 1234567.89);
388 TestSPrintFormat("%10f", 1.23456789, "%10f", 1.23456789);
389 TestSPrintFormat("%-10f", 1.23456789, "%-10f", 1.23456789);
390 TestSPrintFormat("%10f", 123.456789, "%10f", 123.456789);
391 TestSPrintFormat("%10.4f", 123.456789, "%10.4f", 123.456789);
392 TestSPrintFormat("%-10f", 123.456789, "%-10f", 123.456789);
393
394/* TestSPrintFormat("%g", 12345.6789, "%g", 12345.6789);
395 TestSPrintFormat("%g", 123456.789, "%g", 123456.789);
396 TestSPrintFormat("%g", 1234567.89, "%g", 1234567.89);
397 TestSPrintFormat("%G", 123456.789, "%G", 123456.789);
398 TestSPrintFormat("%G", 1234567.89, "%G", 1234567.89);*/
399 TestSPrintFormat("%10g", 1.23456789, "%10g", 1.23456789);
400 TestSPrintFormat("%10.4g", 1.23456789, "%10.4g", 1.23456789);
401 TestSPrintFormat("%-10g", 1.23456789, "%-10g", 1.23456789);
402 TestSPrintFormat("%10g", 123.456789, "%10g", 123.456789);
403 TestSPrintFormat("%-10g", 123.456789, "%-10g", 123.456789);
404
405 TestSPrintFormat("%8x", 123456, "%8x", 123456);
406 TestSPrintFormat("%-8x", 123456, "%-8x", 123456);
407 TestSPrintFormat("%08x", 123456, "%08x", 123456);
408
409 TestSPrintFormat("%8X", 123456, "%8X", 123456);
410 TestSPrintFormat("%-8X", 123456, "%-8X", 123456);
411 TestSPrintFormat("%08X", 123456, "%08X", 123456);
412 TestSPrintFormat("%#x", 123456, "%#x", 123456);
413 TestSPrintFormat("%#x", -123456, "%#x", -123456);
414
415 TestSPrintFormat("%8o", 123456, "%8o", 123456);
416 TestSPrintFormat("%-8o", 123456, "%-8o", 123456);
417 TestSPrintFormat("%08o", 123456, "%08o", 123456);
418 TestSPrintFormat("%#o", 123, "%#o", 123);
419 TestSPrintFormat("%#o", -123, "%#o", -123);
420
421 TestSPrintFormat("%8u", 123456, "%8u", 123456);
422 TestSPrintFormat("%-8u", 123456, "%-8u", 123456);
423 TestSPrintFormat("%08u", 123456, "%08u", 123456);
424 TestSPrintFormat("%8u", -123456, "%8u", -123456);
425 TestSPrintFormat("%-8u", -123456, "%-8u", -123456);
426 TestSPrintFormat("%.5u", 123456, "%.5u", 123456);
427 TestSPrintFormat("%.6u", 123456, "%.6u", 123456);
428 TestSPrintFormat("%.7u", 123456, "%.7u", 123456);
429
430 TestSPrintFormat("%8d", 123456, "%8d", 123456);
431 TestSPrintFormat("%-8d", 123456, "%-8d", 123456);
432 TestSPrintFormat("%08d", 123456, "%08d", 123456);
433 TestSPrintFormat("% d", 123456, "% d", 123456);
434 TestSPrintFormat("% d", -123456, "% d", -123456);
435
436 TestSPrintFormat("%8i", 123456, "%8i", 123456);
437 TestSPrintFormat("%-8i", 123456, "%-8i", 123456);
438 TestSPrintFormat("%08i", 123456, "%08i", 123456);
439
440 log_verbose("Get really crazy with the formatting.\n");
441
442 TestSPrintFormat("%-#12x", 123, "%-#12x", 123);
443 TestSPrintFormat("%-#12x", -123, "%-#12x", -123);
444 TestSPrintFormat("%#12x", 123, "%#12x", 123);
445 TestSPrintFormat("%#12x", -123, "%#12x", -123);
446
447 TestSPrintFormat("%-+12d", 123, "%-+12d", 123);
448 TestSPrintFormat("%-+12d", -123, "%-+12d", -123);
449 TestSPrintFormat("%- 12d", 123, "%- 12d", 123);
450 TestSPrintFormat("%- 12d", -123, "%- 12d", -123);
451 TestSPrintFormat("%+12d", 123, "%+12d", 123);
452 TestSPrintFormat("%+12d", -123, "%+12d", -123);
453 TestSPrintFormat("% 12d", 123, "% 12d", 123);
454 TestSPrintFormat("% 12d", -123, "% 12d", -123);
455 TestSPrintFormat("%12d", 123, "%12d", 123);
456 TestSPrintFormat("%12d", -123, "%12d", -123);
457 TestSPrintFormat("%.12d", 123, "%.12d", 123);
458 TestSPrintFormat("%.12d", -123, "%.12d", -123);
459
460 TestSPrintFormat("%-+12.1f", 1.234, "%-+12.1f", 1.234);
461 TestSPrintFormat("%-+12.1f", -1.234, "%-+12.1f", -1.234);
462 TestSPrintFormat("%- 12.10f", 1.234, "%- 12.10f", 1.234);
463 TestSPrintFormat("%- 12.1f", -1.234, "%- 12.1f", -1.234);
464 TestSPrintFormat("%+12.1f", 1.234, "%+12.1f", 1.234);
465 TestSPrintFormat("%+12.1f", -1.234, "%+12.1f", -1.234);
466 TestSPrintFormat("% 12.1f", 1.234, "% 12.1f", 1.234);
467 TestSPrintFormat("% 12.1f", -1.234, "% 12.1f", -1.234);
468 TestSPrintFormat("%12.1f", 1.234, "%12.1f", 1.234);
469 TestSPrintFormat("%12.1f", -1.234, "%12.1f", -1.234);
470 TestSPrintFormat("%.2f", 1.234, "%.2f", 1.234);
471 TestSPrintFormat("%.2f", -1.234, "%.2f", -1.234);
472 TestSPrintFormat("%3f", 1.234, "%3f", 1.234);
473 TestSPrintFormat("%3f", -1.234, "%3f", -1.234);
474#endif
475}
476
477#undef TestSPrintFormat
478
479static void TestStringCompatibility(void) {
480#if !UCONFIG_NO_FORMATTING
481 UChar myUString[256];
482 UChar uStringBuf[256];
483 char myString[256] = "";
484 char testBuf[256] = "";
485 int32_t num;
486
487 u_memset(myUString, 0x0a, sizeof(myUString)/ sizeof(*myUString));
488 u_memset(uStringBuf, 0x0a, sizeof(uStringBuf) / sizeof(*uStringBuf));
489
490 /* Compare against C API compatibility */
491 for (num = -STANDARD_TEST_NUM_RANGE; num < STANDARD_TEST_NUM_RANGE; num++) {
492 sprintf(testBuf, "%x", (int)num);
493 u_sprintf(uStringBuf, "%x", num);
494 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
495 if (strcmp(myString, testBuf) != 0) {
496 log_err("%%x Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
497 }
498
499 sprintf(testBuf, "%X", (int)num);
500 u_sprintf(uStringBuf, "%X", num);
501 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
502 if (strcmp(myString, testBuf) != 0) {
503 log_err("%%X Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
504 }
505
506 sprintf(testBuf, "%o", (int)num);
507 u_sprintf(uStringBuf, "%o", num);
508 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
509 if (strcmp(myString, testBuf) != 0) {
510 log_err("%%o Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
511 }
512
513 /* sprintf is not compatible on all platforms e.g. the iSeries*/
514 sprintf(testBuf, "%d", (int)num);
515 u_sprintf(uStringBuf, "%d", num);
516 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
517 if (strcmp(myString, testBuf) != 0) {
518 log_err("%%d Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
519 }
520
521 sprintf(testBuf, "%i", (int)num);
522 u_sprintf(uStringBuf, "%i", num);
523 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
524 if (strcmp(myString, testBuf) != 0) {
525 log_err("%%i Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
526 }
527
528 sprintf(testBuf, "%f", (double)num);
529 u_sprintf(uStringBuf, "%f", (double)num);
530 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
531 if (strcmp(myString, testBuf) != 0) {
532 log_err("%%f Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
533 }
534
535/* sprintf(testBuf, "%e", (double)num);
536 u_sprintf(uStringBuf, "%e", (double)num);
537 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
538 if (strcmp(myString, testBuf) != 0) {
539 log_err("%%e Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
540 }
541
542 sprintf(testBuf, "%E", (double)num);
543 u_sprintf(uStringBuf, "%E", (double)num);
544 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
545 if (strcmp(myString, testBuf) != 0) {
546 log_err("%%E Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
547 }*/
548
549 sprintf(testBuf, "%g", (double)num);
550 u_sprintf(uStringBuf, "%g", (double)num);
551 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
552 if (strcmp(myString, testBuf) != 0) {
553 log_err("%%g Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
554 }
555
556 sprintf(testBuf, "%G", (double)num);
557 u_sprintf(uStringBuf, "%G", (double)num);
558 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
559 if (strcmp(myString, testBuf) != 0) {
560 log_err("%%G Got: \"%s\", Expected: \"%s\"\n", myString, testBuf);
561 }
562 }
563
564 for (num = 0; num < 0x80; num++) {
565 testBuf[0] = (char)0xFF;
566 uStringBuf[0] = (UChar)0xfffe;
567 sprintf(testBuf, "%c", (char)num);
568 u_sprintf(uStringBuf, "%c", num);
569 u_austrncpy(myString, uStringBuf, sizeof(myString)/sizeof(myString[0]));
570 if (testBuf[0] != myString[0] || myString[0] != num) {
571 log_err("%%c Got: 0x%x, Expected: 0x%x\n", myString[0], testBuf[0]);
572 }
573 }
574#endif
575}
576
577static void TestSScanSetFormat(const char *format, const UChar *uValue, const char *cValue, UBool expectedToPass) {
578#if !UCONFIG_NO_FORMATTING
579 UChar uBuffer[256];
580 char buffer[256];
581 char compBuffer[256];
582 int32_t uNumScanned;
583 int32_t cNumScanned;
584
585 /* Reinitialize the buffer to verify null termination works. */
586 u_memset(uBuffer, 0x2a, sizeof(uBuffer)/sizeof(*uBuffer));
587 uBuffer[sizeof(uBuffer)/sizeof(*uBuffer)-1] = 0;
588 memset(buffer, '*', sizeof(buffer)/sizeof(*buffer));
589 buffer[sizeof(buffer)/sizeof(*buffer)-1] = 0;
590
591 uNumScanned = u_sscanf(uValue, format, uBuffer);
592 if (expectedToPass) {
593 u_austrncpy(compBuffer, uBuffer, sizeof(uBuffer)/sizeof(uBuffer[0]));
594 cNumScanned = sscanf(cValue, format, buffer);
595 if (strncmp(buffer, compBuffer, sizeof(uBuffer)/sizeof(uBuffer[0])) != 0) {
596 log_err("%s Got: \"%s\", Expected: \"%s\"\n", format, compBuffer, buffer);
597 }
598 if (cNumScanned != uNumScanned) {
599 log_err("%s number scanned Got: %d, Expected: %d\n", format, uNumScanned, cNumScanned);
600 }
601 if (uNumScanned > 0 && uBuffer[u_strlen(uBuffer)+1] != 0x2a) {
602 log_err("%s too much stored\n", format);
603 }
604 }
605 else {
606 if (uNumScanned != 0 || uBuffer[0] != 0x2a || uBuffer[1] != 0x2a) {
607 log_err("%s too much stored on a failure\n", format);
608 }
609 }
610#endif
611}
612
613static void TestSScanset(void) {
614#if !UCONFIG_NO_FORMATTING
615 static const UChar abcUChars[] = {0x61,0x62,0x63,0x63,0x64,0x65,0x66,0x67,0};
616 static const char abcChars[] = "abccdefg";
617
618 TestSScanSetFormat("%[bc]S", abcUChars, abcChars, TRUE);
619 TestSScanSetFormat("%[cb]S", abcUChars, abcChars, TRUE);
620
621 TestSScanSetFormat("%[ab]S", abcUChars, abcChars, TRUE);
622 TestSScanSetFormat("%[ba]S", abcUChars, abcChars, TRUE);
623
624 TestSScanSetFormat("%[ab]", abcUChars, abcChars, TRUE);
625 TestSScanSetFormat("%[ba]", abcUChars, abcChars, TRUE);
626
627 TestSScanSetFormat("%[abcdefgh]", abcUChars, abcChars, TRUE);
628 TestSScanSetFormat("%[;hgfedcba]", abcUChars, abcChars, TRUE);
629
630 TestSScanSetFormat("%[^a]", abcUChars, abcChars, TRUE);
631 TestSScanSetFormat("%[^e]", abcUChars, abcChars, TRUE);
632 TestSScanSetFormat("%[^ed]", abcUChars, abcChars, TRUE);
633 TestSScanSetFormat("%[^dc]", abcUChars, abcChars, TRUE);
634 TestSScanSetFormat("%[^e] ", abcUChars, abcChars, TRUE);
635
636 TestSScanSetFormat("%1[ab] ", abcUChars, abcChars, TRUE);
637 TestSScanSetFormat("%2[^f]", abcUChars, abcChars, TRUE);
638
639 TestSScanSetFormat("%[qrst]", abcUChars, abcChars, TRUE);
640
641 /* Extra long string for testing */
642 TestSScanSetFormat(" %[qrst]",
643 abcUChars, abcChars, TRUE);
644
645 TestSScanSetFormat("%[a-]", abcUChars, abcChars, TRUE);
646
647 /* Bad format */
648 TestSScanSetFormat("%[a", abcUChars, abcChars, FALSE);
649 TestSScanSetFormat("%[f-a]", abcUChars, abcChars, FALSE);
650 TestSScanSetFormat("%[c-a]", abcUChars, abcChars, FALSE);
651 /* The following is not deterministic on Windows */
652/* TestSScanSetFormat("%[a-", abcUChars, abcChars);*/
653
654 /* TODO: Need to specify precision with a "*" */
655#endif
656}
657
658static void TestBadSScanfFormat(const char *format, const UChar *uValue, const char *cValue) {
659#if !UCONFIG_NO_FORMATTING
660 UChar uBuffer[256];
661 int32_t uNumScanned;
662
663 /* Reinitialize the buffer to verify null termination works. */
664 u_memset(uBuffer, 0x2a, sizeof(uBuffer)/sizeof(*uBuffer));
665 uBuffer[sizeof(uBuffer)/sizeof(*uBuffer)-1] = 0;
666
667 uNumScanned = u_sscanf(uValue, format, uBuffer);
668 if (uNumScanned != 0 || uBuffer[0] != 0x2a || uBuffer[1] != 0x2a) {
669 log_err("%s too much stored on a failure\n", format);
670 }
671#endif
672}
673
674static void TestBadScanfFormat(void) {
675#if !UCONFIG_NO_FORMATTING
676 static const UChar abcUChars[] = {0x61,0x62,0x63,0x63,0x64,0x65,0x66,0x67,0};
677 static const char abcChars[] = "abccdefg";
678
679 TestBadSScanfFormat("%[] ", abcUChars, abcChars);
680#endif
681}
682
683static void Test_u_vfprintf(const char *expectedResult, const char *format, ...) {
684#if !UCONFIG_NO_FORMATTING
685 UChar uBuffer[256];
686 UChar uBuffer2[256];
687 va_list ap;
688 int32_t count;
689
690 va_start(ap, format);
691 count = u_vsprintf(uBuffer, format, ap);
692 va_end(ap);
693 u_uastrcpy(uBuffer2, expectedResult);
694 if (u_strcmp(uBuffer, uBuffer2) != 0) {
695 log_err("Got two different results for \"%s\" expected \"%s\"\n", format, expectedResult);
696 }
697
698 u_uastrcpy(uBuffer2, format);
699 va_start(ap, format);
700 count = u_vsprintf_u(uBuffer, uBuffer2, ap);
701 va_end(ap);
702 u_uastrcpy(uBuffer2, expectedResult);
703 if (u_strcmp(uBuffer, uBuffer2) != 0) {
704 log_err("Got two different results for \"%s\" expected \"%s\"\n", format, expectedResult);
705 }
706#endif
707}
708
709static void TestVargs(void) {
710#if !UCONFIG_NO_FORMATTING
711 Test_u_vfprintf("8 9 a B 8.9", "%d %u %x %X %.1f", 8, 9, 10, 11, 8.9);
712#endif
713}
714
715static void TestCount(void) {
716#if !UCONFIG_NO_FORMATTING
717 UChar testStr[16];
718 int16_t i16 = -1;
719 int32_t i32 = -1;
720 int64_t i64 = -1;
721 u_uastrcpy(testStr, "1233456789");
722 if (u_sscanf(testStr, "%*3[123]%n%*[1-9]", &i32) != 0) {
723 log_err("test 1: scanf did not return 0\n");
724 }
725 if (i32 != 3) {
726 log_err("test 1: scanf returned %hd instead of 3\n", i32);
727 }
728 if (u_sscanf(testStr, "%*4[123]%hn%*[1-9]", &i16) != 0) {
729 log_err("test 2: scanf did not return 0\n");
730 }
731 if (i16 != 4) {
732 log_err("test 2: scanf returned %d instead of 4\n", i16);
733 }
734 if (u_sscanf(testStr, "%*[123]%*[1-9]%lln", &i64) != 0) {
735 log_err("test 3: scanf did not return 0\n");
736 }
737 if (i64 != 10) {
738 log_err("test 3: scanf did not return 10\n", i64);
739 }
740#endif
741}
742
743U_CFUNC void
744addStringTest(TestNode** root) {
745#if !UCONFIG_NO_FORMATTING
746 addTest(root, &TestString, "string/TestString");
747 addTest(root, &TestLocalizedString, "string/TestLocalizedString");
748 addTest(root, &TestSprintfFormat, "string/TestSprintfFormat");
749 addTest(root, &TestSnprintf, "string/TestSnprintf");
750 addTest(root, &TestSScanset, "string/TestSScanset");
751 addTest(root, &TestStringCompatibility, "string/TestStringCompatibility");
752 addTest(root, &TestBadScanfFormat, "string/TestBadScanfFormat");
753 addTest(root, &TestVargs, "string/TestVargs");
754 addTest(root, &TestCount, "string/TestCount");
755#endif
756}
757
758