DEVEL15-util-snprintf-replacement-20090624
[openafs.git] / src / util / test / snprintf_test.c
1 /*
2  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of KTH nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software without
19  *    specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32
33 #include <afs/stds.h>
34 #include <afs/afsutil.h>
35 #include <limits.h>
36
37 static int
38 try (const char *format, ...)
39 {
40     int ret;
41     va_list ap;
42     char buf1[256], buf2[256];
43
44     va_start (ap, format);
45     ret = afs_vsnprintf (buf1, sizeof(buf1), format, ap);
46     if (ret >= sizeof(buf1)) {
47         fprintf(stderr, "increase buf and try again\n");
48         exit(1);
49     }
50     va_end (ap);
51     va_start (ap, format);
52     vsprintf (buf2, format, ap);
53     ret = strcmp (buf1, buf2);
54     if (ret)
55         printf ("failed: format = \"%s\", \"%s\" != \"%s\"\n",
56                 format, buf1, buf2);
57     va_end (ap);
58     return ret;
59 }
60
61 static int
62 cmp_with_sprintf_int (void)
63 {
64     int tot = 0;
65     int int_values[] = {INT_MIN, -17, -1, 0, 1, 17, 4711, 65535, INT_MAX};
66     int i;
67
68     for (i = 0; i < sizeof(int_values) / sizeof(int_values[0]); ++i) {
69         tot += try ("%d", int_values[i]);
70         tot += try ("%x", int_values[i]);
71         tot += try ("%X", int_values[i]);
72         tot += try ("%o", int_values[i]);
73         tot += try ("%#x", int_values[i]);
74         tot += try ("%#X", int_values[i]);
75         tot += try ("%#o", int_values[i]);
76         tot += try ("%10d", int_values[i]);
77         tot += try ("%10x", int_values[i]);
78         tot += try ("%10X", int_values[i]);
79         tot += try ("%10o", int_values[i]);
80         tot += try ("%#10x", int_values[i]);
81         tot += try ("%#10X", int_values[i]);
82         tot += try ("%#10o", int_values[i]);
83         tot += try ("%-10d", int_values[i]);
84         tot += try ("%-10x", int_values[i]);
85         tot += try ("%-10X", int_values[i]);
86         tot += try ("%-10o", int_values[i]);
87         tot += try ("%-#10x", int_values[i]);
88         tot += try ("%-#10X", int_values[i]);
89         tot += try ("%-#10o", int_values[i]);
90     }
91     return tot;
92 }
93
94 static int
95 cmp_with_sprintf_long (void)
96 {
97     int tot = 0;
98     long long_values[] = {LONG_MIN, -17, -1, 0, 1, 17, 4711, 65535, LONG_MAX};
99     int i;
100
101     for (i = 0; i < sizeof(long_values) / sizeof(long_values[0]); ++i) {
102         tot += try ("%ld", long_values[i]);
103         tot += try ("%lx", long_values[i]);
104         tot += try ("%lX", long_values[i]);
105         tot += try ("%lo", long_values[i]);
106         tot += try ("%#lx", long_values[i]);
107         tot += try ("%#lX", long_values[i]);
108         tot += try ("%#lo", long_values[i]);
109         tot += try ("%10ld", long_values[i]);
110         tot += try ("%10lx", long_values[i]);
111         tot += try ("%10lX", long_values[i]);
112         tot += try ("%10lo", long_values[i]);
113         tot += try ("%#10lx", long_values[i]);
114         tot += try ("%#10lX", long_values[i]);
115         tot += try ("%#10lo", long_values[i]);
116         tot += try ("%-10ld", long_values[i]);
117         tot += try ("%-10lx", long_values[i]);
118         tot += try ("%-10lX", long_values[i]);
119         tot += try ("%-10lo", long_values[i]);
120         tot += try ("%-#10lx", long_values[i]);
121         tot += try ("%-#10lX", long_values[i]);
122         tot += try ("%-#10lo", long_values[i]);
123     }
124     return tot;
125 }
126
127 #ifdef HAVE_LONG_LONG
128
129 /* XXX doesn't work as expected on lp64 platforms with sizeof(long
130  * long) == sizeof(long) */
131
132 static int
133 cmp_with_sprintf_long_long (void)
134 {
135     int tot = 0;
136     long long long_long_values[] = {
137         ((long long)LONG_MIN) -1, LONG_MIN, -17, -1,
138         0,
139         1, 17, 4711, 65535, LONG_MAX, ((long long)LONG_MAX) + 1};
140     int i;
141
142     for (i = 0; i < sizeof(long_long_values) / sizeof(long_long_values[0]); ++i) {
143         tot += try ("%lld", long_long_values[i]);
144         tot += try ("%llx", long_long_values[i]);
145         tot += try ("%llX", long_long_values[i]);
146         tot += try ("%llo", long_long_values[i]);
147         tot += try ("%#llx", long_long_values[i]);
148         tot += try ("%#llX", long_long_values[i]);
149         tot += try ("%#llo", long_long_values[i]);
150         tot += try ("%10lld", long_long_values[i]);
151         tot += try ("%10llx", long_long_values[i]);
152         tot += try ("%10llX", long_long_values[i]);
153         tot += try ("%10llo", long_long_values[i]);
154         tot += try ("%#10llx", long_long_values[i]);
155         tot += try ("%#10llX", long_long_values[i]);
156         tot += try ("%#10llo", long_long_values[i]);
157         tot += try ("%-10lld", long_long_values[i]);
158         tot += try ("%-10llx", long_long_values[i]);
159         tot += try ("%-10llX", long_long_values[i]);
160         tot += try ("%-10llo", long_long_values[i]);
161         tot += try ("%-#10llx", long_long_values[i]);
162         tot += try ("%-#10llX", long_long_values[i]);
163         tot += try ("%-#10llo", long_long_values[i]);
164     }
165     return tot;
166 }
167
168 #endif
169
170 #if defined(AFS_64BIT_ENV) && defined(AFS_NT40_ENV)
171
172 static int
173 cmp_with_sprintf_I64 (void)
174 {
175     int tot = 0;
176     __int64 int64_values[] = {
177         ((__int64)LONG_MIN) -1, LONG_MIN, -17, -1,
178         0,
179         1, 17, 4711, 65535, LONG_MAX, ((__int64)LONG_MAX) + 1};
180     int i;
181
182     for (i = 0; i < sizeof(int64_values) / sizeof(int64_values[0]); ++i) {
183         tot += try ("%I64d", int64_values[i]);
184         tot += try ("%I64x", int64_values[i]);
185         tot += try ("%I64X", int64_values[i]);
186         tot += try ("%I64o", int64_values[i]);
187         tot += try ("%#I64x", int64_values[i]);
188         tot += try ("%#I64X", int64_values[i]);
189         tot += try ("%#I64o", int64_values[i]);
190         tot += try ("%10I64d", int64_values[i]);
191         tot += try ("%10I64x", int64_values[i]);
192         tot += try ("%10I64X", int64_values[i]);
193         tot += try ("%10I64o", int64_values[i]);
194         tot += try ("%#10I64x", int64_values[i]);
195         tot += try ("%#10I64X", int64_values[i]);
196         tot += try ("%#10I64o", int64_values[i]);
197         tot += try ("%-10I64d", int64_values[i]);
198         tot += try ("%-10I64x", int64_values[i]);
199         tot += try ("%-10I64X", int64_values[i]);
200         tot += try ("%-10I64o", int64_values[i]);
201         tot += try ("%-#10I64x", int64_values[i]);
202         tot += try ("%-#10I64X", int64_values[i]);
203         tot += try ("%-#10I64o", int64_values[i]);
204     }
205     return tot;
206 }
207
208 #endif
209
210 static int
211 cmp_with_sprintf_float (void)
212 {
213     int tot = 0;
214     double double_values[] = {-99999, -999, -17.4, -4.3, -3.0, -1.5, -1,
215                               0, 0.1, 0.2342374852, 0.2340007,
216                               3.1415926, 14.7845, 34.24758, 9999, 9999999};
217     int i;
218
219     for (i = 0; i < sizeof(double_values) / sizeof(double_values[0]); ++i) {
220         tot += try ("%f", double_values[i]);
221         tot += try ("%10f", double_values[i]);
222         tot += try ("%.2f", double_values[i]);
223         tot += try ("%7.0f", double_values[i]);
224         tot += try ("%5.2f", double_values[i]);
225         tot += try ("%0f", double_values[i]);
226         tot += try ("%#f", double_values[i]);
227         tot += try ("%e", double_values[i]);
228         tot += try ("%10e", double_values[i]);
229         tot += try ("%.2e", double_values[i]);
230         tot += try ("%7.0e", double_values[i]);
231         tot += try ("%5.2e", double_values[i]);
232         tot += try ("%0e", double_values[i]);
233         tot += try ("%#e", double_values[i]);
234         tot += try ("%E", double_values[i]);
235         tot += try ("%10E", double_values[i]);
236         tot += try ("%.2E", double_values[i]);
237         tot += try ("%7.0E", double_values[i]);
238         tot += try ("%5.2E", double_values[i]);
239         tot += try ("%0E", double_values[i]);
240         tot += try ("%#E", double_values[i]);
241         tot += try ("%g", double_values[i]);
242         tot += try ("%10g", double_values[i]);
243         tot += try ("%.2g", double_values[i]);
244         tot += try ("%7.0g", double_values[i]);
245         tot += try ("%5.2g", double_values[i]);
246         tot += try ("%0g", double_values[i]);
247         tot += try ("%#g", double_values[i]);
248         tot += try ("%G", double_values[i]);
249         tot += try ("%10G", double_values[i]);
250         tot += try ("%.2G", double_values[i]);
251         tot += try ("%7.0G", double_values[i]);
252         tot += try ("%5.2G", double_values[i]);
253         tot += try ("%0G", double_values[i]);
254         tot += try ("%#G", double_values[i]);
255     }
256     return tot;
257 }
258
259 static int
260 test_null (void)
261 {
262     return afs_snprintf (NULL, 0, "foo") != 3;
263 }
264
265 static int
266 test_sizet (void)
267 {
268     int tot = 0;
269     size_t sizet_values[] = { 0, 1, 2, 200, 4294967295u
270 #ifdef _WIN64
271                               ,0xffffffffffffffffui64
272 #endif
273     }; /* SIZE_MAX */
274     char *result[] = { "0", "1", "2", "200", "4294967295"
275 #ifdef _WIN64
276                        ,"18446744073709551615"
277 #endif
278     };
279     int i;
280
281     for (i = 0; i < sizeof(sizet_values) / sizeof(sizet_values[0]); ++i) {
282 #if 0
283         tot += try("%zu", sizet_values[i]);
284         tot += try("%zx", sizet_values[i]);
285         tot += try("%zX", sizet_values[i]);
286 #else
287         char buf[256];
288         afs_snprintf(buf, sizeof(buf), "%zu", sizet_values[i]);
289         if (strcmp(buf, result[i]) != 0) {
290             printf("%s != %s", buf, result[i]);
291             tot++;
292         }
293 #endif
294     }
295     return tot;
296 }
297
298 static int
299 test_ptr (void)
300 {
301     int tot = 0;
302     void * ptr;
303
304     if (sizeof(ptr) == 4) {
305         ptr = (void *)0x12345678;
306         tot += try ("%p", ptr);
307         tot += try ("%#p", ptr);
308         tot += try ("%4p", ptr);
309         tot += try ("%#4p", ptr);
310         tot += try ("%-4p", ptr);
311         tot += try ("%-#4p", ptr);
312     } else if (sizeof(ptr) == 8) {
313         ptr = (void *)0x0102030405060708;
314         tot += try ("%p", ptr);
315         tot += try ("%#p", ptr);
316         tot += try ("%8p", ptr);
317         tot += try ("%#8p", ptr);
318         tot += try ("%-8p", ptr);
319         tot += try ("%-#8p", ptr);
320     }
321
322
323     return tot;
324 }
325
326 static int 
327 test_ipaddr (void)
328 {
329     int tot = 0;
330     struct hostent * he = gethostbyname("www.openafs.org");
331     char buf[256];
332     unsigned long addr;
333
334     if (!he) {
335         fprintf(stderr, "gethostbyname failure\n");
336         tot = 1;
337     }
338     addr = *((unsigned long *)he->h_addr);
339     afs_snprintf(buf, sizeof(buf), "%I", addr);
340     if (strcmp(buf, "OPENAFS.ORG")) {
341         fprintf(stderr, "%s != %s\n", buf, "OPENAFS.ORG");
342         tot++;
343     }
344     afs_snprintf(buf, sizeof(buf), "%+I", addr);
345     if (strcmp(buf, "OPENAFS.ORG")) {
346         fprintf(stderr, "%s != %s\n", buf, "OPENAFS.ORG");
347         tot++;
348     }
349     afs_snprintf(buf, sizeof(buf), "%#I", addr);
350     if (strcmp(buf, "openafs.org")) {
351         fprintf(stderr, "%s != %s\n", buf, "openafs.org");
352         tot++;
353     }
354     afs_snprintf(buf, sizeof(buf), "%.7I", addr);
355     if (strcmp(buf, "OPENAFS")) {
356         fprintf(stderr, "%s != %s\n", buf, "OPENAFS");
357         tot++;
358     }
359     afs_snprintf(buf, sizeof(buf), "%.0I", addr);
360     if (strcmp(buf, "128.2.200.90")) {
361         fprintf(stderr, "%s != %s\n", buf, "128.2.200.90");
362         tot++;
363     }
364     afs_snprintf(buf, sizeof(buf), "%0.0I", addr);
365     if (strcmp(buf, "128.002.200.090")) {
366         fprintf(stderr, "%s != %s\n", buf, "128.002.200.090");
367         tot++;
368     }
369     afs_snprintf(buf, sizeof(buf), "% .0I", addr);
370     if (strcmp(buf, "128.  2.200. 90")) {
371         fprintf(stderr, "%s != %s\n", buf, "128.  2.200. 90");
372         tot++;
373     }
374
375     return tot;
376 }
377
378
379 int
380 main (int argc, char **argv)
381 {
382     int ret = 0;
383
384 #ifdef AFS_NT40_ENV
385     afs_winsockInit();
386 #endif
387
388     ret += cmp_with_sprintf_int ();
389     ret += cmp_with_sprintf_long ();
390 #ifdef HAVE_LONG_LONG
391     ret += cmp_with_sprintf_long_long ();
392 #endif
393 #if defined(AFS_64BIT_ENV) && defined(AFS_NT40_ENV)
394     ret += cmp_with_sprintf_I64 ();
395 #endif
396     ret += cmp_with_sprintf_float ();
397     ret += test_null ();
398     ret += test_sizet ();
399     ret += test_ptr ();
400     ret += test_ipaddr ();
401
402 #ifdef AFS_NT40_ENV
403     afs_winsockCleanup();
404 #endif
405     
406     return ret;
407 }