1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 /*
7  * File:	sprintf.c
8  * Description:
9  *     This is a test program for the PR_snprintf() functions defined
10  *     in prprf.c.  This test program is based on ns/nspr/tests/sprintf.c,
11  *     revision 1.10.
12  * Modification History:
13  *	20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the
14  *				regress tool parsing routine.
15  ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
16  *			recognize the return code from tha main program.
17  */
18 
19 #include "prinit.h"
20 #include "prprf.h"
21 #include "prlog.h"
22 #include "prlong.h"
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 
27 static char sbuf[20000];
28 
29 
30 /*
31 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
32 ** Make sure the results are identical
33 */
test_i(char * pattern,int i)34 static void test_i(char *pattern, int i)
35 {
36     char *s;
37     char buf[200];
38     int n;
39 
40     /* try all three routines */
41     s = PR_smprintf(pattern, i);
42     PR_ASSERT(s != 0);
43     n = PR_snprintf(buf, sizeof(buf), pattern, i);
44     PR_ASSERT(n <= sizeof(buf));
45     sprintf(sbuf, pattern, i);
46 
47     /* compare results */
48     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
49 	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
50 	fprintf(stderr,
51 	   "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
52 	   pattern, i, s, buf, sbuf);
53 	   PR_smprintf_free(s);
54 	exit(-1);
55     }
56 	PR_smprintf_free(s);
57 }
58 
TestI(void)59 static void TestI(void)
60 {
61     static int nums[] = {
62 	0, 1, -1, 10, -10,
63 	32767, -32768,
64     };
65     static char *signs[] = {
66 	"",
67 	"0",	"-",	"+", " ",
68 	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
69 	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
70 	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
71 	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
72 	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
73 	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
74 	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
75 	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
76 	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
77 	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
78     };
79     static char *precs[] = {
80 	"", "3", "5", "43",
81 	"7.3", "7.5", "7.11", "7.43",
82     };
83     static char *formats[] = {
84 	"d", "o", "x", "u",
85 	"hd", "ho", "hx", "hu"
86     };
87     int f, s, n, p;
88     char fmt[20];
89 
90     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
91 	for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
92 	    for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
93 		fmt[0] = '%';
94 		fmt[1] = 0;
95 		if (signs[s]) strcat(fmt, signs[s]);
96 		if (precs[p]) strcat(fmt, precs[p]);
97 		if (formats[f]) strcat(fmt, formats[f]);
98 		for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
99 		    test_i(fmt, nums[n]);
100 		}
101 	    }
102 	}
103     }
104 }
105 
106 /************************************************************************/
107 
108 /*
109 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
110 ** Make sure the results are identical
111 */
test_l(char * pattern,char * spattern,PRInt32 l)112 static void test_l(char *pattern, char *spattern, PRInt32 l)
113 {
114     char *s;
115     char buf[200];
116     int n;
117 
118     /* try all three routines */
119     s = PR_smprintf(pattern, l);
120     PR_ASSERT(s != 0);
121     n = PR_snprintf(buf, sizeof(buf), pattern, l);
122     PR_ASSERT(n <= sizeof(buf));
123     sprintf(sbuf, spattern, l);
124 
125     /* compare results */
126     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
127 	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
128 	fprintf(stderr,
129 	   "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
130 	   pattern, l, s, buf, sbuf);
131 	PR_smprintf_free(s);
132 	exit(-1);
133     }
134 	PR_smprintf_free(s);
135 }
136 
TestL(void)137 static void TestL(void)
138 {
139     static PRInt32 nums[] = {
140 	0,
141 	1,
142 	-1,
143 	10,
144 	-10,
145 	32767,
146 	-32768,
147 	PR_INT32(0x7fffffff), /* 2147483647L */
148 	-1 - PR_INT32(0x7fffffff)  /* -2147483648L */
149     };
150     static char *signs[] = {
151 	"",
152 	"0",	"-",	"+", " ",
153 	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
154 	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
155 	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
156 	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
157 	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
158 	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
159 	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
160 	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
161 	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
162 	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
163     };
164     static char *precs[] = {
165 	"", "3", "5", "43",
166 	".3", ".43",
167 	"7.3", "7.5", "7.11", "7.43",
168     };
169     static char *formats[] = { "ld", "lo", "lx", "lu" };
170 
171 #if PR_BYTES_PER_INT == 4
172     static char *sformats[] = { "d", "o", "x", "u" };
173 #elif PR_BYTES_PER_LONG == 4
174     static char *sformats[] = { "ld", "lo", "lx", "lu" };
175 #else
176 #error Neither int nor long is 4 bytes on this platform
177 #endif
178 
179     int f, s, n, p;
180     char fmt[40], sfmt[40];
181 
182     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
183 	for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
184 	    for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
185 		fmt[0] = '%';
186 		fmt[1] = 0;
187 		if (signs[s]) strcat(fmt, signs[s]);
188 		if (precs[p]) strcat(fmt, precs[p]);
189 		strcpy(sfmt, fmt);
190 		if (formats[f]) strcat(fmt, formats[f]);
191 		if (sformats[f]) strcat(sfmt, sformats[f]);
192 		for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
193 		    test_l(fmt, sfmt, nums[n]);
194 		}
195 	    }
196 	}
197     }
198 }
199 
200 /************************************************************************/
201 
202 /*
203 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
204 ** Make sure the results are identical
205 */
test_ll(char * pattern,char * spattern,PRInt64 l)206 static void test_ll(char *pattern, char *spattern, PRInt64 l)
207 {
208     char *s;
209     char buf[200];
210     int n;
211 
212     /* try all three routines */
213     s = PR_smprintf(pattern, l);
214     PR_ASSERT(s != 0);
215     n = PR_snprintf(buf, sizeof(buf), pattern, l);
216     PR_ASSERT(n <= sizeof(buf));
217 #if defined(HAVE_LONG_LONG)
218     sprintf(sbuf, spattern, l);
219 
220     /* compare results */
221     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
222 	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
223 #if PR_BYTES_PER_LONG == 8
224 #define FORMAT_SPEC "%ld"
225 #elif defined(WIN16)
226 #define FORMAT_SPEC "%Ld"
227 #elif defined(WIN32)
228 #define FORMAT_SPEC "%I64d"
229 #else
230 #define FORMAT_SPEC "%lld"
231 #endif
232 	fprintf(stderr,
233 	    "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
234 	    pattern, l, s, buf, sbuf);
235 	printf("FAIL\n");
236 	PR_smprintf_free(s);
237 	exit(-1);
238     }
239 	PR_smprintf_free(s);
240 #else
241     /* compare results */
242     if ((strncmp(s, buf, sizeof(buf)) != 0)) {
243 	fprintf(stderr,
244 	    "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
245 	    pattern, s, buf, sbuf);
246 	printf("FAIL\n");
247 	PR_smprintf_free(s);
248         exit(-1);
249     }
250 	PR_smprintf_free(s);
251 #endif
252 }
253 
TestLL(void)254 static void TestLL(void)
255 {
256     static PRInt64 nums[] = {
257 	LL_INIT(0, 0),
258 	LL_INIT(0, 1),
259 	LL_INIT(0xffffffff, 0xffffffff),  /* -1 */
260 	LL_INIT(0, 10),
261 	LL_INIT(0xffffffff, 0xfffffff6),  /* -10 */
262 	LL_INIT(0, 32767),
263 	LL_INIT(0xffffffff, 0xffff8000),  /* -32768 */
264 	LL_INIT(0, 0x7fffffff),  /* 2147483647 */
265 	LL_INIT(0xffffffff, 0x80000000),  /* -2147483648 */
266 	LL_INIT(0x7fffffff, 0xffffffff),  /* 9223372036854775807 */
267 	LL_INIT(0x80000000, 0),           /* -9223372036854775808 */
268 	PR_INT64(0),
269 	PR_INT64(1),
270 	PR_INT64(-1),
271 	PR_INT64(10),
272 	PR_INT64(-10),
273 	PR_INT64(32767),
274 	PR_INT64(-32768),
275 	PR_INT64(2147483647),
276 	PR_INT64(-2147483648),
277 	PR_INT64(9223372036854775807),
278 	PR_INT64(-9223372036854775808)
279     };
280 
281     static char *signs[] = {
282 	"",
283 	"0",	"-",	"+", " ",
284 	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
285 	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
286 	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
287 	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
288 	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
289 	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
290 	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
291 	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
292 	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
293 	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
294     };
295     static char *precs[] = {
296 	"", "3", "5", "43",
297 	".3", ".43",
298 	"7.3", "7.5", "7.11", "7.43",
299     };
300     static char *formats[] = { "lld", "llo", "llx", "llu" };
301 
302 #if PR_BYTES_PER_LONG == 8
303     static char *sformats[] = { "ld", "lo", "lx", "lu" };
304 #elif defined(WIN16)
305     /* Watcom uses the format string "%Ld" instead of "%lld". */
306     static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" };
307 #elif defined(WIN32)
308     static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" };
309 #else
310     static char *sformats[] = { "lld", "llo", "llx", "llu" };
311 #endif
312 
313     int f, s, n, p;
314     char fmt[40], sfmt[40];
315 
316     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
317 	for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
318 	    for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
319 		fmt[0] = '%';
320 		fmt[1] = 0;
321 		if (signs[s]) strcat(fmt, signs[s]);
322 		if (precs[p]) strcat(fmt, precs[p]);
323 		strcpy(sfmt, fmt);
324 		if (formats[f]) strcat(fmt, formats[f]);
325 		if (sformats[f]) strcat(sfmt, sformats[f]);
326 		for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
327 		    test_ll(fmt, sfmt, nums[n]);
328 		}
329 	    }
330 	}
331     }
332 }
333 
334 /************************************************************************/
335 
336 /*
337 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
338 ** Make sure the results are identical
339 */
test_s(char * pattern,char * ss)340 static void test_s(char *pattern, char *ss)
341 {
342     char *s;
343     unsigned char before[8];
344     char buf[200];
345     unsigned char after[8];
346     int n;
347 
348     memset(before, 0xBB, 8);
349     memset(after, 0xAA, 8);
350 
351     /* try all three routines */
352     s = PR_smprintf(pattern, ss);
353     PR_ASSERT(s != 0);
354     n = PR_snprintf(buf, sizeof(buf), pattern, ss);
355     PR_ASSERT(n <= sizeof(buf));
356     sprintf(sbuf, pattern, ss);
357 
358     for (n = 0; n < 8; n++) {
359 	PR_ASSERT(before[n] == 0xBB);
360 	PR_ASSERT(after[n] == 0xAA);
361     }
362 
363     /* compare results */
364     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
365 	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
366 	fprintf(stderr,
367 	   "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
368 	   pattern, ss, s, buf, sbuf);
369 	printf("FAIL\n");
370 	PR_smprintf_free(s);
371 	exit(-1);
372     }
373 	PR_smprintf_free(s);
374 }
375 
TestS(void)376 static void TestS(void)
377 {
378     static char *strs[] = {
379 	"",
380 	"a",
381 	"abc",
382 	"abcde",
383 	"abcdefABCDEF",
384 	"abcdefghijklmnopqrstuvwxyz0123456789!@#$"
385 	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$"
386 	    "abcdefghijklmnopqrstuvwxyz0123456789!@#$",
387     };
388     /* '0' is not relevant to printing strings */
389     static char *signs[] = {
390 	"",
391 	"-",	"+",	" ",
392 	"-+",	"- ",	"+-",	"+ ",	" -",	" +",
393 	"-+ ",	"- +",	"+- ",	"+ -",	" -+",	" +-",
394     };
395     static char *precs[] = {
396 	"", "3", "5", "43",
397 	".3", ".43",
398 	"7.3", "7.5", "7.11", "7.43",
399     };
400     static char *formats[] = { "s" };
401     int f, s, n, p;
402     char fmt[40];
403 
404     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
405 	for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
406 	    for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
407 		fmt[0] = '%';
408 		fmt[1] = 0;
409 		if (signs[s]) strcat(fmt+strlen(fmt), signs[s]);
410 		if (precs[p]) strcat(fmt+strlen(fmt), precs[p]);
411 		if (formats[f]) strcat(fmt+strlen(fmt), formats[f]);
412 		for (n = 0; n < PR_ARRAY_SIZE(strs); n++) {
413 		    test_s(fmt, strs[n]);
414 		}
415 	    }
416 	}
417     }
418 }
419 
420 /************************************************************************/
421 
main(int argc,char ** argv)422 int main(int argc, char **argv)
423 {
424     PR_STDIO_INIT();
425     TestI();
426     TestL();
427     TestLL();
428     TestS();
429     printf("PASS\n");
430     return 0;
431 }
432