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