1 #include <stdio.h>
2
3 #ifdef NEED_VPRINTF
4 /* Portable vsprintf by Robert A. Larson <blarson@skat.usc.edu> */
5 /* Portable vfprintf by Robert A. Larson <blarson@skat.usc.edu> */
6
7 /* Copyright 1989 Robert A. Larson.
8 * Distribution in any form is allowed as long as the author
9 * retains credit, changes are noted by their author and the
10 * copyright message remains intact. This program comes as-is
11 * with no warentee of fitness for any purpouse.
12 *
13 * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
14 * the ansi printf specs.
15 *
16 * Please send any bug fixes and improvments to blarson@skat.usc.edu .
17 * The use of goto is NOT a bug.
18 */
19
20 /* Feb 7, 1989 blarson First usenet release */
21
22 /* This code implements the vsprintf function, without relying on
23 * the existance of _doprint or other system specific code.
24 *
25 * Define NOVOID if void * is not a supported type.
26 *
27 * Two compile options are available for efficency:
28 * INTSPRINTF should be defined if sprintf is int and returns
29 * the number of chacters formated.
30 * LONGINT should be defined if sizeof(long) == sizeof(int)
31 *
32 * They only make the code smaller and faster, they need not be
33 * defined.
34 *
35 * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
36 * than int in argument passing. If this is definded, and LONGINT is not,
37 * the compiler must support the type unsingned long.
38 *
39 * Most quirks and bugs of the available sprintf fuction are duplicated,
40 * however * in the width and precision fields will work correctly
41 * even if sprintf does not support this, as will the n format.
42 *
43 * Bad format strings, or those with very long width and precision
44 * fields (including expanded * fields) will cause undesired results.
45 */
46
47 #ifdef OSK /* os9/68k can take advantage of both */
48 #define LONGINT
49 #define INTSPRINTF
50 #endif
51
52 /* This must be a typedef not a #define! */
53 #ifdef NOVOID
54 typedef char *pointer;
55 #else
56 typedef void *pointer;
57 #endif
58
59 #ifdef INTSPRINTF
60 #define Sprintf(string,format,arg) (sprintf((string),(format),(arg)))
61 #else
62 #define Sprintf(string,format,arg) (\
63 sprintf((string),(format),(arg)),\
64 strlen(string)\
65 )
66 #endif
67
68 #if defined(__STDC__) && !defined(NOSTDHDRS)
69 #include <stdarg.h>
70 #else
71 #include <varargs.h>
72 #endif
73
74 typedef int *intp;
75
vsprintf(dest,format,args)76 int vsprintf(dest, format, args)
77 char *dest;
78 register char *format;
79 va_list args;
80 {
81 register char *dp = dest;
82 register char c;
83 register char *tp;
84 char tempfmt[64];
85 #ifndef LONGINT
86 int longflag;
87 #endif
88
89 tempfmt[0] = '%';
90 while( (c = *format++) != 0) {
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, 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 += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
113 else
114 #endif
115 dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
116 break;
117 #endif
118 case 'd':
119 case 'c':
120 case 'i':
121 *tp++ = c;
122 *tp = '\0';
123 #ifndef LONGINT
124 if(longflag)
125 dp += Sprintf(dp, tempfmt, va_arg(args, long));
126 else
127 #endif
128 dp += Sprintf(dp, tempfmt, va_arg(args, int));
129 break;
130 case 'f':
131 case 'e':
132 case 'E':
133 case 'g':
134 case 'G':
135 *tp++ = c;
136 *tp = '\0';
137 dp += Sprintf(dp, tempfmt, va_arg(args, double));
138 break;
139 case 'p':
140 *tp++ = c;
141 *tp = '\0';
142 dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
143 break;
144 case '-':
145 case '+':
146 case '0':
147 case '1':
148 case '2':
149 case '3':
150 case '4':
151 case '5':
152 case '6':
153 case '7':
154 case '8':
155 case '9':
156 case '.':
157 case ' ':
158 case '#':
159 case 'h':
160 *tp++ = c;
161 goto continue_format;
162 case 'l':
163 #ifndef LONGINT
164 longflag = 1;
165 *tp++ = c;
166 #endif
167 goto continue_format;
168 case '*':
169 tp += Sprintf(tp, "%d", va_arg(args, int));
170 goto continue_format;
171 case 'n':
172 *va_arg(args, intp) = dp - dest;
173 break;
174 case '%':
175 default:
176 *dp++ = c;
177 break;
178 }
179 } else *dp++ = c;
180 }
181 *dp = '\0';
182 return dp - dest;
183 }
184
185
vfprintf(dest,format,args)186 int vfprintf(dest, format, args)
187 FILE *dest;
188 register char *format;
189 va_list args;
190 {
191 register char c;
192 register char *tp;
193 register int count = 0;
194 char tempfmt[64];
195 #ifndef LONGINT
196 int longflag;
197 #endif
198
199 tempfmt[0] = '%';
200 while(c = *format++) {
201 if(c=='%') {
202 tp = &tempfmt[1];
203 #ifndef LONGINT
204 longflag = 0;
205 #endif
206 continue_format:
207 switch(c = *format++) {
208 case 's':
209 *tp++ = c;
210 *tp = '\0';
211 count += fprintf(dest, tempfmt, va_arg(args, char *));
212 break;
213 case 'u':
214 case 'x':
215 case 'o':
216 case 'X':
217 #ifdef UNSIGNEDSPECIAL
218 *tp++ = c;
219 *tp = '\0';
220 #ifndef LONGINT
221 if(longflag)
222 count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
223 else
224 #endif
225 count += fprintf(dest, tempfmt, va_arg(args, unsigned));
226 break;
227 #endif
228 case 'd':
229 case 'c':
230 case 'i':
231 *tp++ = c;
232 *tp = '\0';
233 #ifndef LONGINT
234 if(longflag)
235 count += fprintf(dest, tempfmt, va_arg(args, long));
236 else
237 #endif
238 count += fprintf(dest, tempfmt, va_arg(args, int));
239 break;
240 case 'f':
241 case 'e':
242 case 'E':
243 case 'g':
244 case 'G':
245 *tp++ = c;
246 *tp = '\0';
247 count += fprintf(dest, tempfmt, va_arg(args, double));
248 break;
249 case 'p':
250 *tp++ = c;
251 *tp = '\0';
252 count += fprintf(dest, tempfmt, va_arg(args, pointer));
253 break;
254 case '-':
255 case '+':
256 case '0':
257 case '1':
258 case '2':
259 case '3':
260 case '4':
261 case '5':
262 case '6':
263 case '7':
264 case '8':
265 case '9':
266 case '.':
267 case ' ':
268 case '#':
269 case 'h':
270 *tp++ = c;
271 goto continue_format;
272 case 'l':
273 #ifndef LONGINT
274 longflag = 1;
275 *tp++ = c;
276 #endif
277 goto continue_format;
278 case '*':
279 tp += Sprintf(tp, "%d", va_arg(args, int));
280 goto continue_format;
281 case 'n':
282 *va_arg(args, intp) = count;
283 break;
284 case '%':
285 default:
286 putc(c, dest);
287 count++;
288 break;
289 }
290 } else {
291 putc(c, dest);
292 count++;
293 }
294 }
295 return count;
296 }
297
vprintf(format,args)298 vprintf(format, args)
299 char *format;
300 va_list args;
301 {
302 return vfprintf(stdout, format, args);
303 }
304
305 #endif
306
307
308
309
310
311
312
313 #ifdef NEED_MEMROUTINES
314
315 #include <sys/types.h>
316
strchr(s1,c)317 char *strchr(s1,c)
318 char *s1;
319 int c;
320 {
321 char *p;
322
323 p=s1;
324 while(*p)
325 if(*(p++) == c)
326 return p-1;
327
328 return NULL;
329 }
330
331
memset(s,c,n)332 void *memset(s,c,n)
333 char *s;
334 int c;
335 size_t n;
336 {
337 char *p;
338
339 for (p=s; n--;)
340 *(p++) = c;
341
342 return;
343 }
344
345 #endif /* NEED_MEMROUTINES */
346
347