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