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
19 * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short)
24 #include <sys/types.h>
26 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
28 #define va_strt va_start
31 #define va_strt(p,i) va_start(p)
38 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
39 int printf(const char * fmt
, ...)
41 int printf(fmt
, va_alist
)
49 rv
= vfprintf(stdout
,fmt
,ptr
);
56 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
57 int sprintf(char * sp
, const char * fmt
, ...)
59 int sprintf(sp
, fmt
, va_alist
)
65 static FILE string
[1] =
67 {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1,
68 _IOFBF
| __MODE_WRITE
}
75 rv
= vfprintf(string
,fmt
,ptr
);
77 *(string
->bufpos
) = 0;
83 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
84 int fprintf(FILE * fp
, const char * fmt
, ...)
86 int fprintf(fp
, fmt
, va_alist
)
95 rv
= vfprintf(fp
,fmt
,ptr
);
106 return vfprintf(stdout
,fmt
,ap
);
111 int vsprintf(sp
, fmt
, ap
)
116 static FILE string
[1] =
118 {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1,
119 _IOFBF
| __MODE_WRITE
}
124 rv
= vfprintf(string
,fmt
,ap
);
125 *(string
->bufpos
) = 0;
132 #ifndef __HAS_NO_FLOATS__
133 int (*__fp_print
)() = 0;
137 prtfld(op
, buf
, ljustf
, sign
, pad
, width
, preci
, buffer_mode
)
139 register unsigned char *buf
;
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
;
161 if ((preci
!= -1) && (len
> preci
)) /* limit max data width */
164 if (width
< len
) /* flexible field width or width overflow */
168 * at this point: width = total field width len = actual data width
169 * (including possible sign character)
176 if (!ljustf
&& width
) /* left padding */
178 if (len
&& sign
&& (pad
== '0'))
187 showsign
:ch
= sign
; /* sign */
191 ch
= *buf
++; /* main field */
196 ch
= pad
; /* right padding */
200 if( ch
== '\n' && buffer_mode
== _IOLBF
) fflush(op
);
207 vfprintf(op
, fmt
, ap
)
209 register __const
char *fmt
;
212 register int i
, cnt
= 0, ljustf
, lval
;
213 int preci
, dpoint
, width
;
214 char pad
, sign
, radix
, hash
;
216 char tmp
[64], *ltostr(), *ultostr();
219 /* This speeds things up a bit for unbuffered */
220 buffer_mode
= (op
->mode
&__MODE_BUF
);
221 op
->mode
&= (~__MODE_BUF
);
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 */
237 lval
= (sizeof(int)==sizeof(long)); /* long value flaged */
243 if(*fmt
< '0' || *fmt
> '9' ) break;
244 i
= (i
* 10) + (*fmt
- '0');
247 else if (!i
&& (pad
== ' '))
258 case '\0': /* early EOS */
262 case '-': /* left justification */
267 case '+': /* leading sign flag */
271 case '*': /* parameter width value */
279 case '.': /* secondary width field */
283 case 'l': /* long data */
287 case 'h': /* short data */
291 case 'd': /* Signed decimal */
293 ptmp
= ltostr((long) ((lval
)
295 : va_arg(ap
, short)),
299 case 'b': /* Unsigned binary */
303 case 'o': /* Unsigned octal */
307 case 'p': /* Pointer */
308 lval
= (sizeof(char*) == sizeof(long));
314 case 'x': /* Unsigned hexadecimal */
319 case 'u': /* Unsigned decimal */
321 ptmp
= ultostr((unsigned long) ((lval
)
322 ? va_arg(ap
, unsigned long)
323 : va_arg(ap
, unsigned short)),
325 if( hash
&& radix
== 8 ) { width
= strlen(ptmp
)+1; pad
='0'; }
332 case 'c': /* Character */
333 ptmp
[0] = va_arg(ap
, int);
337 case 's': /* String */
338 ptmp
= va_arg(ap
, char*);
343 cnt
+= prtfld(op
, ptmp
, ljustf
,
344 sign
, pad
, width
, preci
, buffer_mode
);
347 #ifndef __HAS_NO_FLOATS__
348 case 'e': /* float */
355 (*__fp_print
)(&va_arg(ap
, double), *fmt
, preci
, ptmp
);
359 /* FALLTHROUGH if no floating printf available */
362 default: /* unknown character */
369 putc(*fmt
, op
); /* normal char out */
371 if( *fmt
== '\n' && buffer_mode
== _IOLBF
) fflush(op
);
375 op
->mode
|= buffer_mode
;
376 if( buffer_mode
== _IONBF
) fflush(op
);
377 if( buffer_mode
== _IOLBF
) op
->bufwrite
= op
->bufstart
;
383 #ifndef __HAS_NO_FLOATS__
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
.
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
.
404 __fp_print_func(pval
, style
, preci
, ptmp
)
414 if (preci
< 0) preci
= 6;
416 cvt
= fcvt(val
, preci
, &decpt
, &negative
);
424 *ptmp
++ = '0'; decpt
++;
444 extern int (*__fp_print
)();
445 __fp_print
= __fp_print_func
;