source: trunk/third/tcp_wrappers/vfprintf.c @ 11717

Revision 11717, 3.1 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11716, which included commits to RCS files with non-trunk default branches.
Line 
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
10static 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
23int     vfprintf(fp, format, ap)
24FILE   *fp;
25char   *format;
26va_list ap;
27{
28    char    fmt[BUFSIZ];                /* format specifier */
29    register char *fmtp;
30    register char *cp;
31    int     count = 0;
32
33    /*
34     * Iterate over characters in the format string, picking up arguments
35     * when format specifiers are found.
36     */
37
38    for (cp = format; *cp; cp++) {
39        if (*cp != '%') {
40            putc(*cp, fp);                      /* ordinary character */
41            count++;
42        } else {
43
44            /*
45             * Format specifiers are handled one at a time, since we can only
46             * deal with arguments one at a time. Try to determine the end of
47             * the format specifier. We do not attempt to fully parse format
48             * strings, since we are ging to let fprintf() do the hard work.
49             * In regular expression notation, we recognize:
50             *
51             * %-?0?([0-9]+|\*)?\.?([0-9]+|\*)?l?[a-z]
52             *
53             * which includes some combinations that do not make sense.
54             */
55
56            fmtp = fmt;
57            *fmtp++ = *cp++;
58            if (*cp == '-')                     /* left-adjusted field? */
59                *fmtp++ = *cp++;
60            if (*cp == '0')                     /* zero-padded field? */
61                *fmtp++ = *cp++;
62            if (*cp == '*') {                   /* dynamic field witdh */
63                sprintf(fmtp, "%d", va_arg(ap, int));
64                fmtp += strlen(fmtp);
65                cp++;
66            } else {
67                while (isdigit(*cp))            /* hard-coded field width */
68                    *fmtp++ = *cp++;
69            }
70            if (*cp == '.')                     /* width/precision separator */
71                *fmtp++ = *cp++;
72            if (*cp == '*') {                   /* dynamic precision */
73                sprintf(fmtp, "%d", va_arg(ap, int));
74                fmtp += strlen(fmtp);
75                cp++;
76            } else {
77                while (isdigit(*cp))            /* hard-coded precision */
78                    *fmtp++ = *cp++;
79            }
80            if (*cp == 'l')                     /* long whatever */
81                *fmtp++ = *cp++;
82            if (*cp == 0)                       /* premature end, punt */
83                break;
84            *fmtp++ = *cp;                      /* type (checked below) */
85            *fmtp = 0;
86
87            /* Execute the format string - let fprintf() do the hard work. */
88
89            switch (fmtp[-1]) {
90            case 's':                           /* string-valued argument */
91                count += fprintf(fp, fmt, va_arg(ap, char *));
92                break;
93            case 'c':                           /* integral-valued argument */
94            case 'd':
95            case 'u':
96            case 'o':
97            case 'x':
98                if (fmtp[-2] == 'l')
99                    count += fprintf(fp, fmt, va_arg(ap, long));
100                else
101                    count += fprintf(fp, fmt, va_arg(ap, int));
102                break;
103            case 'e':                           /* float-valued argument */
104            case 'f':
105            case 'g':
106                count += fprintf(fp, fmt, va_arg(ap, double));
107                break;
108            default:                            /* anything else */
109                putc(fmtp[-1], fp);
110                count++;
111                break;
112            }
113        }
114    }
115    return (count);
116}
117
118/* vprintf - print variable-length argument list to stdout */
119
120vprintf(format, ap)
121char   *format;
122va_list ap;
123{
124    return (vfprintf(stdout, format, ap));
125}
Note: See TracBrowser for help on using the repository browser.