home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume06 / vsprintf.prt < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  11.6 KB

  1. From decwrl!wyse!uunet!allbery Fri Mar 24 22:23:15 PST 1989
  2. Article 811 of comp.sources.misc:
  3. Path: decwrl!wyse!uunet!allbery
  4. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5. Newsgroups: comp.sources.misc
  6. Subject: v06i042: portable v*printf
  7. Message-ID: <8902100417.AA18647@skat.usc.edu>
  8. Date: 4 Mar 89 21:19:25 GMT
  9. Sender: allbery@uunet.UU.NET
  10. Reply-To: blarson%skat.usc.edu@oberon.usc.edu (Bob Larson)
  11. Organization: USC AIS, Los Angeles
  12. Lines: 454
  13. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  14.  
  15. Posting-number: Volume 6, Issue 42
  16. Submitted-by: blarson%skat.usc.edu@oberon.usc.edu (Bob Larson)
  17. Archive-name: vsprintf.port
  18.  
  19. [That, and a few other things....  ++bsa]
  20.  
  21. Here is the portable vsprinf function I promised.  Uunet had a
  22. problem with their comp-source-misc sumbission address, so this
  23. is a bit late, but it now includes vfprintf and vprintf.  No
  24. makefile is included since this was developted on and for a non-
  25. unix system, (os9/68k) but it should be portable to almost anything
  26. with a working varargs and sprintf/fprintf.
  27.  
  28. #    This is a shell archive.
  29. #    Remove everything above and including the cut line.
  30. #    Then run the rest of the file through sh.
  31. #----cut here-----cut here-----cut here-----cut here----#
  32. #!/bin/sh
  33. # shar:    Shell Archiver
  34. #    Run the following text with /bin/sh to create:
  35. #    vsprintf.doc
  36. #    vsprintf.c
  37. #    vfprintf.c
  38. # This archive created: Thu Feb  9 20:06:13 1989
  39. # By:    blarson
  40. cat << \SHAR_EOF > vsprintf.doc
  41. Portable vsprintf, vfprintf, and vprintf  by Robert A. Larson
  42.     <blarson@skat.usc.edu>
  43.  
  44. Copyright 1989 Robert A. Larson.
  45. Distribution in any form is allowed as long as the author
  46. retains credit, changes are noted by their author and the
  47. copyright message remains intact.  This program comes as-is
  48. with no warentee of fitness for any purpouse.
  49.  
  50. Thanks to Doug Gwen, Chris Torek, and others who helped clarify
  51. the ansi printf specs.
  52.  
  53. Please send any bug fixes and improvments to blarson@skat.usc.edu .
  54. The use of goto is NOT a bug.
  55.  
  56.  
  57. Feb  9, 1989        blarson        First usenet release
  58.  
  59. This code implements the vsprintf function, without relying on
  60. the existance of _doprint or other system specific code.
  61.  
  62. Define NOVOID if void * is not a supported type.
  63.  
  64. Two compile options are available for efficency:
  65.     INTSPRINTF    should be defined if sprintf is int and returns
  66.             the number of chacters formated.
  67.     LONGINT        should be defined if sizeof(long) == sizeof(int)
  68.  
  69.     They only make the code smaller and faster, they need not be 
  70.     defined.
  71.  
  72. UNSIGNEDSPECIAL should be defined if unsigned is treated differently
  73. than int in argument passing.  If this is definded, and LONGINT is not,
  74. the compiler must support the type unsigned long.
  75.  
  76. Most quirks and bugs of the available sprintf and fprintf fuction are
  77. duplicated, however * in the width and precision fields will work
  78. correctly even if sprintf does not support this, and the %n format
  79. will always work in vsprintf.  %n and return count will work properly
  80. in vfprintf and vprintf only if fprintf returns the number of
  81. characters formatted.
  82.  
  83. Bad format strings, or those with very long width and precision
  84. fields (including expanded * fields) will cause undesired results.
  85. SHAR_EOF
  86. cat << \SHAR_EOF > vsprintf.c
  87. /* Portable vsprintf  by Robert A. Larson <blarson@skat.usc.edu> */
  88.  
  89. /* Copyright 1989 Robert A. Larson.
  90.  * Distribution in any form is allowed as long as the author
  91.  * retains credit, changes are noted by their author and the
  92.  * copyright message remains intact.  This program comes as-is
  93.  * with no warentee of fitness for any purpouse.
  94.  *
  95.  * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
  96.  * the ansi printf specs.
  97.  *
  98.  * Please send any bug fixes and improvments to blarson@skat.usc.edu .
  99.  * The use of goto is NOT a bug.
  100.  */
  101.  
  102. /* Feb    7, 1989        blarson        First usenet release */
  103.  
  104. /* This code implements the vsprintf function, without relying on
  105.  * the existance of _doprint or other system specific code.
  106.  *
  107.  * Define NOVOID if void * is not a supported type.
  108.  *
  109.  * Two compile options are available for efficency:
  110.  *    INTSPRINTF    should be defined if sprintf is int and returns
  111.  *            the number of chacters formated.
  112.  *    LONGINT        should be defined if sizeof(long) == sizeof(int)
  113.  *
  114.  *    They only make the code smaller and faster, they need not be
  115.  *    defined.
  116.  *
  117.  * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
  118.  * than int in argument passing.  If this is definded, and LONGINT is not,
  119.  * the compiler must support the type unsingned long.
  120.  *
  121.  * Most quirks and bugs of the available sprintf fuction are duplicated,
  122.  * however * in the width and precision fields will work correctly
  123.  * even if sprintf does not support this, as will the n format.
  124.  *
  125.  * Bad format strings, or those with very long width and precision
  126.  * fields (including expanded * fields) will cause undesired results.
  127.  */
  128.  
  129. #ifdef OSK        /* os9/68k can take advantage of both */
  130. #define LONGINT
  131. #define INTSPRINTF
  132. #endif
  133.  
  134. /* This must be a typedef not a #define! */
  135. #ifdef NOVOID
  136. typedef char *pointer;
  137. #else
  138. typedef void *pointer;
  139. #endif
  140.  
  141. #ifdef    INTSPRINTF
  142. #define Sprintf(string,format,arg)    (sprintf((string),(format),(arg)))
  143. #else
  144. #define Sprintf(string,format,arg)    (\
  145.     sprintf((string),(format),(arg)),\
  146.     strlen(string)\
  147. )
  148. #endif
  149.  
  150. #ifdef __STDC__
  151. #include <stdarg.h>
  152. #else
  153. #include <varargs.h>
  154. #endif
  155.  
  156. typedef int *intp;
  157.  
  158. int vsprintf(dest, format, args)
  159. char *dest;
  160. register char *format;
  161. va_list args;
  162. {
  163.     register char *dp = dest;
  164.     register char c;
  165.     register char *tp;
  166.     char tempfmt[64];
  167. #ifndef LONGINT
  168.     int longflag;
  169. #endif
  170.  
  171.     tempfmt[0] = '%';
  172.     while(c = *format++) {
  173.     if(c=='%') {
  174.         tp = &tempfmt[1];
  175. #ifndef LONGINT
  176.         longflag = 0;
  177. #endif
  178. continue_format:
  179.         switch(c = *format++) {
  180.         case 's':
  181.             *tp++ = c;
  182.             *tp = '\0';
  183.             dp += Sprintf(dp, tempfmt, va_arg(args, char *));
  184.             break;
  185.         case 'u':
  186.         case 'x':
  187.         case 'o':
  188.         case 'X':
  189. #ifdef UNSIGNEDSPECIAL
  190.             *tp++ = c;
  191.             *tp = '\0';
  192. #ifndef LONGINT
  193.             if(longflag)
  194.             dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
  195.             else
  196. #endif
  197.             dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
  198.             break;
  199. #endif
  200.         case 'd':
  201.         case 'c':
  202.         case 'i':
  203.             *tp++ = c;
  204.             *tp = '\0';
  205. #ifndef LONGINT
  206.             if(longflag)
  207.             dp += Sprintf(dp, tempfmt, va_arg(args, long));
  208.             else
  209. #endif
  210.             dp += Sprintf(dp, tempfmt, va_arg(args, int));
  211.             break;
  212.         case 'f':
  213.         case 'e':
  214.         case 'E':
  215.         case 'g':
  216.         case 'G':
  217.             *tp++ = c;
  218.             *tp = '\0';
  219.             dp += Sprintf(dp, tempfmt, va_arg(args, double));
  220.             break;
  221.         case 'p':
  222.             *tp++ = c;
  223.             *tp = '\0';
  224.             dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
  225.             break;
  226.         case '-':
  227.         case '+':
  228.         case '0':
  229.         case '1':
  230.         case '2':
  231.         case '3':
  232.         case '4':
  233.         case '5':
  234.         case '6':
  235.         case '7':
  236.         case '8':
  237.         case '9':
  238.         case '.':
  239.         case ' ':
  240.         case '#':
  241.         case 'h':
  242.             *tp++ = c;
  243.             goto continue_format;
  244.         case 'l':
  245. #ifndef LONGINT
  246.             longflag = 1;
  247.             *tp++ = c;
  248. #endif
  249.             goto continue_format;
  250.         case '*':
  251.             tp += Sprintf(tp, "%d", va_arg(args, int));
  252.             goto continue_format;
  253.         case 'n':
  254.             *va_arg(args, intp) = dp - dest;
  255.             break;
  256.         case '%':
  257.         default:
  258.             *dp++ = c;
  259.             break;
  260.         }
  261.     } else *dp++ = c;
  262.     }
  263.     *dp = '\0';
  264.     return dp - dest;
  265. }
  266. SHAR_EOF
  267. cat << \SHAR_EOF > vfprintf.c
  268. /* Portable vfprintf and vprintf by Robert A. Larson <blarson@skat.usc.edu> */
  269.  
  270. /* Copyright 1989 Robert A. Larson.
  271.  * Distribution in any form is allowed as long as the author
  272.  * retains credit, changes are noted by their author and the
  273.  * copyright message remains intact.  This program comes as-is
  274.  * with no warentee of fitness for any purpouse.
  275.  *
  276.  * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
  277.  * the ansi printf specs.
  278.  *
  279.  * Please send any bug fixes and improvments to blarson@skat.usc.edu .
  280.  * The use of goto is NOT a bug.
  281.  */
  282.  
  283. /* Feb    9, 1989        blarson        First usenet release */
  284.  
  285. /* This code implements the vfprintf function, without relying on
  286.  * the existance of _doprint or other system specific code.
  287.  *
  288.  * Define NOVOID if void * is not a supported type.
  289.  *
  290.  * Two compile options are available for efficency:
  291.  *    INTSPRINTF    should be defined if sprintf is int and returns
  292.  *            the number of chacters formated.
  293.  *    LONGINT        should be defined if sizeof(long) == sizeof(int)
  294.  *
  295.  *    They only make the code smaller and faster, they need not be
  296.  *    defined.
  297.  *
  298.  * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
  299.  * than int in argument passing.  If this is definded, and LONGINT is not,
  300.  * the compiler must support the type unsingned long.
  301.  *
  302.  * Most quirks and bugs of the available fprintf fuction are duplicated,
  303.  * however * in the width and precision fields will work correctly
  304.  * even if fprintf does not support this.  The %n format and the return
  305.  * count will only work if fprintf returns the number of characters
  306.  * formatted.
  307.  *
  308.  * Bad format strings, or those with very long width and precision
  309.  * fields (including expanded * fields) will cause undesired results.
  310.  */
  311.  
  312. #ifdef OSK        /* os9/68k can take advantage of both */
  313. #define INTSPRINTF
  314. #define LONGINT
  315. #endif
  316.  
  317. /* This must be a typedef not a #define! */
  318. #ifdef NOVOID
  319. typedef char *pointer;
  320. #else
  321. typedef void *pointer;
  322. #endif
  323.  
  324. #include <stdio.h>
  325.  
  326. #ifdef    INTSPRINTF
  327. #define Sprintf(string,format,arg)    (sprintf((string),(format),(arg)))
  328. #else
  329. #define Sprintf(string,format,arg)    (\
  330.     sprintf((string),(format),(arg)),\
  331.     strlen(string)\
  332. )
  333. #endif
  334.  
  335. #ifdef __STDC__
  336. #include <stdarg.h>
  337. #else
  338. #include <varargs.h>
  339. #endif
  340.  
  341. typedef int *intp;
  342.  
  343. int vfprintf(dest, format, args)
  344. FILE *dest;
  345. register char *format;
  346. va_list args;
  347. {
  348.     register char c;
  349.     register char *tp;
  350.     register int count = 0;
  351.     char tempfmt[64];
  352. #ifndef LONGINT
  353.     int longflag;
  354. #endif
  355.  
  356.     tempfmt[0] = '%';
  357.     while(c = *format++) {
  358.     if(c=='%') {
  359.         tp = &tempfmt[1];
  360. #ifndef LONGINT
  361.         longflag = 0;
  362. #endif
  363. continue_format:
  364.         switch(c = *format++) {
  365.         case 's':
  366.             *tp++ = c;
  367.             *tp = '\0';
  368.             count += fprintf(dest, tempfmt, va_arg(args, char *));
  369.             break;
  370.         case 'u':
  371.         case 'x':
  372.         case 'o':
  373.         case 'X':
  374. #ifdef UNSIGNEDSPECIAL
  375.             *tp++ = c;
  376.             *tp = '\0';
  377. #ifndef LONGINT
  378.             if(longflag)
  379.             count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
  380.             else
  381. #endif
  382.             count += fprintf(dest, tempfmt, va_arg(args, unsigned));
  383.             break;
  384. #endif
  385.         case 'd':
  386.         case 'c':
  387.         case 'i':
  388.             *tp++ = c;
  389.             *tp = '\0';
  390. #ifndef LONGINT
  391.             if(longflag)
  392.             count += fprintf(dest, tempfmt, va_arg(args, long));
  393.             else
  394. #endif
  395.             count += fprintf(dest, tempfmt, va_arg(args, int));
  396.             break;
  397.         case 'f':
  398.         case 'e':
  399.         case 'E':
  400.         case 'g':
  401.         case 'G':
  402.             *tp++ = c;
  403.             *tp = '\0';
  404.             count += fprintf(dest, tempfmt, va_arg(args, double));
  405.             break;
  406.         case 'p':
  407.             *tp++ = c;
  408.             *tp = '\0';
  409.             count += fprintf(dest, tempfmt, va_arg(args, pointer));
  410.             break;
  411.         case '-':
  412.         case '+':
  413.         case '0':
  414.         case '1':
  415.         case '2':
  416.         case '3':
  417.         case '4':
  418.         case '5':
  419.         case '6':
  420.         case '7':
  421.         case '8':
  422.         case '9':
  423.         case '.':
  424.         case ' ':
  425.         case '#':
  426.         case 'h':
  427.             *tp++ = c;
  428.             goto continue_format;
  429.         case 'l':
  430. #ifndef LONGINT
  431.             longflag = 1;
  432.             *tp++ = c;
  433. #endif
  434.             goto continue_format;
  435.         case '*':
  436.             tp += Sprintf(tp, "%d", va_arg(args, int));
  437.             goto continue_format;
  438.         case 'n':
  439.             *va_arg(args, intp) = count;
  440.             break;
  441.         case '%':
  442.         default:
  443.             putc(c, dest);
  444.             count++;
  445.             break;
  446.         }
  447.     } else {
  448.         putc(c, dest);
  449.         count++;
  450.     }
  451.     }
  452.     return count;
  453. }
  454.  
  455. vprintf(format, args)
  456. char *format;
  457. va_list args;
  458. {
  459.     return vfprintf(stdout, format, args);
  460. }
  461. SHAR_EOF
  462. #    End of shell archive
  463. exit 0
  464. -- 
  465. Bob Larson    Arpa: Blarson@Ecla.Usc.Edu    blarson@skat.usc.edu
  466. Uucp: {sdcrdcf,cit-vax}!oberon!skat!blarson
  467. Prime mailing list:    info-prime-request%ais1@ecla.usc.edu
  468.             oberon!ais1!info-prime-request
  469.  
  470.  
  471.