]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcp_wrappers/vfprintf.c
libfido2: update to 1.13.0
[FreeBSD/FreeBSD.git] / contrib / tcp_wrappers / vfprintf.c
1  /*
2   * vfprintf() and vprintf() clones. They will produce unexpected results
3   * when excessive dynamic ("*") field widths are specified. To be used for
4   * testing purposes only.
5   * 
6   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
7   */
8
9 #ifndef lint
10 static char sccsid[] = "@(#) vfprintf.c 1.2 94/03/23 17:44:46";
11 #endif
12
13 #include <stdio.h>
14 #include <ctype.h>
15 #ifdef __STDC__
16 #include <stdarg.h>
17 #else
18 #include <varargs.h>
19 #endif
20
21 /* vfprintf - print variable-length argument list to stream */
22
23 int     vfprintf(FILE *fp, char *format, va_list ap)
24 {
25     char    fmt[BUFSIZ];                /* format specifier */
26     register char *fmtp;
27     register char *cp;
28     int     count = 0;
29
30     /*
31      * Iterate over characters in the format string, picking up arguments
32      * when format specifiers are found.
33      */
34
35     for (cp = format; *cp; cp++) {
36         if (*cp != '%') {
37             putc(*cp, fp);                      /* ordinary character */
38             count++;
39         } else {
40
41             /*
42              * Format specifiers are handled one at a time, since we can only
43              * deal with arguments one at a time. Try to determine the end of
44              * the format specifier. We do not attempt to fully parse format
45              * strings, since we are ging to let fprintf() do the hard work.
46              * In regular expression notation, we recognize:
47              * 
48              * %-?0?([0-9]+|\*)?\.?([0-9]+|\*)?l?[a-z]
49              * 
50              * which includes some combinations that do not make sense.
51              */
52
53             fmtp = fmt;
54             *fmtp++ = *cp++;
55             if (*cp == '-')                     /* left-adjusted field? */
56                 *fmtp++ = *cp++;
57             if (*cp == '0')                     /* zero-padded field? */
58                 *fmtp++ = *cp++;
59             if (*cp == '*') {                   /* dynamic field witdh */
60                 sprintf(fmtp, "%d", va_arg(ap, int));
61                 fmtp += strlen(fmtp);
62                 cp++;
63             } else {
64                 while (isdigit(*cp))            /* hard-coded field width */
65                     *fmtp++ = *cp++;
66             }
67             if (*cp == '.')                     /* width/precision separator */
68                 *fmtp++ = *cp++;
69             if (*cp == '*') {                   /* dynamic precision */
70                 sprintf(fmtp, "%d", va_arg(ap, int));
71                 fmtp += strlen(fmtp);
72                 cp++;
73             } else {
74                 while (isdigit(*cp))            /* hard-coded precision */
75                     *fmtp++ = *cp++;
76             }
77             if (*cp == 'l')                     /* long whatever */
78                 *fmtp++ = *cp++;
79             if (*cp == 0)                       /* premature end, punt */
80                 break;
81             *fmtp++ = *cp;                      /* type (checked below) */
82             *fmtp = 0;
83
84             /* Execute the format string - let fprintf() do the hard work. */
85
86             switch (fmtp[-1]) {
87             case 's':                           /* string-valued argument */
88                 count += fprintf(fp, fmt, va_arg(ap, char *));
89                 break;
90             case 'c':                           /* integral-valued argument */
91             case 'd':
92             case 'u':
93             case 'o':
94             case 'x':
95                 if (fmtp[-2] == 'l')
96                     count += fprintf(fp, fmt, va_arg(ap, long));
97                 else
98                     count += fprintf(fp, fmt, va_arg(ap, int));
99                 break;
100             case 'e':                           /* float-valued argument */
101             case 'f':
102             case 'g':
103                 count += fprintf(fp, fmt, va_arg(ap, double));
104                 break;
105             default:                            /* anything else */
106                 putc(fmtp[-1], fp);
107                 count++;
108                 break;
109             }
110         }
111     }
112     return (count);
113 }
114
115 /* vprintf - print variable-length argument list to stdout */
116
117 vprintf(char *format, va_list ap)
118 {
119     return (vfprintf(stdout, format, ap));
120 }