Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / openssh / openbsd-compat / bsd-snprintf.c
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  *  Ben Lindstrom <mouring@eviladmin.org> 09/27/00 for OpenSSH
42  *    Welcome to the world of %lld and %qd support.  With other
43  *    long long support.  This is needed for sftp-server to work
44  *    right.
45  *
46  *  Ben Lindstrom <mouring@eviladmin.org> 02/12/01 for OpenSSH
47  *    Removed all hint of VARARGS stuff and banished it to the void,
48  *    and did a bit of KNF style work to make things a bit more
49  *    acceptable.  Consider stealing from mutt or enlightenment.
50  **************************************************************/
51
52 #include "includes.h"
53
54 RCSID("$Id: bsd-snprintf.c,v 1.5 2001/02/25 23:20:41 mouring Exp $");
55
56 #if defined(BROKEN_SNPRINTF)            /* For those with broken snprintf() */
57 # undef HAVE_SNPRINTF
58 # undef HAVE_VSNPRINTF
59 #endif
60
61 #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
62
63 static void 
64 dopr(char *buffer, size_t maxlen, const char *format, va_list args);
65
66 static void 
67 fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, 
68        int min, int max);
69
70 static void 
71 fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, 
72        int min, int max, int flags);
73
74 static void 
75 fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, 
76       int min, int max, int flags);
77
78 static void
79 dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
80
81 /*
82  * dopr(): poor man's version of doprintf
83  */
84
85 /* format read states */
86 #define DP_S_DEFAULT 0
87 #define DP_S_FLAGS   1
88 #define DP_S_MIN     2
89 #define DP_S_DOT     3
90 #define DP_S_MAX     4
91 #define DP_S_MOD     5
92 #define DP_S_CONV    6
93 #define DP_S_DONE    7
94
95 /* format flags - Bits */
96 #define DP_F_MINUS      (1 << 0)
97 #define DP_F_PLUS       (1 << 1)
98 #define DP_F_SPACE      (1 << 2)
99 #define DP_F_NUM        (1 << 3)
100 #define DP_F_ZERO       (1 << 4)
101 #define DP_F_UP         (1 << 5)
102 #define DP_F_UNSIGNED   (1 << 6)
103
104 /* Conversion Flags */
105 #define DP_C_SHORT     1
106 #define DP_C_LONG      2
107 #define DP_C_LDOUBLE   3
108 #define DP_C_LONG_LONG 4
109
110 #define char_to_int(p) (p - '0')
111 #define abs_val(p) (p < 0 ? -p : p)
112
113
114 static void 
115 dopr(char *buffer, size_t maxlen, const char *format, va_list args)
116 {
117         char *strvalue;
118         char ch;
119         long value;
120         long double fvalue;
121         int min = 0;
122         int max = -1;
123         int state = DP_S_DEFAULT;
124         int flags = 0;
125         int cflags = 0;
126         size_t currlen = 0;
127   
128         ch = *format++;
129
130         while (state != DP_S_DONE) {
131                 if ((ch == '\0') || (currlen >= maxlen)) 
132                         state = DP_S_DONE;
133
134                 switch(state) {
135                         case DP_S_DEFAULT:
136                                 if (ch == '%') 
137                                         state = DP_S_FLAGS;
138                                 else 
139                                         dopr_outch(buffer, &currlen, maxlen, ch);
140                                 ch = *format++;
141                                 break;
142                         case DP_S_FLAGS:
143                                 switch (ch) {
144                                         case '-':
145                                                 flags |= DP_F_MINUS;
146                                                 ch = *format++;
147                                                 break;
148                                         case '+':
149                                                 flags |= DP_F_PLUS;
150                                                 ch = *format++;
151                                                 break;
152                                         case ' ':
153                                                 flags |= DP_F_SPACE;
154                                                 ch = *format++;
155                                                 break;
156                                         case '#':
157                                                 flags |= DP_F_NUM;
158                                                 ch = *format++;
159                                                 break;
160                                         case '0':
161                                                 flags |= DP_F_ZERO;
162                                                 ch = *format++;
163                                                 break;
164                                         default:
165                                                 state = DP_S_MIN;
166                                                 break;
167                                 }
168                                 break;
169                         case DP_S_MIN:
170                                 if (isdigit((unsigned char)ch)) {
171                                         min = 10*min + char_to_int (ch);
172                                         ch = *format++;
173                                 } else if (ch == '*') {
174                                         min = va_arg (args, int);
175                                         ch = *format++;
176                                         state = DP_S_DOT;
177                                 } else 
178                                         state = DP_S_DOT;
179                                 break;
180                         case DP_S_DOT:
181                                 if (ch == '.') {
182                                         state = DP_S_MAX;
183                                         ch = *format++;
184                                 } else 
185                                         state = DP_S_MOD;
186                                 break;
187                         case DP_S_MAX:
188                                 if (isdigit((unsigned char)ch)) {
189                                         if (max < 0)
190                                                 max = 0;
191                                         max = 10*max + char_to_int(ch);
192                                         ch = *format++;
193                                 } else if (ch == '*') {
194                                         max = va_arg (args, int);
195                                         ch = *format++;
196                                         state = DP_S_MOD;
197                                 } else 
198                                         state = DP_S_MOD;
199                                 break;
200                         case DP_S_MOD:
201                                 switch (ch) {
202                                         case 'h':
203                                                 cflags = DP_C_SHORT;
204                                                 ch = *format++;
205                                                 break;
206                                         case 'l':
207                                                 cflags = DP_C_LONG;
208                                                 ch = *format++;
209                                                 if (ch == 'l') {
210                                                         cflags = DP_C_LONG_LONG;
211                                                         ch = *format++;
212                                                 }
213                                                 break;
214                                         case 'q':
215                                                 cflags = DP_C_LONG_LONG;
216                                                 ch = *format++;
217                                                 break;
218                                         case 'L':
219                                                 cflags = DP_C_LDOUBLE;
220                                                 ch = *format++;
221                                                 break;
222                                         default:
223                                                 break;
224                                 }
225                                 state = DP_S_CONV;
226                                 break;
227                         case DP_S_CONV:
228                                 switch (ch) {
229                                         case 'd':
230                                         case 'i':
231                                                 if (cflags == DP_C_SHORT) 
232                                                         value = va_arg(args, int);
233                                                 else if (cflags == DP_C_LONG)
234                                                         value = va_arg(args, long int);
235                                                 else if (cflags == DP_C_LONG_LONG)
236                                                         value = va_arg (args, long long);
237                                                 else
238                                                         value = va_arg (args, int);
239                                                 fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
240                                                 break;
241                                         case 'o':
242                                                 flags |= DP_F_UNSIGNED;
243                                                 if (cflags == DP_C_SHORT)
244                                                         value = va_arg(args, unsigned int);
245                                                 else if (cflags == DP_C_LONG)
246                                                         value = va_arg(args, unsigned long int);
247                                                 else if (cflags == DP_C_LONG_LONG)
248                                                         value = va_arg(args, unsigned long long);
249                                                 else
250                                                         value = va_arg(args, unsigned int);
251                                                 fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
252                                                 break;
253                                         case 'u':
254                                                 flags |= DP_F_UNSIGNED;
255                                                 if (cflags == DP_C_SHORT)
256                                                         value = va_arg(args, unsigned int);
257                                                 else if (cflags == DP_C_LONG)
258                                                         value = va_arg(args, unsigned long int);
259                                                 else if (cflags == DP_C_LONG_LONG)
260                                                         value = va_arg(args, unsigned long long);
261                                                 else
262                                                         value = va_arg(args, unsigned int);
263                                                 fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
264                                                 break;
265                                         case 'X':
266                                                 flags |= DP_F_UP;
267                                         case 'x':
268                                                 flags |= DP_F_UNSIGNED;
269                                                 if (cflags == DP_C_SHORT)
270                                                         value = va_arg(args, unsigned int);
271                                                 else if (cflags == DP_C_LONG)
272                                                         value = va_arg(args, unsigned long int);
273                                                 else if (cflags == DP_C_LONG_LONG)
274                                                         value = va_arg(args, unsigned long long);
275                                                 else
276                                                         value = va_arg(args, unsigned int);
277                                                 fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
278                                                 break;
279                                         case 'f':
280                                                 if (cflags == DP_C_LDOUBLE)
281                                                         fvalue = va_arg(args, long double);
282                                                 else
283                                                         fvalue = va_arg(args, double);
284                                                 /* um, floating point? */
285                                                 fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
286                                                 break;
287                                         case 'E':
288                                                 flags |= DP_F_UP;
289                                         case 'e':
290                                                 if (cflags == DP_C_LDOUBLE)
291                                                         fvalue = va_arg(args, long double);
292                                                 else
293                                                         fvalue = va_arg(args, double);
294                                                 break;
295                                         case 'G':
296                                                 flags |= DP_F_UP;
297                                         case 'g':
298                                                 if (cflags == DP_C_LDOUBLE)
299                                                         fvalue = va_arg(args, long double);
300                                                 else
301                                                         fvalue = va_arg(args, double);
302                                                 break;
303                                         case 'c':
304                                                 dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
305                                                 break;
306                                         case 's':
307                                                 strvalue = va_arg(args, char *);
308                                                 if (max < 0) 
309                                                         max = maxlen; /* ie, no max */
310                                                 fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
311                                                 break;
312                                         case 'p':
313                                                 strvalue = va_arg(args, void *);
314                                                 fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
315                                                 break;
316                                         case 'n':
317                                                 if (cflags == DP_C_SHORT) {
318                                                         short int *num;
319                                                         num = va_arg(args, short int *);
320                                                         *num = currlen;
321                                                 } else if (cflags == DP_C_LONG) {
322                                                         long int *num;
323                                                         num = va_arg(args, long int *);
324                                                         *num = currlen;
325                                                 } else if (cflags == DP_C_LONG_LONG) {
326                                                         long long *num;
327                                                         num = va_arg(args, long long *);
328                                                         *num = currlen;
329                                                 } else {
330                                                         int *num;
331                                                         num = va_arg(args, int *);
332                                                         *num = currlen;
333                                                 }
334                                                 break;
335                                         case '%':
336                                                 dopr_outch(buffer, &currlen, maxlen, ch);
337                                                 break;
338                                         case 'w': /* not supported yet, treat as next char */
339                                                 ch = *format++;
340                                                 break;
341                                         default: /* Unknown, skip */
342                                         break;
343                                 }
344                                 ch = *format++;
345                                 state = DP_S_DEFAULT;
346                                 flags = cflags = min = 0;
347                                 max = -1;
348                                 break;
349                         case DP_S_DONE:
350                                 break;
351                         default: /* hmm? */
352                                 break; /* some picky compilers need this */
353                 }
354         }
355         if (currlen < maxlen - 1) 
356                 buffer[currlen] = '\0';
357         else 
358                 buffer[maxlen - 1] = '\0';
359 }
360
361 static void
362 fmtstr(char *buffer, size_t *currlen, size_t maxlen,
363        char *value, int flags, int min, int max)
364 {
365         int padlen, strln;     /* amount to pad */
366         int cnt = 0;
367   
368         if (value == 0) 
369                 value = "<NULL>";
370
371         for (strln = 0; value[strln]; ++strln); /* strlen */
372         padlen = min - strln;
373         if (padlen < 0) 
374                 padlen = 0;
375         if (flags & DP_F_MINUS) 
376                 padlen = -padlen; /* Left Justify */
377
378         while ((padlen > 0) && (cnt < max)) {
379                 dopr_outch(buffer, currlen, maxlen, ' ');
380                 --padlen;
381                 ++cnt;
382         }
383         while (*value && (cnt < max)) {
384                 dopr_outch(buffer, currlen, maxlen, *value++);
385                 ++cnt;
386         }
387         while ((padlen < 0) && (cnt < max)) {
388                 dopr_outch(buffer, currlen, maxlen, ' ');
389                 ++padlen;
390                 ++cnt;
391         }
392 }
393
394 /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
395
396 static void 
397 fmtint(char *buffer, size_t *currlen, size_t maxlen,
398        long value, int base, int min, int max, int flags)
399 {
400         unsigned long uvalue;
401         char convert[20];
402         int signvalue = 0;
403         int place = 0;
404         int spadlen = 0; /* amount to space pad */
405         int zpadlen = 0; /* amount to zero pad */
406         int caps = 0;
407   
408         if (max < 0)
409                 max = 0;
410
411         uvalue = value;
412
413         if (!(flags & DP_F_UNSIGNED)) {
414                 if (value < 0) {
415                         signvalue = '-';
416                         uvalue = -value;
417                 } else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
418                         signvalue = '+';
419                 else if (flags & DP_F_SPACE)
420                         signvalue = ' ';
421         }
422   
423         if (flags & DP_F_UP) 
424                 caps = 1; /* Should characters be upper case? */
425
426         do {
427                 convert[place++] =
428                         (caps? "0123456789ABCDEF":"0123456789abcdef")
429                         [uvalue % (unsigned)base];
430                 uvalue = (uvalue / (unsigned)base );
431         } while (uvalue && (place < 20));
432         if (place == 20) 
433                 place--;
434         convert[place] = 0;
435
436         zpadlen = max - place;
437         spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
438         if (zpadlen < 0)
439                 zpadlen = 0;
440         if (spadlen < 0)
441                 spadlen = 0;
442         if (flags & DP_F_ZERO) {
443                 zpadlen = MAX(zpadlen, spadlen);
444                 spadlen = 0;
445         }
446         if (flags & DP_F_MINUS) 
447                 spadlen = -spadlen; /* Left Justifty */
448
449
450         /* Spaces */
451         while (spadlen > 0) {
452                 dopr_outch(buffer, currlen, maxlen, ' ');
453                 --spadlen;
454         }
455
456         /* Sign */
457         if (signvalue) 
458                 dopr_outch(buffer, currlen, maxlen, signvalue);
459
460         /* Zeros */
461         if (zpadlen > 0) {
462                 while (zpadlen > 0) {
463                         dopr_outch(buffer, currlen, maxlen, '0');
464                         --zpadlen;
465                 }
466         }
467
468         /* Digits */
469         while (place > 0) 
470                 dopr_outch(buffer, currlen, maxlen, convert[--place]);
471   
472         /* Left Justified spaces */
473         while (spadlen < 0) {
474                 dopr_outch (buffer, currlen, maxlen, ' ');
475                 ++spadlen;
476         }
477 }
478
479 static long double 
480 pow10(int exp)
481 {
482         long double result = 1;
483
484         while (exp) {
485                 result *= 10;
486                 exp--;
487         }
488   
489         return result;
490 }
491
492 static long 
493 round(long double value)
494 {
495         long intpart = value;
496
497         value -= intpart;
498         if (value >= 0.5)
499                 intpart++;
500
501         return intpart;
502 }
503
504 static void 
505 fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, 
506       int min, int max, int flags)
507 {
508         char iconvert[20];
509         char fconvert[20];
510         int signvalue = 0;
511         int iplace = 0;
512         int fplace = 0;
513         int padlen = 0; /* amount to pad */
514         int zpadlen = 0; 
515         int caps = 0;
516         long intpart;
517         long fracpart;
518         long double ufvalue;
519   
520         /* 
521          * AIX manpage says the default is 0, but Solaris says the default
522          * is 6, and sprintf on AIX defaults to 6
523          */
524         if (max < 0)
525                 max = 6;
526
527         ufvalue = abs_val(fvalue);
528
529         if (fvalue < 0)
530                 signvalue = '-';
531         else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
532                 signvalue = '+';
533         else if (flags & DP_F_SPACE)
534                 signvalue = ' ';
535
536         intpart = ufvalue;
537
538         /* 
539          * Sorry, we only support 9 digits past the decimal because of our 
540          * conversion method
541          */
542         if (max > 9)
543                 max = 9;
544
545         /* We "cheat" by converting the fractional part to integer by
546          * multiplying by a factor of 10
547          */
548         fracpart = round((pow10 (max)) * (ufvalue - intpart));
549
550         if (fracpart >= pow10 (max)) {
551                 intpart++;
552                 fracpart -= pow10 (max);
553         }
554
555         /* Convert integer part */
556         do {
557                 iconvert[iplace++] =
558                   (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
559                 intpart = (intpart / 10);
560         } while(intpart && (iplace < 20));
561         if (iplace == 20) 
562                 iplace--;
563         iconvert[iplace] = 0;
564
565         /* Convert fractional part */
566         do {
567                 fconvert[fplace++] =
568                   (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
569                 fracpart = (fracpart / 10);
570         } while(fracpart && (fplace < 20));
571         if (fplace == 20) 
572                 fplace--;
573         fconvert[fplace] = 0;
574
575         /* -1 for decimal point, another -1 if we are printing a sign */
576         padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
577         zpadlen = max - fplace;
578         if (zpadlen < 0)
579                 zpadlen = 0;
580         if (padlen < 0) 
581                 padlen = 0;
582         if (flags & DP_F_MINUS) 
583                 padlen = -padlen; /* Left Justifty */
584
585         if ((flags & DP_F_ZERO) && (padlen > 0)) {
586                 if (signvalue) {
587                         dopr_outch(buffer, currlen, maxlen, signvalue);
588                         --padlen;
589                         signvalue = 0;
590                 }
591                 while (padlen > 0) {
592                         dopr_outch(buffer, currlen, maxlen, '0');
593                         --padlen;
594                 }
595         }
596         while (padlen > 0) {
597                 dopr_outch(buffer, currlen, maxlen, ' ');
598                 --padlen;
599         }
600         if (signvalue) 
601                 dopr_outch(buffer, currlen, maxlen, signvalue);
602
603         while (iplace > 0) 
604                 dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
605
606         /*
607          * Decimal point.  This should probably use locale to find the correct
608          * char to print out.
609          */
610         dopr_outch(buffer, currlen, maxlen, '.');
611
612         while (fplace > 0) 
613                 dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
614
615         while (zpadlen > 0) {
616                 dopr_outch(buffer, currlen, maxlen, '0');
617                 --zpadlen;
618         }
619
620         while (padlen < 0) {
621                 dopr_outch(buffer, currlen, maxlen, ' ');
622                 ++padlen;
623         }
624 }
625
626 static void 
627 dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
628 {
629         if (*currlen < maxlen)
630                 buffer[(*currlen)++] = c;
631 }
632 #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
633
634 #ifndef HAVE_VSNPRINTF
635 int 
636 vsnprintf(char *str, size_t count, const char *fmt, va_list args)
637 {
638         str[0] = 0;
639         dopr(str, count, fmt, args);
640
641         return(strlen(str));
642 }
643 #endif /* !HAVE_VSNPRINTF */
644
645 #ifndef HAVE_SNPRINTF
646 int 
647 snprintf(char *str,size_t count,const char *fmt,...)
648 {
649         va_list ap;
650
651         va_start(ap, fmt);
652         (void) vsnprintf(str, count, fmt, ap);
653         va_end(ap);
654
655         return(strlen(str));
656 }
657
658 #ifdef TEST_SNPRINTF
659 int 
660 main(void)
661 {
662 #define LONG_STRING 1024
663         char buf1[LONG_STRING];
664         char buf2[LONG_STRING];
665         char *fp_fmt[] = {
666                 "%-1.5f",
667                 "%1.5f",
668                 "%123.9f",
669                 "%10.5f",
670                 "% 10.5f",
671                 "%+22.9f",
672                 "%+4.9f",
673                 "%01.3f",
674                 "%4f",
675                 "%3.1f",
676                 "%3.2f",
677                 NULL
678         };
679         double fp_nums[] = { 
680                 -1.5, 
681                 134.21, 
682                 91340.2, 
683                 341.1234, 
684                 0203.9, 
685                 0.96, 
686                 0.996, 
687                 0.9996, 
688                 1.996, 
689                 4.136, 
690                 0
691         };
692         char *int_fmt[] = {
693                 "%-1.5d",
694                 "%1.5d",
695                 "%123.9d",
696                 "%5.5d",
697                 "%10.5d",
698                 "% 10.5d",
699                 "%+22.33d",
700                 "%01.3d",
701                 "%4d",
702                 "%lld",
703                 "%qd",
704                 NULL
705         };
706         long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 };
707         int x, y;
708         int fail = 0;
709         int num = 0;
710
711         printf("Testing snprintf format codes against system sprintf...\n");
712
713         for (x = 0; fp_fmt[x] != NULL ; x++) {
714                 for (y = 0; fp_nums[y] != 0 ; y++) {
715                         snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
716                         sprintf (buf2, fp_fmt[x], fp_nums[y]);
717                         if (strcmp (buf1, buf2)) {
718                                 printf("snprintf doesn't match Format: %s\n\t"
719                                        "snprintf = %s\n\tsprintf  = %s\n", 
720                                         fp_fmt[x], buf1, buf2);
721                                 fail++;
722                         }
723                         num++;
724                 }
725         }
726         for (x = 0; int_fmt[x] != NULL ; x++) {
727                 for (y = 0; int_nums[y] != 0 ; y++) {
728                         snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
729                         sprintf(buf2, int_fmt[x], int_nums[y]);
730                         if (strcmp (buf1, buf2)) {
731                                 printf("snprintf doesn't match Format: %s\n\t"
732                                        "snprintf = %s\n\tsprintf  = %s\n", 
733                                         int_fmt[x], buf1, buf2);
734                                 fail++;
735                         }
736                         num++;
737                 }
738         }
739         printf("%d tests failed out of %d.\n", fail, num);
740         return(0);
741 }
742 #endif /* SNPRINTF_TEST */
743
744 #endif /* !HAVE_SNPRINTF */