home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dmake40.zip / unix / coherent / vfprintf.c < prev   
C/C++ Source or Header  |  1994-10-23  |  5KB  |  191 lines

  1. /* Portable vfprintf and vprintf by Robert A. Larson <blarson@skat.usc.edu> */
  2.  
  3. /* Copyright 1989 Robert A. Larson.
  4.  * Distribution in any form is allowed as long as the author
  5.  * retains credit, changes are noted by their author and the
  6.  * copyright message remains intact.  This program comes as-is
  7.  * with no warentee of fitness for any purpouse.
  8.  *
  9.  * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
  10.  * the ansi printf specs.
  11.  *
  12.  * Please send any bug fixes and improvments to blarson@skat.usc.edu .
  13.  * The use of goto is NOT a bug.
  14.  */
  15.  
  16. /* Feb    9, 1989        blarson        First usenet release */
  17.  
  18. /* This code implements the vfprintf function, without relying on
  19.  * the existance of _doprint or other system specific code.
  20.  *
  21.  * Define NOVOID if void * is not a supported type.
  22.  *
  23.  * Two compile options are available for efficency:
  24.  *    INTSPRINTF    should be defined if sprintf is int and returns
  25.  *            the number of chacters formated.
  26.  *    LONGINT        should be defined if sizeof(long) == sizeof(int)
  27.  *
  28.  *    They only make the code smaller and faster, they need not be
  29.  *    defined.
  30.  *
  31.  * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
  32.  * than int in argument passing.  If this is definded, and LONGINT is not,
  33.  * the compiler must support the type unsingned long.
  34.  *
  35.  * Most quirks and bugs of the available fprintf fuction are duplicated,
  36.  * however * in the width and precision fields will work correctly
  37.  * even if fprintf does not support this.  The %n format and the return
  38.  * count will only work if fprintf returns the number of characters
  39.  * formatted.
  40.  *
  41.  * Bad format strings, or those with very long width and precision
  42.  * fields (including expanded * fields) will cause undesired results.
  43.  */
  44.  
  45. #ifdef OSK        /* os9/68k can take advantage of both */
  46. #define INTSPRINTF
  47. #define LONGINT
  48. #endif
  49. #define NOVOID 1
  50.  
  51. /* This must be a typedef not a #define! */
  52. #ifdef NOVOID
  53. typedef char *pointer;
  54. #else
  55. typedef void *pointer;
  56. #endif
  57.  
  58. #include <stdio.h>
  59.  
  60. #ifdef    INTSPRINTF
  61. #define Sprintf(string,format,arg)    (sprintf((string),(format),(arg)))
  62. #else
  63. #define Sprintf(string,format,arg)    (\
  64.     sprintf((string),(format),(arg)),\
  65.     strlen(string)\
  66. )
  67. #endif
  68.  
  69. #include <stdarg.h>
  70.  
  71. typedef int *intp;
  72.  
  73. int vfprintf(dest, format, args)
  74. FILE *dest;
  75. register char *format;
  76. va_list args;
  77. {
  78.     register char c;
  79.     register char *tp;
  80.     register int count = 0;
  81.     char tempfmt[64];
  82. #ifndef LONGINT
  83.     int longflag;
  84. #endif
  85.  
  86.     tempfmt[0] = '%';
  87.     while(c = *format++) {
  88.     if(c=='%') {
  89.         tp = &tempfmt[1];
  90. #ifndef LONGINT
  91.         longflag = 0;
  92. #endif
  93. continue_format:
  94.         switch(c = *format++) {
  95.         case 's':
  96.             *tp++ = c;
  97.             *tp = '\0';
  98.             count += fprintf(dest, tempfmt, va_arg(args, char *));
  99.             break;
  100.         case 'u':
  101.         case 'x':
  102.         case 'o':
  103.         case 'X':
  104. #ifdef UNSIGNEDSPECIAL
  105.             *tp++ = c;
  106.             *tp = '\0';
  107. #ifndef LONGINT
  108.             if(longflag)
  109.             count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
  110.             else
  111. #endif
  112.             count += fprintf(dest, tempfmt, va_arg(args, unsigned));
  113.             break;
  114. #endif
  115.         case 'd':
  116.         case 'c':
  117.         case 'i':
  118.             *tp++ = c;
  119.             *tp = '\0';
  120. #ifndef LONGINT
  121.             if(longflag)
  122.             count += fprintf(dest, tempfmt, va_arg(args, long));
  123.             else
  124. #endif
  125.             count += fprintf(dest, tempfmt, va_arg(args, int));
  126.             break;
  127.         case 'f':
  128.         case 'e':
  129.         case 'E':
  130.         case 'g':
  131.         case 'G':
  132.             *tp++ = c;
  133.             *tp = '\0';
  134.             count += fprintf(dest, tempfmt, va_arg(args, double));
  135.             break;
  136.         case 'p':
  137.             *tp++ = c;
  138.             *tp = '\0';
  139.             count += fprintf(dest, tempfmt, va_arg(args, pointer));
  140.             break;
  141.         case '-':
  142.         case '+':
  143.         case '0':
  144.         case '1':
  145.         case '2':
  146.         case '3':
  147.         case '4':
  148.         case '5':
  149.         case '6':
  150.         case '7':
  151.         case '8':
  152.         case '9':
  153.         case '.':
  154.         case ' ':
  155.         case '#':
  156.         case 'h':
  157.             *tp++ = c;
  158.             goto continue_format;
  159.         case 'l':
  160. #ifndef LONGINT
  161.             longflag = 1;
  162.             *tp++ = c;
  163. #endif
  164.             goto continue_format;
  165.         case '*':
  166.             tp += Sprintf(tp, "%d", va_arg(args, int));
  167.             goto continue_format;
  168.         case 'n':
  169.             *va_arg(args, intp) = count;
  170.             break;
  171.         case '%':
  172.         default:
  173.             putc(c, dest);
  174.             count++;
  175.             break;
  176.         }
  177.     } else {
  178.         putc(c, dest);
  179.         count++;
  180.     }
  181.     }
  182.     return count;
  183. }
  184.  
  185. vprintf(format, args)
  186. char *format;
  187. va_list args;
  188. {
  189.     return vfprintf(stdout, format, args);
  190. }
  191.