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]) {
96                     strcat(fmt, signs[s]);
97                 }
98                 if (precs[p]) {
99                     strcat(fmt, precs[p]);
100                 }
101                 if (formats[f]) {
102                     strcat(fmt, formats[f]);
103                 }
104                 for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
105                     test_i(fmt, nums[n]);
106                 }
107             }
108         }
109     }
110 }
111 
112 /************************************************************************/
113 
114 /*
115 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
116 ** Make sure the results are identical
117 */
test_l(char * pattern,char * spattern,PRInt32 l)118 static void test_l(char *pattern, char *spattern, PRInt32 l)
119 {
120     char *s;
121     char buf[200];
122     int n;
123 
124     /* try all three routines */
125     s = PR_smprintf(pattern, l);
126     PR_ASSERT(s != 0);
127     n = PR_snprintf(buf, sizeof(buf), pattern, l);
128     PR_ASSERT(n <= sizeof(buf));
129     sprintf(sbuf, spattern, l);
130 
131     /* compare results */
132     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
133         (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
134         fprintf(stderr,
135                 "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
136                 pattern, l, s, buf, sbuf);
137         PR_smprintf_free(s);
138         exit(-1);
139     }
140     PR_smprintf_free(s);
141 }
142 
TestL(void)143 static void TestL(void)
144 {
145     static PRInt32 nums[] = {
146         0,
147         1,
148         -1,
149         10,
150         -10,
151         32767,
152         -32768,
153         PR_INT32(0x7fffffff), /* 2147483647L */
154         -1 - PR_INT32(0x7fffffff)  /* -2147483648L */
155     };
156     static char *signs[] = {
157         "",
158         "0",    "-",    "+", " ",
159         "0-",   "0+",   "0 ",   "-0",   "-+",   "- ",
160         "+0",   "+-",   "+ ",   " 0",   " -",   " +",
161         "0-+",  "0- ",  "0+-",  "0+ ",  "0 -",  "0 +",
162         "-0+",  "-0 ",  "-+0",  "-+ ",  "- 0",  "- +",
163         "+0-",  "+0 ",  "+-0",  "+- ",  "+ 0",  "+ -",
164         " 0-",  " 0+",  " -0",  " -+",  " +0",  " +-",
165         "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-",
166         "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0",
167         "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0",
168         " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0",
169     };
170     static char *precs[] = {
171         "", "3", "5", "43",
172         ".3", ".43",
173         "7.3", "7.5", "7.11", "7.43",
174     };
175     static char *formats[] = { "ld", "lo", "lx", "lu" };
176 
177 #if PR_BYTES_PER_INT == 4
178     static char *sformats[] = { "d", "o", "x", "u" };
179 #elif PR_BYTES_PER_LONG == 4
180     static char *sformats[] = { "ld", "lo", "lx", "lu" };
181 #else
182 #error Neither int nor long is 4 bytes on this platform
183 #endif
184 
185     int f, s, n, p;
186     char fmt[40], sfmt[40];
187 
188     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
189         for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
190             for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
191                 fmt[0] = '%';
192                 fmt[1] = 0;
193                 if (signs[s]) {
194                     strcat(fmt, signs[s]);
195                 }
196                 if (precs[p]) {
197                     strcat(fmt, precs[p]);
198                 }
199                 strcpy(sfmt, fmt);
200                 if (formats[f]) {
201                     strcat(fmt, formats[f]);
202                 }
203                 if (sformats[f]) {
204                     strcat(sfmt, sformats[f]);
205                 }
206                 for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
207                     test_l(fmt, sfmt, nums[n]);
208                 }
209             }
210         }
211     }
212 }
213 
214 /************************************************************************/
215 
216 /*
217 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
218 ** Make sure the results are identical
219 */
test_ll(char * pattern,char * spattern,PRInt64 l)220 static void test_ll(char *pattern, char *spattern, PRInt64 l)
221 {
222     char *s;
223     char buf[200];
224     int n;
225 
226     /* try all three routines */
227     s = PR_smprintf(pattern, l);
228     PR_ASSERT(s != 0);
229     n = PR_snprintf(buf, sizeof(buf), pattern, l);
230     PR_ASSERT(n <= sizeof(buf));
231 #if defined(HAVE_LONG_LONG)
232     sprintf(sbuf, spattern, l);
233 
234     /* compare results */
235     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
236         (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
237 #if PR_BYTES_PER_LONG == 8
238 #define FORMAT_SPEC "%ld"
239 #elif defined(WIN16)
240 #define FORMAT_SPEC "%Ld"
241 #elif defined(WIN32)
242 #define FORMAT_SPEC "%I64d"
243 #else
244 #define FORMAT_SPEC "%lld"
245 #endif
246         fprintf(stderr,
247                 "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
248                 pattern, l, s, buf, sbuf);
249         printf("FAIL\n");
250         PR_smprintf_free(s);
251         exit(-1);
252     }
253     PR_smprintf_free(s);
254 #else
255     /* compare results */
256     if ((strncmp(s, buf, sizeof(buf)) != 0)) {
257         fprintf(stderr,
258                 "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
259                 pattern, s, buf, sbuf);
260         printf("FAIL\n");
261         PR_smprintf_free(s);
262         exit(-1);
263     }
264     PR_smprintf_free(s);
265 #endif
266 }
267 
TestLL(void)268 static void TestLL(void)
269 {
270     static PRInt64 nums[] = {
271         LL_INIT(0, 0),
272         LL_INIT(0, 1),
273         LL_INIT(0xffffffff, 0xffffffff),  /* -1 */
274         LL_INIT(0, 10),
275         LL_INIT(0xffffffff, 0xfffffff6),  /* -10 */
276         LL_INIT(0, 32767),
277         LL_INIT(0xffffffff, 0xffff8000),  /* -32768 */
278         LL_INIT(0, 0x7fffffff),  /* 2147483647 */
279         LL_INIT(0xffffffff, 0x80000000),  /* -2147483648 */
280         LL_INIT(0x7fffffff, 0xffffffff),  /* 9223372036854775807 */
281         LL_INIT(0x80000000, 0),           /* -9223372036854775808 */
282         PR_INT64(0),
283         PR_INT64(1),
284         PR_INT64(-1),
285         PR_INT64(10),
286         PR_INT64(-10),
287         PR_INT64(32767),
288         PR_INT64(-32768),
289         PR_INT64(2147483647),
290         PR_INT64(-2147483648),
291         PR_INT64(9223372036854775807),
292         PR_INT64(-9223372036854775808)
293     };
294 
295     static char *signs[] = {
296         "",
297         "0",    "-",    "+", " ",
298         "0-",   "0+",   "0 ",   "-0",   "-+",   "- ",
299         "+0",   "+-",   "+ ",   " 0",   " -",   " +",
300         "0-+",  "0- ",  "0+-",  "0+ ",  "0 -",  "0 +",
301         "-0+",  "-0 ",  "-+0",  "-+ ",  "- 0",  "- +",
302         "+0-",  "+0 ",  "+-0",  "+- ",  "+ 0",  "+ -",
303         " 0-",  " 0+",  " -0",  " -+",  " +0",  " +-",
304         "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-",
305         "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0",
306         "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0",
307         " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0",
308     };
309     static char *precs[] = {
310         "", "3", "5", "43",
311         ".3", ".43",
312         "7.3", "7.5", "7.11", "7.43",
313     };
314     static char *formats[] = { "lld", "llo", "llx", "llu" };
315 
316 #if PR_BYTES_PER_LONG == 8
317     static char *sformats[] = { "ld", "lo", "lx", "lu" };
318 #elif defined(WIN16)
319     /* Watcom uses the format string "%Ld" instead of "%lld". */
320     static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" };
321 #elif defined(WIN32)
322     static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" };
323 #else
324     static char *sformats[] = { "lld", "llo", "llx", "llu" };
325 #endif
326 
327     int f, s, n, p;
328     char fmt[40], sfmt[40];
329 
330     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
331         for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
332             for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
333                 fmt[0] = '%';
334                 fmt[1] = 0;
335                 if (signs[s]) {
336                     strcat(fmt, signs[s]);
337                 }
338                 if (precs[p]) {
339                     strcat(fmt, precs[p]);
340                 }
341                 strcpy(sfmt, fmt);
342                 if (formats[f]) {
343                     strcat(fmt, formats[f]);
344                 }
345                 if (sformats[f]) {
346                     strcat(sfmt, sformats[f]);
347                 }
348                 for (n = 0; n < PR_ARRAY_SIZE(nums); n++) {
349                     test_ll(fmt, sfmt, nums[n]);
350                 }
351             }
352         }
353     }
354 }
355 
356 /************************************************************************/
357 
358 /*
359 ** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
360 ** Make sure the results are identical
361 */
test_s(char * pattern,char * ss)362 static void test_s(char *pattern, char *ss)
363 {
364     char *s;
365     unsigned char before[8];
366     char buf[200];
367     unsigned char after[8];
368     int n;
369 
370     memset(before, 0xBB, 8);
371     memset(after, 0xAA, 8);
372 
373     /* try all three routines */
374     s = PR_smprintf(pattern, ss);
375     PR_ASSERT(s != 0);
376     n = PR_snprintf(buf, sizeof(buf), pattern, ss);
377     PR_ASSERT(n <= sizeof(buf));
378     sprintf(sbuf, pattern, ss);
379 
380     for (n = 0; n < 8; n++) {
381         PR_ASSERT(before[n] == 0xBB);
382         PR_ASSERT(after[n] == 0xAA);
383     }
384 
385     /* compare results */
386     if ((strncmp(s, buf, sizeof(buf)) != 0) ||
387         (strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
388         fprintf(stderr,
389                 "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
390                 pattern, ss, s, buf, sbuf);
391         printf("FAIL\n");
392         PR_smprintf_free(s);
393         exit(-1);
394     }
395     PR_smprintf_free(s);
396 }
397 
TestS(void)398 static void TestS(void)
399 {
400     static char *strs[] = {
401         "",
402         "a",
403         "abc",
404         "abcde",
405         "abcdefABCDEF",
406         "abcdefghijklmnopqrstuvwxyz0123456789!@#$"
407         "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$"
408         "abcdefghijklmnopqrstuvwxyz0123456789!@#$",
409     };
410     /* '0' is not relevant to printing strings */
411     static char *signs[] = {
412         "",
413         "-",    "+",    " ",
414         "-+",   "- ",   "+-",   "+ ",   " -",   " +",
415         "-+ ",  "- +",  "+- ",  "+ -",  " -+",  " +-",
416     };
417     static char *precs[] = {
418         "", "3", "5", "43",
419         ".3", ".43",
420         "7.3", "7.5", "7.11", "7.43",
421     };
422     static char *formats[] = { "s" };
423     int f, s, n, p;
424     char fmt[40];
425 
426     for (f = 0; f < PR_ARRAY_SIZE(formats); f++) {
427         for (s = 0; s < PR_ARRAY_SIZE(signs); s++) {
428             for (p = 0; p < PR_ARRAY_SIZE(precs); p++) {
429                 fmt[0] = '%';
430                 fmt[1] = 0;
431                 if (signs[s]) {
432                     strcat(fmt+strlen(fmt), signs[s]);
433                 }
434                 if (precs[p]) {
435                     strcat(fmt+strlen(fmt), precs[p]);
436                 }
437                 if (formats[f]) {
438                     strcat(fmt+strlen(fmt), formats[f]);
439                 }
440                 for (n = 0; n < PR_ARRAY_SIZE(strs); n++) {
441                     test_s(fmt, strs[n]);
442                 }
443             }
444         }
445     }
446 }
447 
448 /************************************************************************/
449 
main(int argc,char ** argv)450 int main(int argc, char **argv)
451 {
452     PR_STDIO_INIT();
453     TestI();
454     TestL();
455     TestLL();
456     TestS();
457     printf("PASS\n");
458     return 0;
459 }
460