home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / tcp_wrapper-6.3 / vfprintf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-27  |  3.1 KB  |  126 lines

  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(fp, format, ap)
  24. FILE   *fp;
  25. char   *format;
  26. va_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.  
  120. vprintf(format, ap)
  121. char   *format;
  122. va_list ap;
  123. {
  124.     return (vfprintf(stdout, format, ap));
  125. }
  126.