home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / vsprintf.port < prev    next >
Text File  |  1989-03-04  |  12KB  |  462 lines

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