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.
6 * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
10 static char sccsid[] = "@(#) vfprintf.c 1.2 94/03/23 17:44:46";
21 /* vfprintf - print variable-length argument list to stream */
23 int vfprintf(FILE *fp, char *format, va_list ap)
25 char fmt[BUFSIZ]; /* format specifier */
31 * Iterate over characters in the format string, picking up arguments
32 * when format specifiers are found.
35 for (cp = format; *cp; cp++) {
37 putc(*cp, fp); /* ordinary character */
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:
48 * %-?0?([0-9]+|\*)?\.?([0-9]+|\*)?l?[a-z]
50 * which includes some combinations that do not make sense.
55 if (*cp == '-') /* left-adjusted field? */
57 if (*cp == '0') /* zero-padded field? */
59 if (*cp == '*') { /* dynamic field witdh */
60 sprintf(fmtp, "%d", va_arg(ap, int));
64 while (isdigit(*cp)) /* hard-coded field width */
67 if (*cp == '.') /* width/precision separator */
69 if (*cp == '*') { /* dynamic precision */
70 sprintf(fmtp, "%d", va_arg(ap, int));
74 while (isdigit(*cp)) /* hard-coded precision */
77 if (*cp == 'l') /* long whatever */
79 if (*cp == 0) /* premature end, punt */
81 *fmtp++ = *cp; /* type (checked below) */
84 /* Execute the format string - let fprintf() do the hard work. */
87 case 's': /* string-valued argument */
88 count += fprintf(fp, fmt, va_arg(ap, char *));
90 case 'c': /* integral-valued argument */
96 count += fprintf(fp, fmt, va_arg(ap, long));
98 count += fprintf(fp, fmt, va_arg(ap, int));
100 case 'e': /* float-valued argument */
103 count += fprintf(fp, fmt, va_arg(ap, double));
105 default: /* anything else */
115 /* vprintf - print variable-length argument list to stdout */
117 vprintf(char *format, va_list ap)
119 return (vfprintf(stdout, format, ap));