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