* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / stdio / printf.c
blobb7b0b81ece45b13449ad128e2d27a17049892876
1 /*
2 * This file based on printf.c from 'Dlibs' on the atari ST (RdeBath)
4 * 19-OCT-88: Dale Schumacher
5 * > John Stanley has again been a great help in debugging, particularly
6 * > with the printf/scanf functions which are his creation.
8 * Dale Schumacher 399 Beacon Ave.
9 * (alias: Dalnefre') St. Paul, MN 55104
10 * dal@syntel.UUCP United States of America
11 * "It's not reality that's important, but how you perceive things."
15 /* Altered to use stdarg, made the core function vfprintf.
16 * Hooked into the stdio package using 'inside information'
17 * Altered sizeof() assumptions, now assumes all integers except chars
18 * will be either
19 * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short)
21 * -RDB
24 #include <sys/types.h>
25 #include <fcntl.h>
26 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
27 #include <stdarg.h>
28 #define va_strt va_start
29 #else
30 #include <varargs.h>
31 #define va_strt(p,i) va_start(p)
32 #endif
34 #include "stdio.h"
36 #ifdef L_printf
38 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
39 int printf(const char * fmt, ...)
40 #else
41 int printf(fmt, va_alist)
42 __const char *fmt;
43 va_dcl
44 #endif
46 va_list ptr;
47 int rv;
48 va_strt(ptr, fmt);
49 rv = vfprintf(stdout,fmt,ptr);
50 va_end(ptr);
51 return rv;
53 #endif
55 #ifdef L_sprintf
56 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
57 int sprintf(char * sp, const char * fmt, ...)
58 #else
59 int sprintf(sp, fmt, va_alist)
60 char * sp;
61 __const char *fmt;
62 va_dcl
63 #endif
65 static FILE string[1] =
67 {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1,
68 _IOFBF | __MODE_WRITE}
71 va_list ptr;
72 int rv;
73 va_strt(ptr, fmt);
74 string->bufpos = sp;
75 rv = vfprintf(string,fmt,ptr);
76 va_end(ptr);
77 *(string->bufpos) = 0;
78 return rv;
80 #endif
82 #ifdef L_fprintf
83 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
84 int fprintf(FILE * fp, const char * fmt, ...)
85 #else
86 int fprintf(fp, fmt, va_alist)
87 FILE * fp;
88 __const char *fmt;
89 va_dcl
90 #endif
92 va_list ptr;
93 int rv;
94 va_strt(ptr, fmt);
95 rv = vfprintf(fp,fmt,ptr);
96 va_end(ptr);
97 return rv;
99 #endif
101 #ifdef L_vprintf
102 int vprintf(fmt, ap)
103 __const char *fmt;
104 va_list ap;
106 return vfprintf(stdout,fmt,ap);
108 #endif
110 #ifdef L_vsprintf
111 int vsprintf(sp, fmt, ap)
112 char * sp;
113 __const char *fmt;
114 va_list ap;
116 static FILE string[1] =
118 {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1,
119 _IOFBF | __MODE_WRITE}
122 int rv;
123 string->bufpos = sp;
124 rv = vfprintf(string,fmt,ap);
125 *(string->bufpos) = 0;
126 return rv;
128 #endif
130 #ifdef L_vfprintf
132 #ifndef __HAS_NO_FLOATS__
133 int (*__fp_print)() = 0;
134 #endif
136 static int
137 prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode)
138 register FILE *op;
139 register unsigned char *buf;
140 int ljustf;
141 register char sign;
142 char pad;
143 register int width;
144 int preci;
145 int buffer_mode;
147 * Output the given field in the manner specified by the arguments. Return
148 * the number of characters output.
151 register int cnt = 0, len;
152 register unsigned char ch;
154 len = strlen(buf);
156 if (*buf == '-')
157 sign = *buf++;
158 else if (sign)
159 len++;
161 if ((preci != -1) && (len > preci)) /* limit max data width */
162 len = preci;
164 if (width < len) /* flexible field width or width overflow */
165 width = len;
168 * at this point: width = total field width len = actual data width
169 * (including possible sign character)
171 cnt = width;
172 width -= len;
174 while (width || len)
176 if (!ljustf && width) /* left padding */
178 if (len && sign && (pad == '0'))
179 goto showsign;
180 ch = pad;
181 --width;
183 else if (len)
185 if (sign)
187 showsign:ch = sign; /* sign */
188 sign = '\0';
190 else
191 ch = *buf++; /* main field */
192 --len;
194 else
196 ch = pad; /* right padding */
197 --width;
199 putc(ch, op);
200 if( ch == '\n' && buffer_mode == _IOLBF ) fflush(op);
203 return (cnt);
207 vfprintf(op, fmt, ap)
208 FILE *op;
209 register __const char *fmt;
210 register va_list ap;
212 register int i, cnt = 0, ljustf, lval;
213 int preci, dpoint, width;
214 char pad, sign, radix, hash;
215 register char *ptmp;
216 char tmp[64], *ltostr(), *ultostr();
217 int buffer_mode;
219 /* This speeds things up a bit for unbuffered */
220 buffer_mode = (op->mode&__MODE_BUF);
221 op->mode &= (~__MODE_BUF);
223 while (*fmt)
225 if (*fmt == '%')
227 if( buffer_mode == _IONBF ) fflush(op);
228 ljustf = 0; /* left justify flag */
229 sign = '\0'; /* sign char & status */
230 pad = ' '; /* justification padding char */
231 width = -1; /* min field width */
232 dpoint = 0; /* found decimal point */
233 preci = -1; /* max data width */
234 radix = 10; /* number base */
235 ptmp = tmp; /* pointer to area to print */
236 hash = 0;
237 lval = (sizeof(int)==sizeof(long)); /* long value flaged */
238 fmtnxt:
239 i = 0;
240 for(;;)
242 ++fmt;
243 if(*fmt < '0' || *fmt > '9' ) break;
244 i = (i * 10) + (*fmt - '0');
245 if (dpoint)
246 preci = i;
247 else if (!i && (pad == ' '))
249 pad = '0';
250 goto fmtnxt;
252 else
253 width = i;
256 switch (*fmt)
258 case '\0': /* early EOS */
259 --fmt;
260 goto charout;
262 case '-': /* left justification */
263 ljustf = 1;
264 goto fmtnxt;
266 case ' ':
267 case '+': /* leading sign flag */
268 sign = *fmt;
269 goto fmtnxt;
271 case '*': /* parameter width value */
272 i = va_arg(ap, int);
273 if (dpoint)
274 preci = i;
275 else
276 width = i;
277 goto fmtnxt;
279 case '.': /* secondary width field */
280 dpoint = 1;
281 goto fmtnxt;
283 case 'l': /* long data */
284 lval = 1;
285 goto fmtnxt;
287 case 'h': /* short data */
288 lval = 0;
289 goto fmtnxt;
291 case 'd': /* Signed decimal */
292 case 'i':
293 ptmp = ltostr((long) ((lval)
294 ? va_arg(ap, long)
295 : va_arg(ap, short)),
296 10);
297 goto printit;
299 case 'b': /* Unsigned binary */
300 radix = 2;
301 goto usproc;
303 case 'o': /* Unsigned octal */
304 radix = 8;
305 goto usproc;
307 case 'p': /* Pointer */
308 lval = (sizeof(char*) == sizeof(long));
309 pad = '0';
310 width = 6;
311 preci = 8;
312 /* fall thru */
314 case 'x': /* Unsigned hexadecimal */
315 case 'X':
316 radix = 16;
317 /* fall thru */
319 case 'u': /* Unsigned decimal */
320 usproc:
321 ptmp = ultostr((unsigned long) ((lval)
322 ? va_arg(ap, unsigned long)
323 : va_arg(ap, unsigned short)),
324 radix);
325 if( hash && radix == 8 ) { width = strlen(ptmp)+1; pad='0'; }
326 goto printit;
328 case '#':
329 hash=1;
330 goto fmtnxt;
332 case 'c': /* Character */
333 ptmp[0] = va_arg(ap, int);
334 ptmp[1] = '\0';
335 goto nopad;
337 case 's': /* String */
338 ptmp = va_arg(ap, char*);
339 nopad:
340 sign = '\0';
341 pad = ' ';
342 printit:
343 cnt += prtfld(op, ptmp, ljustf,
344 sign, pad, width, preci, buffer_mode);
345 break;
347 #ifndef __HAS_NO_FLOATS__
348 case 'e': /* float */
349 case 'f':
350 case 'g':
351 case 'E':
352 case 'G':
353 if ( __fp_print )
355 (*__fp_print)(&va_arg(ap, double), *fmt, preci, ptmp);
356 preci = -1;
357 goto printit;
359 /* FALLTHROUGH if no floating printf available */
360 #endif
362 default: /* unknown character */
363 goto charout;
366 else
368 charout:
369 putc(*fmt, op); /* normal char out */
370 ++cnt;
371 if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op);
373 ++fmt;
375 op->mode |= buffer_mode;
376 if( buffer_mode == _IONBF ) fflush(op);
377 if( buffer_mode == _IOLBF ) op->bufwrite = op->bufstart;
378 return (cnt);
380 #endif
382 #ifdef L_fp_print
383 #ifndef __HAS_NO_FLOATS__
385 #ifdef __AS386_16__
386 #asm
387 loc 1 ! Make sure the pointer is in the correct segment
388 auto_func: ! Label for bcc -M to work.
389 .word ___xfpcvt ! Pointer to the autorun function
390 .text ! So the function after is also in the correct seg.
391 #endasm
392 #endif
394 #ifdef __AS386_32__
395 #asm
396 loc 1 ! Make sure the pointer is in the correct segment
397 auto_func: ! Label for bcc -M to work.
398 .long ___xfpcvt ! Pointer to the autorun function
399 .text ! So the function after is also in the correct seg.
400 #endasm
401 #endif
403 void
404 __fp_print_func(pval, style, preci, ptmp)
405 double * pval;
406 int style;
407 int preci;
408 char * ptmp;
410 int decpt, negative;
411 char * cvt;
412 double val = *pval;
414 if (preci < 0) preci = 6;
416 cvt = fcvt(val, preci, &decpt, &negative);
417 if(negative)
418 *ptmp++ = '-';
420 if (decpt<0) {
421 *ptmp++ = '0';
422 *ptmp++ = '.';
423 while(decpt<0) {
424 *ptmp++ = '0'; decpt++;
428 while(*cvt) {
429 *ptmp++ = *cvt++;
430 if (decpt == 1)
431 *ptmp++ = '.';
432 decpt--;
435 while(decpt > 0) {
436 *ptmp++ = '0';
437 decpt--;
441 void
442 __xfpcvt()
444 extern int (*__fp_print)();
445 __fp_print = __fp_print_func;
448 #endif
449 #endif