* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of California at Berkeley. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)vfprintf.c 5.7 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#define PUTC(ch, fd) {++cnt; putc(ch, fd);}
r = argsize&LONGINT ? va_arg(argp, long) : \
argsize&SHORTINT ? va_arg(argp, short) : va_arg(argp, int);
register u_long reg_ulong
;
register char *digs
, *bp
, *t
, padc
;
char argsize
, printsign
, *_cvt(), buf
[MAXBUF
];
int alternate
, cnt
, n
, ladjust
, width
, prec
, size
;
digs
= "0123456789abcdef";
for (cnt
= 0; *fmt
; ++fmt
) {
alternate
= ladjust
= width
= 0;
argsize
= printsign
= '\0';
* ``A negative field width argument is taken as a
* - flag followed by a positive field width.''
* They don't exclude field widths read from args.
if ((width
= va_arg(argp
, int)) >= 0)
prec
= va_arg(argp
, int);
else if (isdigit(*fmt
)) {
prec
= 10 * prec
+ *fmt
- '0';
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
width
= 10 * width
+ *fmt
- '0';
case '%': /* "%#%" prints as "%" */
_double
= va_arg(argp
, double);
bp
= _cvt(_double
, prec
, buf
, EFORMAT
, *fmt
,
_double
= va_arg(argp
, double);
bp
= _cvt(_double
, prec
, buf
, FFORMAT
, 'f',
_double
= va_arg(argp
, double);
bp
= _cvt(_double
, prec
, buf
, GFORMAT
, *fmt
- 2,
if (size
< width
&& !ladjust
)
} while (--width
> size
);
for (t
= buf
; t
< bp
; ++t
)
for (; width
> size
; --width
)
*(va_arg(argp
, int *)) = cnt
;
if (!reg_ulong
|| !alternate
)
bp
= buf
+ sizeof(buf
) - 1;
*bp
-- = digs
[reg_ulong
% base
];
size
= &buf
[sizeof(buf
) - 1] - bp
;
if (size
< --width
&& !ladjust
)
} while (--width
> size
);
if (!(bp
= va_arg(argp
, char *)))
if (width
> 0 && !ladjust
) {
for (n
= 0; *bp
&& (prec
< 0 || n
< prec
);
if (++n
> prec
&& prec
>= 0)
if (n
< width
&& ladjust
)
digs
= "0123456789ABCDEF";
if (alternate
&& reg_ulong
) {
num1
: bp
= buf
+ sizeof(buf
) - 1;
*bp
-- = digs
[reg_ulong
% base
];
size
= &buf
[sizeof(buf
) - 1] - bp
;
for (; size
< prec
; *bp
-- = '0', ++size
);
if (size
< width
&& !ladjust
)
} while (--width
> size
);
num2
: while (++bp
!= &buf
[MAXBUF
])
for (; width
> size
; --width
)
digs
= "0123456789abcdef";
case '\0': /* "%?" prints ?, unless ? is NULL */
return(ferror(fp
) ? -1 : cnt
);
return(ferror(fp
) ? -1 : cnt
);
_cvt(number
, prec
, bp
, format
, fmtch
, printsign
, alternate
)
int prec
, format
, alternate
;
t
= fabs(number
) < 1 ? ecvt(number
, prec
+ 1, &decpt
, &sign
) :
fcvt(number
, prec
+ 1, &decpt
, &sign
);
/* use 'e' format if exponent > precision or less than -4 */
format
== GFORMAT
&& (decpt
> prec
|| decpt
< -3)) {
if (format
!= GFORMAT
&& prec
|| prec
> 1) {
if (format
== GFORMAT
&& !alternate
) {
for (; bp
[-1] == '0'; --bp
);
*bp
++ = decpt
/ 10 + '0';
*bp
++ = decpt
% 10 + '0';
while (decpt
++ < 0 && prec
--)
for (n
= 1; n
<= decpt
; n
++)
for (n
= 1; n
<= prec
; n
++)
if (format
== GFORMAT
&& !alternate
) {
for (; bp
[-1] == '0'; --bp
);