1 /**************************************************************
2 * Original:
3 * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
4 * A bombproof version of doprnt (dopr) included.
5 * Sigh. This sort of thing is always nasty do deal with. Note that
6 * the version here does not include floating point...
7 *
8 * snprintf() is used instead of sprintf() as it does limit checks
9 * for string length. This covers a nasty loophole.
10 *
11 * The other functions are there to prevent NULL pointers from
12 * causing nast effects.
13 *
14 * More Recently:
15 * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
16 * This was ugly. It is still ugly. I opted out of floating point
17 * numbers, but the formatter understands just about everything
18 * from the normal C string format, at least as far as I can tell from
19 * the Solaris 2.5 printf(3S) man page.
20 *
21 * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
22 * Ok, added some minimal floating point support, which means this
23 * probably requires libm on most operating systems. Don't yet
24 * support the exponent (e,E) and sigfig (g,G). Also, fmtint()
25 * was pretty badly broken, it just wasn't being exercised in ways
26 * which showed it, so that's been fixed. Also, formated the code
27 * to mutt conventions, and removed dead code left over from the
28 * original. Also, there is now a builtin-test, just compile with:
29 * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
30 * and run snprintf for results.
31 *
32 * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
33 * The PGP code was using unsigned hexadecimal formats.
34 * Unfortunately, unsigned formats simply didn't work.
35 *
36 * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
37 * The original code assumed that both snprintf() and vsnprintf() were
38 * missing. Some systems only have snprintf() but not vsnprintf(), so
39 * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
40 *
41 **************************************************************/
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #else
46 #ifdef __STDC__
47 #define HAVE_STDARG_H 1
48 #endif
49 #endif
50
51 #if defined(BROKEN_SNPRINTF) || (!defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF))
52
53 #include <ctype.h>
54 #include <sys/types.h>
55 /* #include <stdio.h> */
56
57 /* Define this as a fall through, HAVE_STDARG_H is probably already set */
58
59 #define HAVE_VARARGS_H
60
61 /* varargs declarations: */
62
63 #if defined(HAVE_STDARG_H)
64 # include <stdarg.h>
65 # define HAVE_STDARGS /* let's hope that works everywhere (mj) */
66 # define VA_LOCAL_DECL va_list ap
67 # define VA_START(f) va_start(ap, f)
68 # define VA_SHIFT(v,t) ; /* no-op for ANSI */
69 # define VA_END va_end(ap)
70 #else
71 # if defined(HAVE_VARARGS_H)
72 # include <varargs.h>
73 # undef HAVE_STDARGS
74 # define VA_LOCAL_DECL va_list ap
75 # define VA_START(f) va_start(ap) /* f is ignored! */
76 # define VA_SHIFT(v,t) v = va_arg(ap,t)
77 # define VA_END va_end(ap)
78 # else
79 /*XX ** NO VARARGS ** XX*/
80 # endif
81 #endif
82
83 /*int snprintf (char *str, size_t count, const char *fmt, ...);*/
84 /*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
85
86 static int dopr (char *buffer, size_t maxlen, const char *format,
87 va_list args);
88 static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
89 char *value, int flags, int min, int max);
90 static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
91 long value, int base, int min, int max, int flags);
92 static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
93 long double fvalue, int min, int max, int flags);
94 static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
95
96 /*
97 * dopr(): poor man's version of doprintf
98 */
99
100 /* format read states */
101 #define DP_S_DEFAULT 0
102 #define DP_S_FLAGS 1
103 #define DP_S_MIN 2
104 #define DP_S_DOT 3
105 #define DP_S_MAX 4
106 #define DP_S_MOD 5
107 #define DP_S_CONV 6
108 #define DP_S_DONE 7
109
110 /* format flags - Bits */
111 #define DP_F_MINUS (1 << 0)
112 #define DP_F_PLUS (1 << 1)
113 #define DP_F_SPACE (1 << 2)
114 #define DP_F_NUM (1 << 3)
115 #define DP_F_ZERO (1 << 4)
116 #define DP_F_UP (1 << 5)
117 #define DP_F_UNSIGNED (1 << 6)
118
119 /* Conversion Flags */
120 #define DP_C_SHORT 1
121 #define DP_C_LONG 2
122 #define DP_C_LDOUBLE 3
123
124 #define char_to_int(p) ((int)(p - '0'))
125 #define MAX(p,q) ((p >= q) ? p : q)
126
127 static int
dopr(char * buffer,size_t maxlen,const char * format,va_list args)128 dopr (char *buffer, size_t maxlen, const char *format, va_list args)
129 {
130 char ch;
131 long value;
132 long double fvalue;
133 char *strvalue;
134 int min;
135 int max;
136 int state;
137 int flags;
138 int cflags;
139 size_t currlen;
140
141 state = DP_S_DEFAULT;
142 currlen = flags = cflags = min = 0;
143 max = -1;
144 ch = *format++;
145
146 while (state != DP_S_DONE)
147 {
148 if ((ch == '\0') || (currlen >= maxlen))
149 state = DP_S_DONE;
150
151 switch(state)
152 {
153 case DP_S_DEFAULT:
154 if (ch == '%')
155 state = DP_S_FLAGS;
156 else
157 dopr_outch (buffer, &currlen, maxlen, ch);
158 ch = *format++;
159 break;
160 case DP_S_FLAGS:
161 switch (ch)
162 {
163 case '-':
164 flags |= DP_F_MINUS;
165 ch = *format++;
166 break;
167 case '+':
168 flags |= DP_F_PLUS;
169 ch = *format++;
170 break;
171 case ' ':
172 flags |= DP_F_SPACE;
173 ch = *format++;
174 break;
175 case '#':
176 flags |= DP_F_NUM;
177 ch = *format++;
178 break;
179 case '0':
180 flags |= DP_F_ZERO;
181 ch = *format++;
182 break;
183 default:
184 state = DP_S_MIN;
185 break;
186 }
187 break;
188 case DP_S_MIN:
189 if (isdigit(ch))
190 {
191 min = 10*min + char_to_int (ch);
192 ch = *format++;
193 }
194 else if (ch == '*')
195 {
196 min = va_arg (args, int);
197 ch = *format++;
198 state = DP_S_DOT;
199 }
200 else
201 state = DP_S_DOT;
202 break;
203 case DP_S_DOT:
204 if (ch == '.')
205 {
206 state = DP_S_MAX;
207 ch = *format++;
208 }
209 else
210 state = DP_S_MOD;
211 break;
212 case DP_S_MAX:
213 if (isdigit(ch))
214 {
215 if (max < 0)
216 max = 0;
217 max = 10*max + char_to_int (ch);
218 ch = *format++;
219 }
220 else if (ch == '*')
221 {
222 max = va_arg (args, int);
223 ch = *format++;
224 state = DP_S_MOD;
225 }
226 else
227 state = DP_S_MOD;
228 break;
229 case DP_S_MOD:
230 /* Currently, we don't support Long Long, bummer */
231 switch (ch)
232 {
233 case 'h':
234 cflags = DP_C_SHORT;
235 ch = *format++;
236 break;
237 case 'l':
238 cflags = DP_C_LONG;
239 ch = *format++;
240 break;
241 case 'L':
242 cflags = DP_C_LDOUBLE;
243 ch = *format++;
244 break;
245 default:
246 break;
247 }
248 state = DP_S_CONV;
249 break;
250 case DP_S_CONV:
251 switch (ch)
252 {
253 case 'd':
254 case 'i':
255 if (cflags == DP_C_SHORT)
256 value = va_arg (args, int) & 0xffff;
257 else if (cflags == DP_C_LONG)
258 value = va_arg (args, long int);
259 else
260 value = va_arg (args, int);
261 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
262 break;
263 case 'o':
264 flags |= DP_F_UNSIGNED;
265 if (cflags == DP_C_SHORT)
266 value = va_arg (args, unsigned int) & 0xffff;
267 else if (cflags == DP_C_LONG)
268 value = va_arg (args, unsigned long int);
269 else
270 value = va_arg (args, unsigned int);
271 fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
272 break;
273 case 'u':
274 flags |= DP_F_UNSIGNED;
275 if (cflags == DP_C_SHORT)
276 value = va_arg (args, unsigned int) & 0xffff;
277 else if (cflags == DP_C_LONG)
278 value = va_arg (args, unsigned long int);
279 else
280 value = va_arg (args, unsigned int);
281 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
282 break;
283 case 'X':
284 flags |= DP_F_UP;
285 case 'x':
286 flags |= DP_F_UNSIGNED;
287 if (cflags == DP_C_SHORT)
288 value = va_arg (args, unsigned int) & 0xffff;
289 else if (cflags == DP_C_LONG)
290 value = va_arg (args, unsigned long int);
291 else
292 value = va_arg (args, unsigned int);
293 fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
294 break;
295 case 'f':
296 if (cflags == DP_C_LDOUBLE)
297 fvalue = va_arg (args, long double);
298 else
299 fvalue = va_arg (args, double);
300 /* um, floating point? */
301 fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
302 break;
303 case 'E':
304 flags |= DP_F_UP;
305 case 'e':
306 if (cflags == DP_C_LDOUBLE)
307 fvalue = va_arg (args, long double);
308 else
309 fvalue = va_arg (args, double);
310 break;
311 case 'G':
312 flags |= DP_F_UP;
313 case 'g':
314 if (cflags == DP_C_LDOUBLE)
315 fvalue = va_arg (args, long double);
316 else
317 fvalue = va_arg (args, double);
318 break;
319 case 'c':
320 dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
321 break;
322 case 's':
323 strvalue = va_arg (args, char *);
324 if (max < 0)
325 max = maxlen; /* ie, no max */
326 fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
327 break;
328 case 'p':
329 strvalue = va_arg (args, void *);
330 fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
331 break;
332 case 'n':
333 if (cflags == DP_C_SHORT)
334 {
335 short int *num;
336 num = va_arg (args, short int *);
337 *num = currlen;
338 }
339 else if (cflags == DP_C_LONG)
340 {
341 long int *num;
342 num = va_arg (args, long int *);
343 *num = currlen;
344 }
345 else
346 {
347 int *num;
348 num = va_arg (args, int *);
349 *num = currlen;
350 }
351 break;
352 case '%':
353 dopr_outch (buffer, &currlen, maxlen, ch);
354 break;
355 case 'w':
356 /* not supported yet, treat as next char */
357 ch = *format++;
358 break;
359 default:
360 /* Unknown, skip */
361 break;
362 }
363 ch = *format++;
364 state = DP_S_DEFAULT;
365 flags = cflags = min = 0;
366 max = -1;
367 break;
368 case DP_S_DONE:
369 break;
370 default:
371 /* hmm? */
372 break; /* some picky compilers need this */
373 }
374 }
375 if (currlen < maxlen - 1) {
376 buffer[currlen] = '\0';
377 return currlen;
378 } else {
379 buffer[maxlen - 1] = '\0';
380 return -1;
381 }
382 }
383
fmtstr(char * buffer,size_t * currlen,size_t maxlen,char * value,int flags,int min,int max)384 static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
385 char *value, int flags, int min, int max)
386 {
387 int padlen, strln; /* amount to pad */
388 int cnt = 0;
389
390 if (value == 0)
391 {
392 value = "<NULL>";
393 }
394
395 for (strln = 0; value[strln]; ++strln); /* strlen */
396 padlen = min - strln;
397 if (padlen < 0)
398 padlen = 0;
399 if (flags & DP_F_MINUS)
400 padlen = -padlen; /* Left Justify */
401
402 while ((padlen > 0) && (cnt < max))
403 {
404 dopr_outch (buffer, currlen, maxlen, ' ');
405 --padlen;
406 ++cnt;
407 }
408 while (*value && (cnt < max))
409 {
410 dopr_outch (buffer, currlen, maxlen, *value++);
411 ++cnt;
412 }
413 while ((padlen < 0) && (cnt < max))
414 {
415 dopr_outch (buffer, currlen, maxlen, ' ');
416 ++padlen;
417 ++cnt;
418 }
419 }
420
421 /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
422
fmtint(char * buffer,size_t * currlen,size_t maxlen,long value,int base,int min,int max,int flags)423 static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
424 long value, int base, int min, int max, int flags)
425 {
426 int signvalue = 0;
427 unsigned long uvalue;
428 char convert[20];
429 int place = 0;
430 int spadlen = 0; /* amount to space pad */
431 int zpadlen = 0; /* amount to zero pad */
432 int caps = 0;
433
434 if (max < 0)
435 max = 0;
436
437 uvalue = value;
438
439 if (!(flags & DP_F_UNSIGNED))
440 {
441 if (value < 0) {
442 signvalue = '-';
443 uvalue = -value;
444 }
445 else
446 if (flags & DP_F_PLUS) /* Do a sign (+/i) */
447 signvalue = '+';
448 else
449 if (flags & DP_F_SPACE)
450 signvalue = ' ';
451 }
452
453 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
454
455 do {
456 convert[place++] =
457 (caps? "0123456789ABCDEF":"0123456789abcdef")
458 [uvalue % (unsigned)base ];
459 uvalue = (uvalue / (unsigned)base );
460 } while(uvalue && (place < 20));
461 if (place == 20) place--;
462 convert[place] = 0;
463
464 zpadlen = max - place;
465 spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
466 if (zpadlen < 0) zpadlen = 0;
467 if (spadlen < 0) spadlen = 0;
468 if (flags & DP_F_ZERO)
469 {
470 zpadlen = MAX(zpadlen, spadlen);
471 spadlen = 0;
472 }
473 if (flags & DP_F_MINUS)
474 spadlen = -spadlen; /* Left Justifty */
475
476 #ifdef DEBUG_SNPRINTF
477 dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
478 zpadlen, spadlen, min, max, place));
479 #endif
480
481 /* Spaces */
482 while (spadlen > 0)
483 {
484 dopr_outch (buffer, currlen, maxlen, ' ');
485 --spadlen;
486 }
487
488 /* Sign */
489 if (signvalue)
490 dopr_outch (buffer, currlen, maxlen, signvalue);
491
492 /* Zeros */
493 if (zpadlen > 0)
494 {
495 while (zpadlen > 0)
496 {
497 dopr_outch (buffer, currlen, maxlen, '0');
498 --zpadlen;
499 }
500 }
501
502 /* Digits */
503 while (place > 0)
504 dopr_outch (buffer, currlen, maxlen, convert[--place]);
505
506 /* Left Justified spaces */
507 while (spadlen < 0) {
508 dopr_outch (buffer, currlen, maxlen, ' ');
509 ++spadlen;
510 }
511 }
512
abs_val(long double value)513 static long double abs_val (long double value)
514 {
515 long double result = value;
516
517 if (value < 0)
518 result = -value;
519
520 return result;
521 }
522
pow10(int exp)523 static long double pow10 (int exp)
524 {
525 long double result = 1;
526
527 while (exp)
528 {
529 result *= 10;
530 exp--;
531 }
532
533 return result;
534 }
535
round(long double value)536 static long round (long double value)
537 {
538 long intpart;
539
540 intpart = value;
541 value = value - intpart;
542 if (value >= 0.5)
543 intpart++;
544
545 return intpart;
546 }
547
fmtfp(char * buffer,size_t * currlen,size_t maxlen,long double fvalue,int min,int max,int flags)548 static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
549 long double fvalue, int min, int max, int flags)
550 {
551 int signvalue = 0;
552 long double ufvalue;
553 char iconvert[20];
554 char fconvert[20];
555 int iplace = 0;
556 int fplace = 0;
557 int padlen = 0; /* amount to pad */
558 int zpadlen = 0;
559 int caps = 0;
560 long intpart;
561 long fracpart;
562
563 /*
564 * AIX manpage says the default is 0, but Solaris says the default
565 * is 6, and sprintf on AIX defaults to 6
566 */
567 if (max < 0)
568 max = 6;
569
570 ufvalue = abs_val (fvalue);
571
572 if (fvalue < 0)
573 signvalue = '-';
574 else
575 if (flags & DP_F_PLUS) /* Do a sign (+/i) */
576 signvalue = '+';
577 else
578 if (flags & DP_F_SPACE)
579 signvalue = ' ';
580
581 #if 0
582 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
583 #endif
584
585 intpart = ufvalue;
586
587 /*
588 * Sorry, we only support 9 digits past the decimal because of our
589 * conversion method
590 */
591 if (max > 9)
592 max = 9;
593
594 /* We "cheat" by converting the fractional part to integer by
595 * multiplying by a factor of 10
596 */
597 fracpart = round ((pow10 (max)) * (ufvalue - intpart));
598
599 if (fracpart >= pow10 (max))
600 {
601 intpart++;
602 fracpart -= pow10 (max);
603 }
604
605 #ifdef DEBUG_SNPRINTF
606 dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
607 #endif
608
609 /* Convert integer part */
610 do {
611 iconvert[iplace++] =
612 (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
613 intpart = (intpart / 10);
614 } while(intpart && (iplace < 20));
615 if (iplace == 20) iplace--;
616 iconvert[iplace] = 0;
617
618 /* Convert fractional part */
619 do {
620 fconvert[fplace++] =
621 (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
622 fracpart = (fracpart / 10);
623 } while(fracpart && (fplace < 20));
624 if (fplace == 20) fplace--;
625 fconvert[fplace] = 0;
626
627 /* -1 for decimal point, another -1 if we are printing a sign */
628 padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
629 zpadlen = max - fplace;
630 if (zpadlen < 0)
631 zpadlen = 0;
632 if (padlen < 0)
633 padlen = 0;
634 if (flags & DP_F_MINUS)
635 padlen = -padlen; /* Left Justifty */
636
637 if ((flags & DP_F_ZERO) && (padlen > 0))
638 {
639 if (signvalue)
640 {
641 dopr_outch (buffer, currlen, maxlen, signvalue);
642 --padlen;
643 signvalue = 0;
644 }
645 while (padlen > 0)
646 {
647 dopr_outch (buffer, currlen, maxlen, '0');
648 --padlen;
649 }
650 }
651 while (padlen > 0)
652 {
653 dopr_outch (buffer, currlen, maxlen, ' ');
654 --padlen;
655 }
656 if (signvalue)
657 dopr_outch (buffer, currlen, maxlen, signvalue);
658
659 while (iplace > 0)
660 dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
661
662 /*
663 * Decimal point. This should probably use locale to find the correct
664 * char to print out.
665 */
666 dopr_outch (buffer, currlen, maxlen, '.');
667
668 while (fplace > 0)
669 dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
670
671 while (zpadlen > 0)
672 {
673 dopr_outch (buffer, currlen, maxlen, '0');
674 --zpadlen;
675 }
676
677 while (padlen < 0)
678 {
679 dopr_outch (buffer, currlen, maxlen, ' ');
680 ++padlen;
681 }
682 }
683
dopr_outch(char * buffer,size_t * currlen,size_t maxlen,char c)684 static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
685 {
686 if (*currlen < maxlen)
687 buffer[(*currlen)++] = c;
688 }
689 #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
690
691 #if defined(BROKEN_SNPRINTF) || !defined(HAVE_VSNPRINTF)
vsnprintf(char * str,size_t count,const char * fmt,va_list args)692 int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
693 {
694 int len;
695
696 if (!count)
697 return -1;
698 str[0] = 0;
699 len = dopr(str, count, fmt, args);
700
701 return len;
702 }
703 #endif /* !HAVE_VSNPRINTF */
704
705 #if defined(BROKEN_SNPRINTF) || !defined(HAVE_SNPRINTF)
706 /* VARARGS3 */
707 #ifdef HAVE_STDARGS
snprintf(char * str,size_t count,const char * fmt,...)708 int snprintf (char *str,size_t count,const char *fmt,...)
709 #else
710 int snprintf (va_alist) va_dcl
711 #endif
712 {
713 #ifndef HAVE_STDARGS
714 char *str;
715 size_t count;
716 char *fmt;
717 #endif
718 VA_LOCAL_DECL;
719 int len;
720
721 VA_START (fmt);
722 VA_SHIFT (str, char *);
723 VA_SHIFT (count, size_t );
724 VA_SHIFT (fmt, char *);
725 len = vsnprintf(str, count, fmt, ap);
726 VA_END;
727
728 return len;
729 }
730
731 #ifdef TEST_SNPRINTF
732 #ifndef LONG_STRING
733 #define LONG_STRING 1024
734 #endif
main(void)735 int main (void)
736 {
737 char buf1[LONG_STRING];
738 char buf2[LONG_STRING];
739 char *fp_fmt[] = {
740 "%-1.5f",
741 "%1.5f",
742 "%123.9f",
743 "%10.5f",
744 "% 10.5f",
745 "%+22.9f",
746 "%+4.9f",
747 "%01.3f",
748 "%4f",
749 "%3.1f",
750 "%3.2f",
751 0
752 };
753 double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
754 0.9996, 1.996, 4.136, 0};
755 char *int_fmt[] = {
756 "%-1.5d",
757 "%1.5d",
758 "%123.9d",
759 "%5.5d",
760 "%10.5d",
761 "% 10.5d",
762 "%+22.33d",
763 "%01.3d",
764 "%4d",
765 0
766 };
767 long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
768 int x, y;
769 int fail = 0;
770 int num = 0;
771
772 printf("Testing snprintf format codes against system sprintf...\n");
773
774 for (x = 0; fp_fmt[x] != 0 ; x++)
775 for (y = 0; fp_nums[y] != 0 ; y++)
776 {
777 snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
778 sprintf(buf2, fp_fmt[x], fp_nums[y]);
779 if (strcmp(buf1, buf2))
780 {
781 printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
782 fp_fmt[x], buf1, buf2);
783 fail++;
784 }
785 num++;
786 }
787
788 for (x = 0; int_fmt[x] != 0 ; x++)
789 for (y = 0; int_nums[y] != 0 ; y++)
790 {
791 snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
792 sprintf(buf2, int_fmt[x], int_nums[y]);
793 if (strcmp (buf1, buf2))
794 {
795 printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
796 int_fmt[x], buf1, buf2);
797 fail++;
798 }
799 num++;
800 }
801 printf("%d tests failed out of %d.\n", fail, num);
802 }
803 #endif /* SNPRINTF_TEST */
804
805 #endif /* !HAVE_SNPRINTF */
806