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