diff options
Diffstat (limited to 'lib/libc/stdio/vfprintf.c')
| -rw-r--r-- | lib/libc/stdio/vfprintf.c | 58 | 
1 files changed, 38 insertions, 20 deletions
| diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 8d064c696c2e..dea8a5620da6 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -35,7 +35,8 @@   */  #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)vfprintf.c	5.50 (Berkeley) 12/16/92"; +/*static char *sccsid = "from: @(#)vfprintf.c	5.50 (Berkeley) 12/16/92";*/ +static char *rcsid = "$Id: vfprintf.c,v 1.5 1994/02/06 07:35:02 wollman Exp $";  #endif /* LIBC_SCCS and not lint */  /* @@ -120,6 +121,7 @@ __sbprintf(fp, fmt, ap)  #ifdef FLOATING_POINT +#include <locale.h>  #include <math.h>  #include "floatio.h" @@ -159,7 +161,7 @@ int  vfprintf(fp, fmt0, ap)  	FILE *fp;  	const char *fmt0; -	va_list ap; +	_VA_LIST_ ap;  {  	register char *fmt;	/* format string */  	register int ch;	/* character from fmt */ @@ -382,20 +384,23 @@ reswitch:	switch (ch) {  			base = DEC;  			goto number;  #ifdef FLOATING_POINT -		case 'e':		/* anomalous precision */ +		case 'e':  		case 'E': -			prec = (prec == -1) ? -				DEFPREC + 1 : prec + 1; -			/* FALLTHROUGH */ -			goto fp_begin; -		case 'f':		/* always print trailing zeroes */ -			if (prec != 0) -				flags |= ALT; +		case 'f':  		case 'g':  		case 'G': -			if (prec == -1) +			if (prec == -1) {  				prec = DEFPREC; -fp_begin:		_double = va_arg(ap, double); +			} else if ((ch == 'g' || ch == 'G') && prec == 0) { +				prec = 1; +			} + +			if (flags & LONGDBL) { +				_double = (double) va_arg(ap, long double); +			} else { +				_double = va_arg(ap, double); +			} +  			/* do this before tricky precision changes */  			if (isinf(_double)) {  				if (_double < 0) @@ -409,6 +414,7 @@ fp_begin:		_double = va_arg(ap, double);  				size = 3;  				break;  			} +  			flags |= FPT;  			cp = cvt(_double, prec, flags, &softsign,  				&expt, ch, &ndig); @@ -469,7 +475,12 @@ fp_begin:		_double = va_arg(ap, double);  			 *	-- ANSI X3J11  			 */  			/* NOSTRICT */ +			/* no easy way to tell in cpp how big a type is */ +#if defined(__i386) +			_uquad = (u_quad_t)(u_long)va_arg(ap, void *); +#else  			_uquad = (u_quad_t)va_arg(ap, void *); +#endif  			base = HEX;  			xdigs = "0123456789abcdef";  			flags |= HEXPREFIX; @@ -631,9 +642,8 @@ number:			if ((dprec = prec) >= 0)  		} else {	/* glue together f_p fragments */  			if (ch >= 'f') {	/* 'f' or 'g' */  				if (_double == 0) { -				/* kludge for __dtoa irregularity */ -					if (prec == 0 || -					    (flags & ALT) == 0) { +					/* kludge for __dtoa irregularity */ +					if (expt >= ndig && (flags & ALT) == 0) {  						PRINT("0", 1);  					} else {  						PRINT("0.", 2); @@ -701,18 +711,26 @@ cvt(value, ndigits, flags, sign, decpt, ch, length)  	int mode, dsgn;  	char *digits, *bp, *rve; -	if (ch == 'f') -		mode = 3; -	else { -		mode = 2; +	if (ch == 'f') { +		mode = 3;		/* ndigits after the decimal point */ +	} else { +		/* To obtain ndigits after the decimal point for the 'e'  +		 * and 'E' formats, round to ndigits + 1 significant  +		 * figures. +		 */ +		if (ch == 'e' || ch == 'E') { +			ndigits++; +		} +		mode = 2;		/* ndigits significant digits */  	} +  	if (value < 0) {  		value = -value;  		*sign = '-';  	} else  		*sign = '\000';  	digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); -	if (flags & ALT) {	/* Print trailing zeros */ +	if ((ch != 'g' && ch != 'G') || flags & ALT) {	/* Print trailing zeros */  		bp = digits + ndigits;  		if (ch == 'f') {  			if (*digits == '0' && value) | 
