]> pd.if.org Git - pdclib/blob - functions/stdio/vfprintf.c
Merged PDPCLIB and Therx code.
[pdclib] / functions / stdio / vfprintf.c
1 // ----------------------------------------------------------------------------
2 // $Id$
3 // ----------------------------------------------------------------------------
4 // Public Domain C Library - http://pdclib.sourceforge.net
5 // This code is Public Domain. Use, modify, and redistribute at will.
6 // ----------------------------------------------------------------------------
7
8 int vfprintf( FILE * restrict stream, const char * restrict format, va_list ap ) { /* TODO */ };
9
10 /* PDPC code - unreviewed
11 {
12     int ret;
13
14     ret = vvprintf(format, arg, stream, NULL);
15     return (ret);
16 }
17
18 {
19     int fin = 0;
20     int vint;
21     char *vcptr;
22     int chcount = 0;
23     size_t len;
24     char numbuf[50];
25     char *nptr;
26
27     while (!fin)
28     {
29         if (*format == '\0')
30         {
31             fin = 1;
32         }
33         else if (*format == '%')
34         {
35             format++;
36             if (*format == 'd')
37             {
38                 int neg = 0;
39
40                 vint = va_arg(arg, int);
41                 if (vint < 0)
42                 {
43                     neg = 1;
44                     vint = -vint;
45                 }
46                 nptr = numbuf;
47                 do
48                 {
49                     *nptr++ = (char)('0' + vint % 10);
50                     vint /= 10;
51                 } while (vint > 0);
52                 if (neg)
53                 {
54                     *nptr++ = '-';
55                 }
56                 do
57                 {
58                     nptr--;
59                     outch(*nptr);
60                     chcount++;
61                 } while (nptr != numbuf);
62             }
63             else if (*format == 's')
64             {
65                 vcptr = va_arg(arg, char *);
66                 if (fq == NULL)
67                 {
68                     len = strlen(vcptr);
69                     memcpy(s, vcptr, len);
70                     s += len;
71                     chcount += len;
72                 }
73                 else
74                 {
75                     fputs(vcptr, fq);
76                     chcount += strlen(vcptr);
77                 }
78             }
79             else if (*format == 'c')
80             {
81                 vint = va_arg(arg, int);
82                 outch(vint);
83                 chcount++;
84             }
85             else if (*format == '%')
86             {
87                 outch('%');
88                 chcount++;
89             }
90             else
91             {
92                 int extraCh;
93
94                 extraCh = examine(&format, fq, s, &arg, chcount);
95                 chcount += extraCh;
96                 if (s != NULL)
97                 {
98                     s += extraCh;
99                 }
100             }
101         }
102         else
103         {
104             outch(*format);
105             chcount++;
106         }
107         format++;
108     }
109     return (chcount);
110 }
111
112 static int examine(const char **formt, FILE *fq, char *s, va_list *arg,
113                    int chcount)
114 {
115     int extraCh = 0;
116     int flagMinus = 0;
117     int flagPlus = 0;
118     int flagSpace = 0;
119     int flagHash = 0;
120     int flagZero = 0;
121     int width = 0;
122     int precision = -1;
123     int half = 0;
124     int lng = 0;
125     int specifier = 0;
126     int fin;
127     long lvalue;
128     unsigned long ulvalue;
129     char *svalue;
130     char work[50];
131     int x;
132     int y;
133     int rem;
134     const char *format;
135     int base;
136     int fillCh;
137     int neg;
138     int length;
139
140     unused(chcount);
141     format = *formt;
142     /* processing flags */
143     fin = 0;
144     while (!fin)
145     {
146         switch (*format)
147         {
148             case '-': flagMinus = 1;
149                       break;
150             case '+': flagPlus = 1;
151                       break;
152             case ' ': flagSpace = 1;
153                       break;
154             case '#': flagHash = 1;
155                       break;
156             case '0': flagZero = 1;
157                       break;
158             default:  fin = 1;
159                       break;
160         }
161         if (!fin)
162         {
163             format++;
164         }
165         else
166         {
167             if (flagSpace && flagPlus)
168             {
169                 flagSpace = 0;
170             }
171             if (flagMinus)
172             {
173                 flagZero = 0;
174             }
175         }
176     }
177
178     /* processing width */
179     if (isdigit((unsigned char)*format))
180     {
181         while (isdigit((unsigned char)*format))
182         {
183             width = width * 10 + (*format - '0');
184             format++;
185         }
186     }
187
188     /* processing precision */
189     if (*format == '.')
190     {
191         format++;
192         precision = 0;
193         while (isdigit((unsigned char)*format))
194         {
195             precision = precision * 10 + (*format - '0');
196             format++;
197         }
198     }
199
200     /* processing h/l/L */
201     if (*format == 'h')
202     {
203         half = 1;
204     }
205     else if (*format == 'l')
206     {
207         lng = 1;
208     }
209     else if (*format == 'L')
210     {
211         lng = 1;
212     }
213     else
214     {
215         format--;
216     }
217     format++;
218
219     if (precision < 0)
220     {
221         precision = 1;
222     }
223     /* processing specifier */
224     specifier = *format;
225
226     if (strchr("dxXuiop", specifier) != NULL)
227     {
228 #if defined(__MSDOS__) && !defined(__PDOS__)
229         if (specifier == 'p')
230         {
231             lng = 1;
232         }
233 #endif
234         if (lng)
235         {
236             lvalue = va_arg(*arg, long);
237         }
238         else if (half)
239         {
240             lvalue = va_arg(*arg, short);
241         }
242         else
243         {
244             lvalue = va_arg(*arg, int);
245         }
246         ulvalue = (unsigned long)lvalue;
247         if ((lvalue < 0) && ((specifier == 'd') || (specifier == 'i')))
248         {
249             neg = 1;
250             ulvalue = -lvalue;
251         }
252         else
253         {
254             neg = 0;
255         }
256         if ((specifier == 'X') || (specifier == 'x') || (specifier == 'p'))
257         {
258             base = 16;
259         }
260         else if (specifier == 'o')
261         {
262             base = 8;
263         }
264         else
265         {
266             base = 10;
267         }
268         if (specifier == 'p')
269         {
270 #if defined(__OS2__) || defined(__PDOS__)
271             precision = 8;
272 #endif
273 #if defined(__MSDOS__) && !defined(__PDOS__)
274             precision = 9;
275 #endif
276         }
277         x = 0;
278         while (ulvalue > 0)
279         {
280             rem = (int)(ulvalue % base);
281             if (rem < 10)
282             {
283                 work[x] = (char)('0' + rem);
284             }
285             else
286             {
287                 if ((specifier == 'X') || (specifier == 'p'))
288                 {
289                     work[x] = (char)('A' + (rem - 10));
290                 }
291                 else
292                 {
293                     work[x] = (char)('a' + (rem - 10));
294                 }
295             }
296             x++;
297 #if defined(__MSDOS__) && !defined(__PDOS__)
298             if ((x == 4) && (specifier == 'p'))
299             {
300                 work[x] = ':';
301                 x++;
302             }
303 #endif
304             ulvalue = ulvalue / base;
305         }
306         while (x < precision)
307         {
308             work[x] = '0';
309             x++;
310         }
311         if (neg)
312         {
313             work[x++] = '-';
314         }
315         if (flagZero)
316         {
317             fillCh = '0';
318         }
319         else
320         {
321             fillCh = ' ';
322         }
323         y = x;
324         if (!flagMinus)
325         {
326             while (y < width)
327             {
328                 outch(fillCh);
329                 extraCh++;
330                 y++;
331             }
332         }
333         if (flagHash && (toupper(specifier) == 'X'))
334         {
335             outch('0');
336             outch('x');
337             extraCh += 2;
338         }
339         x--;
340         while (x >= 0)
341         {
342             outch(work[x]);
343             extraCh++;
344             x--;
345         }
346         if (flagMinus)
347         {
348             while (y < width)
349             {
350                 outch(fillCh);
351                 extraCh++;
352                 y++;
353             }
354         }
355     }
356     else if (specifier == 's')
357     {
358         svalue = va_arg(*arg, char *);
359         fillCh = ' ';
360         if (precision > 1)
361         {
362             char *p;
363
364             p = memchr(svalue, '\0', precision);
365             if (p != NULL)
366             {
367                 length = (int)(p - svalue);
368             }
369             else
370             {
371                 length = precision;
372             }
373         }
374         else
375         {
376             length = strlen(svalue);
377         }
378         if (!flagMinus)
379         {
380             if (length < width)
381             {
382                 extraCh += (width - length);
383                 for (x = 0; x < (width - length); x++)
384                 {
385                     outch(fillCh);
386                 }
387             }
388         }
389         for (x = 0; x < length; x++)
390         {
391             outch(svalue[x]);
392         }
393         extraCh += length;
394         if (flagMinus)
395         {
396             if (length < width)
397             {
398                 extraCh += (width - length);
399                 for (x = 0; x < (width - length); x++)
400                 {
401                     outch(fillCh);
402                 }
403             }
404         }
405     }
406     *formt = format;
407     return (extraCh);
408 }
409 */