diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/tcpd/vfprintf.c | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/tcpd/vfprintf.c')
-rw-r--r-- | usr/src/cmd/tcpd/vfprintf.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/usr/src/cmd/tcpd/vfprintf.c b/usr/src/cmd/tcpd/vfprintf.c new file mode 100644 index 0000000000..d6f37d59bf --- /dev/null +++ b/usr/src/cmd/tcpd/vfprintf.c @@ -0,0 +1,125 @@ + /* + * vfprintf() and vprintf() clones. They will produce unexpected results + * when excessive dynamic ("*") field widths are specified. To be used for + * testing purposes only. + * + * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. + */ + +#ifndef lint +static char sccsid[] = "@(#) vfprintf.c 1.2 94/03/23 17:44:46"; +#endif + +#include <stdio.h> +#include <ctype.h> +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +/* vfprintf - print variable-length argument list to stream */ + +int vfprintf(fp, format, ap) +FILE *fp; +char *format; +va_list ap; +{ + char fmt[BUFSIZ]; /* format specifier */ + register char *fmtp; + register char *cp; + int count = 0; + + /* + * Iterate over characters in the format string, picking up arguments + * when format specifiers are found. + */ + + for (cp = format; *cp; cp++) { + if (*cp != '%') { + putc(*cp, fp); /* ordinary character */ + count++; + } else { + + /* + * Format specifiers are handled one at a time, since we can only + * deal with arguments one at a time. Try to determine the end of + * the format specifier. We do not attempt to fully parse format + * strings, since we are ging to let fprintf() do the hard work. + * In regular expression notation, we recognize: + * + * %-?0?([0-9]+|\*)?\.?([0-9]+|\*)?l?[a-z] + * + * which includes some combinations that do not make sense. + */ + + fmtp = fmt; + *fmtp++ = *cp++; + if (*cp == '-') /* left-adjusted field? */ + *fmtp++ = *cp++; + if (*cp == '0') /* zero-padded field? */ + *fmtp++ = *cp++; + if (*cp == '*') { /* dynamic field witdh */ + sprintf(fmtp, "%d", va_arg(ap, int)); + fmtp += strlen(fmtp); + cp++; + } else { + while (isdigit(*cp)) /* hard-coded field width */ + *fmtp++ = *cp++; + } + if (*cp == '.') /* width/precision separator */ + *fmtp++ = *cp++; + if (*cp == '*') { /* dynamic precision */ + sprintf(fmtp, "%d", va_arg(ap, int)); + fmtp += strlen(fmtp); + cp++; + } else { + while (isdigit(*cp)) /* hard-coded precision */ + *fmtp++ = *cp++; + } + if (*cp == 'l') /* long whatever */ + *fmtp++ = *cp++; + if (*cp == 0) /* premature end, punt */ + break; + *fmtp++ = *cp; /* type (checked below) */ + *fmtp = 0; + + /* Execute the format string - let fprintf() do the hard work. */ + + switch (fmtp[-1]) { + case 's': /* string-valued argument */ + count += fprintf(fp, fmt, va_arg(ap, char *)); + break; + case 'c': /* integral-valued argument */ + case 'd': + case 'u': + case 'o': + case 'x': + if (fmtp[-2] == 'l') + count += fprintf(fp, fmt, va_arg(ap, long)); + else + count += fprintf(fp, fmt, va_arg(ap, int)); + break; + case 'e': /* float-valued argument */ + case 'f': + case 'g': + count += fprintf(fp, fmt, va_arg(ap, double)); + break; + default: /* anything else */ + putc(fmtp[-1], fp); + count++; + break; + } + } + } + return (count); +} + +/* vprintf - print variable-length argument list to stdout */ + +vprintf(format, ap) +char *format; +va_list ap; +{ + return (vfprintf(stdout, format, ap)); +} |