diff options
Diffstat (limited to 'contrib/libg++/libio/iovfprintf.c')
| -rw-r--r-- | contrib/libg++/libio/iovfprintf.c | 881 | 
1 files changed, 0 insertions, 881 deletions
| diff --git a/contrib/libg++/libio/iovfprintf.c b/contrib/libg++/libio/iovfprintf.c deleted file mode 100644 index c6ba7957d719..000000000000 --- a/contrib/libg++/libio/iovfprintf.c +++ /dev/null @@ -1,881 +0,0 @@ -/*  -Copyright (C) 1993 Free Software Foundation - -This file is part of the GNU IO Library.  This library is free -software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) -any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING.  If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. - -As a special exception, if you link this library with files -compiled with a GNU compiler to produce an executable, this does not cause -the resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why -the executable file might be covered by the GNU General Public License. */ - -/* - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, 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'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "%W% (Berkeley) %G%"; -#endif /* LIBC_SCCS and not lint */ - -/* - * Actual printf innards. - * - * This code is large and complicated... - */ - -#include <sys/types.h> -#include "libioP.h" -#include <string.h> -#ifdef __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif - -/* - * Define FLOATING_POINT to get floating point. - */ -#ifndef	NO_FLOATING_POINT -#define	FLOATING_POINT -#endif - -/* end of configuration stuff */ - - -/* - * Helper "class" for `fprintf to unbuffered': creates a - * temporary buffer. */ - -struct helper_file -{ -  struct _IO_FILE_plus _f; -  _IO_FILE *_put_stream; -}; - -static int -DEFUN(_IO_helper_overflow, (fp, c), -      _IO_FILE *fp AND int c) -{ -  _IO_FILE *target = ((struct helper_file*)fp)->_put_stream; -  int used = fp->_IO_write_ptr - fp->_IO_write_base; -  if (used) -    { -      _IO_sputn(target, fp->_IO_write_base, used); -      fp->_IO_write_ptr -= used; -    } -  return _IO_putc (c, fp); -} - -static struct _IO_jump_t _IO_helper_jumps = { -  JUMP_INIT_DUMMY, -  JUMP_INIT(finish, _IO_default_finish), -  JUMP_INIT(overflow, _IO_helper_overflow), -  JUMP_INIT(underflow, _IO_default_underflow), -  JUMP_INIT(uflow, _IO_default_uflow), -  JUMP_INIT(pbackfail, _IO_default_pbackfail), -  JUMP_INIT(xsputn, _IO_default_xsputn), -  JUMP_INIT(xsgetn, _IO_default_xsgetn), -  JUMP_INIT(seekoff, _IO_default_seekoff), -  JUMP_INIT(seekpos, _IO_default_seekpos), -  JUMP_INIT(setbuf, _IO_default_setbuf), -  JUMP_INIT(sync, _IO_default_sync), -  JUMP_INIT(doallocate, _IO_default_doallocate), -  JUMP_INIT(read, _IO_default_read), -  JUMP_INIT(write, _IO_default_write), -  JUMP_INIT(seek, _IO_default_seek), -  JUMP_INIT(close, _IO_default_close), -  JUMP_INIT(stat, _IO_default_stat) -}; - -static int -DEFUN(helper_vfprintf, (fp, fmt0, ap), -      register _IO_FILE* fp AND char const *fmt0 AND _IO_va_list ap) -{ -  char buf[_IO_BUFSIZ]; -  struct helper_file helper; -  register _IO_FILE *hp = (_IO_FILE*)&helper; -  int result, to_flush; - -  /* initialize helper */ -  helper._put_stream = fp; -  hp->_IO_write_base = buf; -  hp->_IO_write_ptr = buf; -  hp->_IO_write_end = buf+_IO_BUFSIZ; -  hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS; -  _IO_JUMPS(hp) = &_IO_helper_jumps; -   -  /* Now print to helper instead. */ -  result = _IO_vfprintf(hp, fmt0, ap); - -  /* Now flush anything from the helper to the fp. */ -  if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0) -    { -      if (_IO_sputn(fp, hp->_IO_write_base, to_flush) != to_flush) -	return EOF; -    } -  return result; -} - -#ifdef FLOATING_POINT - -#include "floatio.h" -#define	BUF		(MAXEXP+MAXFRACT+1)	/* + decimal point */ -#define	DEFPREC		6 -extern double modf __P((double, double*)); - -#else /* no FLOATING_POINT */ - -#define	BUF		40 - -#endif /* FLOATING_POINT */ - - -/* - * Macros for converting digits to letters and vice versa - */ -#define	to_digit(c)	((c) - '0') -#define is_digit(c)	((unsigned)to_digit(c) <= 9) -#define	to_char(n)	((n) + '0') - -/* - * Flags used during conversion. - */ -#define	LONGINT		0x01		/* long integer */ -#define	LONGDBL		0x02		/* long double; unimplemented */ -#define	SHORTINT	0x04		/* short integer */ -#define	ALT		0x08		/* alternate form */ -#define	LADJUST		0x10		/* left adjustment */ -#define	ZEROPAD		0x20		/* zero (as opposed to blank) pad */ -#define	HEXPREFIX	0x40		/* add 0x or 0X prefix */ - -int -DEFUN(_IO_vfprintf, (fp, fmt0, ap), -      register _IO_FILE* fp AND char const *fmt0 AND _IO_va_list ap) -{ -	register const char *fmt; /* format string */ -	register int ch;	/* character from fmt */ -	register int n;		/* handy integer (short term usage) */ -	register char *cp;	/* handy char pointer (short term usage) */ -	const char *fmark;	/* for remembering a place in fmt */ -	register int flags;	/* flags as above */ -	int ret;		/* return value accumulator */ -	int width;		/* width from format (%8d), or 0 */ -	int prec;		/* precision from format (%.3d), or -1 */ -	char sign;		/* sign prefix (' ', '+', '-', or \0) */ -#ifdef FLOATING_POINT -	int softsign;		/* temporary negative sign for floats */ -	double _double;		/* double precision arguments %[eEfgG] */ -#ifndef _IO_USE_DTOA -	int fpprec;		/* `extra' floating precision in [eEfgG] */ -#endif -#endif -	unsigned long _ulong;	/* integer arguments %[diouxX] */ -	enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ -	int dprec;		/* a copy of prec if [diouxX], 0 otherwise */ -	int dpad;		/* extra 0 padding needed for integers */ -	int fieldsz;		/* field size expanded by sign, dpad etc */ -	/* The initialization of 'size' is to suppress a warning that -	   'size' might be used unitialized.  It seems gcc can't -	   quite grok this spaghetti code ... */ -	int size = 0;		/* size of converted field or string */ -	char buf[BUF];		/* space for %c, %[diouxX], %[eEfgG] */ -	char ox[2];		/* space for 0x hex-prefix */ - -	/* -	 * BEWARE, these `goto error' on error, and PAD uses `n'. -	 */ -#define	PRINT(ptr, len) \ -  do { if (_IO_sputn(fp,ptr, len) != len) goto error; } while (0) -#define PAD_SP(howmany) if (_IO_padn(fp, ' ', howmany) < (howmany)) goto error; -#define PAD_0(howmany) if (_IO_padn(fp, '0', howmany) < (howmany)) goto error; - -	/* -	 * To extend shorts properly, we need both signed and unsigned -	 * argument extraction methods. -	 */ -#define	SARG() \ -	(flags&LONGINT ? va_arg(ap, long) : \ -	    flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ -	    (long)va_arg(ap, int)) -#define	UARG() \ -	(flags&LONGINT ? va_arg(ap, unsigned long) : \ -	    flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \ -	    (unsigned long)va_arg(ap, unsigned int)) - -	/* optimise stderr (and other unbuffered Unix files) */ -	if (fp->_IO_file_flags & _IO_UNBUFFERED) -	    return helper_vfprintf(fp, fmt0, ap); - -	fmt = fmt0; -	ret = 0; - -	/* -	 * Scan the format for conversions (`%' character). -	 */ -	for (;;) { -		for (fmark = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) -			/* void */; -		if ((n = fmt - fmark) != 0) { -			PRINT(fmark, n); -			ret += n; -		} -		if (ch == '\0') -			goto done; -		fmt++;		/* skip over '%' */ - -		flags = 0; -		dprec = 0; -#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA) -		fpprec = 0; -#endif -		width = 0; -		prec = -1; -		sign = '\0'; - -rflag:		ch = *fmt++; -reswitch:	switch (ch) { -		case ' ': -			/* -			 * ``If the space and + flags both appear, the space -			 * flag will be ignored.'' -			 *	-- ANSI X3J11 -			 */ -			if (!sign) -				sign = ' '; -			goto rflag; -		case '#': -			flags |= ALT; -			goto rflag; -		case '*': -			/* -			 * ``A negative field width argument is taken as a -			 * - flag followed by a positive field width.'' -			 *	-- ANSI X3J11 -			 * They don't exclude field widths read from args. -			 */ -			if ((width = va_arg(ap, int)) >= 0) -				goto rflag; -			width = -width; -			/* FALLTHROUGH */ -		case '-': -			flags |= LADJUST; -			flags &= ~ZEROPAD; /* '-' disables '0' */ -			goto rflag; -		case '+': -			sign = '+'; -			goto rflag; -		case '.': -			if ((ch = *fmt++) == '*') { -				n = va_arg(ap, int); -				prec = n < 0 ? -1 : n; -				goto rflag; -			} -			n = 0; -			while (is_digit(ch)) { -				n = 10 * n + to_digit(ch); -				ch = *fmt++; -			} -			prec = n < 0 ? -1 : n; -			goto reswitch; -		case '0': -			/* -			 * ``Note that 0 is taken as a flag, not as the -			 * beginning of a field width.'' -			 *	-- ANSI X3J11 -			 */ -			if (!(flags & LADJUST)) -			    flags |= ZEROPAD; /* '-' disables '0' */ -			goto rflag; -		case '1': case '2': case '3': case '4': -		case '5': case '6': case '7': case '8': case '9': -			n = 0; -			do { -				n = 10 * n + to_digit(ch); -				ch = *fmt++; -			} while (is_digit(ch)); -			width = n; -			goto reswitch; -#ifdef FLOATING_POINT -		case 'L': -			flags |= LONGDBL; -			goto rflag; -#endif -		case 'h': -			flags |= SHORTINT; -			goto rflag; -		case 'l': -			flags |= LONGINT; -			goto rflag; -		case 'c': -			*(cp = buf) = va_arg(ap, int); -			size = 1; -			sign = '\0'; -			break; -		case 'D': -			flags |= LONGINT; -			/*FALLTHROUGH*/ -		case 'd': -		case 'i': -			_ulong = SARG(); -			if ((long)_ulong < 0) { -				_ulong = -_ulong; -				sign = '-'; -			} -			base = DEC; -			goto number; -#ifdef FLOATING_POINT -		case 'e': -		case 'E': -		case 'f': -		case 'F': -		case 'g': -		case 'G': -			_double = va_arg(ap, double); -#ifdef _IO_USE_DTOA -			{ -			    int fmt_flags = 0; -			    int fill = ' '; -			    if (flags & ALT) -				fmt_flags |= _IO_SHOWPOINT; -			    if (flags & LADJUST) -				fmt_flags |= _IO_LEFT; -			    else if (flags & ZEROPAD) -				fmt_flags |= _IO_INTERNAL, fill = '0'; -			    n = _IO_outfloat(_double, fp, ch, width, -					     prec < 0 ? DEFPREC : prec, -					     fmt_flags, sign, fill); -			    if (n < 0) -				goto error; -			    ret += n; -			} -			/* CHECK ERROR! */ -			continue; -#else -			/* -			 * don't do unrealistic precision; just pad it with -			 * zeroes later, so buffer size stays rational. -			 */ -			if (prec > MAXFRACT) { -				if ((ch != 'g' && ch != 'G') || (flags&ALT)) -					fpprec = prec - MAXFRACT; -				prec = MAXFRACT; -			} else if (prec == -1) -				prec = DEFPREC; -			/* __cvt_double may have to round up before the -			   "start" of its buffer, i.e. -			   ``intf("%.2f", (double)9.999);''; -			   if the first character is still NUL, it did. -			   softsign avoids negative 0 if _double < 0 but -			   no significant digits will be shown. */ -			cp = buf; -			*cp = '\0'; -			size = __cvt_double(_double, prec, flags, &softsign, -					    ch, cp, buf + sizeof(buf)); -			if (softsign) -				sign = '-'; -			if (*cp == '\0') -				cp++; -			break; -#endif -#endif /* FLOATING_POINT */ -		case 'n': -			if (flags & LONGINT) -				*va_arg(ap, long *) = ret; -			else if (flags & SHORTINT) -				*va_arg(ap, short *) = ret; -			else -				*va_arg(ap, int *) = ret; -			continue;	/* no output */ -		case 'O': -			flags |= LONGINT; -			/*FALLTHROUGH*/ -		case 'o': -			_ulong = UARG(); -			base = OCT; -			goto nosign; -		case 'p': -			/* -			 * ``The argument shall be a pointer to void.  The -			 * value of the pointer is converted to a sequence -			 * of printable characters, in an implementation- -			 * defined manner.'' -			 *	-- ANSI X3J11 -			 */ -			/* NOSTRICT */ -			_ulong = (unsigned long)va_arg(ap, void *); -			base = HEX; -			flags |= HEXPREFIX; -			ch = 'x'; -			goto nosign; -		case 's': -			if ((cp = va_arg(ap, char *)) == NULL) -				cp = "(null)"; -			if (prec >= 0) { -				/* -				 * can't use strlen; can only look for the -				 * NUL in the first `prec' characters, and -				 * strlen() will go further. -				 */ -				char *p = (char*)memchr(cp, 0, prec); - -				if (p != NULL) { -					size = p - cp; -					if (size > prec) -						size = prec; -				} else -					size = prec; -			} else -				size = strlen(cp); -			sign = '\0'; -			break; -		case 'U': -			flags |= LONGINT; -			/*FALLTHROUGH*/ -		case 'u': -			_ulong = UARG(); -			base = DEC; -			goto nosign; -		case 'X': -		case 'x': -			_ulong = UARG(); -			base = HEX; -			/* leading 0x/X only if non-zero */ -			if (flags & ALT && _ulong != 0) -				flags |= HEXPREFIX; - -			/* unsigned conversions */ -nosign:			sign = '\0'; -			/* -			 * ``... diouXx conversions ... if a precision is -			 * specified, the 0 flag will be ignored.'' -			 *	-- ANSI X3J11 -			 */ -number:			if ((dprec = prec) >= 0) -				flags &= ~ZEROPAD; - -			/* -			 * ``The result of converting a zero value with an -			 * explicit precision of zero is no characters.'' -			 *	-- ANSI X3J11 -			 */ -			cp = buf + BUF; -			if (_ulong != 0 || prec != 0) { -			        char *xdigs; /* digits for [xX] conversion */ -				/* -				 * unsigned mod is hard, and unsigned mod -				 * by a constant is easier than that by -				 * a variable; hence this switch. -				 */ -				switch (base) { -				case OCT: -					do { -						*--cp = to_char(_ulong & 7); -						_ulong >>= 3; -					} while (_ulong); -					/* handle octal leading 0 */ -					if (flags & ALT && *cp != '0') -						*--cp = '0'; -					break; - -				case DEC: -					/* many numbers are 1 digit */ -					while (_ulong >= 10) { -						*--cp = to_char(_ulong % 10); -						_ulong /= 10; -					} -					*--cp = to_char(_ulong); -					break; - -				case HEX: -					if (ch == 'X') -					    xdigs = "0123456789ABCDEF"; -					else /* ch == 'x' || ch == 'p' */ -					    xdigs = "0123456789abcdef"; -					do { -						*--cp = xdigs[_ulong & 15]; -						_ulong >>= 4; -					} while (_ulong); -					break; - -				default: -					cp = "bug in vform: bad base"; -					goto skipsize; -				} -			} -			size = buf + BUF - cp; -		skipsize: -			break; -		default:	/* "%?" prints ?, unless ? is NUL */ -			if (ch == '\0') -				goto done; -			/* pretend it was %c with argument ch */ -			cp = buf; -			*cp = ch; -			size = 1; -			sign = '\0'; -			break; -		} - -		/* -		 * All reasonable formats wind up here.  At this point, -		 * `cp' points to a string which (if not flags&LADJUST) -		 * should be padded out to `width' places.  If -		 * flags&ZEROPAD, it should first be prefixed by any -		 * sign or other prefix; otherwise, it should be blank -		 * padded before the prefix is emitted.  After any -		 * left-hand padding and prefixing, emit zeroes -		 * required by a decimal [diouxX] precision, then print -		 * the string proper, then emit zeroes required by any -		 * leftover floating precision; finally, if LADJUST, -		 * pad with blanks. -		 */ - -		/* -		 * compute actual size, so we know how much to pad. -		 */ -#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA) -		fieldsz = size + fpprec; -#else -		fieldsz = size; -#endif -		dpad = dprec - size; -		if (dpad < 0) -		    dpad = 0; - -		if (sign) -			fieldsz++; -		else if (flags & HEXPREFIX) -			fieldsz += 2; -		fieldsz += dpad; - -		/* right-adjusting blank padding */ -		if ((flags & (LADJUST|ZEROPAD)) == 0) -			PAD_SP(width - fieldsz); - -		/* prefix */ -		if (sign) { -			PRINT(&sign, 1); -		} else if (flags & HEXPREFIX) { -			ox[0] = '0'; -			ox[1] = ch; -			PRINT(ox, 2); -		} - -		/* right-adjusting zero padding */ -		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) -			PAD_0(width - fieldsz); - -		/* leading zeroes from decimal precision */ -		PAD_0(dpad); - -		/* the string or number proper */ -		PRINT(cp, size); - -#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA) -		/* trailing f.p. zeroes */ -		PAD_0(fpprec); -#endif - -		/* left-adjusting padding (always blank) */ -		if (flags & LADJUST) -			PAD_SP(width - fieldsz); - -		/* finally, adjust ret */ -		ret += width > fieldsz ? width : fieldsz; - -	} -done: -	return ret; -error: -	return EOF; -	/* NOTREACHED */ -} - -#if defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) - -static char *exponent(register char *p, register int exp, int fmtch) -{ -	register char *t; -	char expbuf[MAXEXP]; - -	*p++ = fmtch; -	if (exp < 0) { -		exp = -exp; -		*p++ = '-'; -	} -	else -		*p++ = '+'; -	t = expbuf + MAXEXP; -	if (exp > 9) { -		do { -			*--t = to_char(exp % 10); -		} while ((exp /= 10) > 9); -		*--t = to_char(exp); -		for (; t < expbuf + MAXEXP; *p++ = *t++); -	} -	else { -		*p++ = '0'; -		*p++ = to_char(exp); -	} -	return (p); -} - -static char * round(double fract, int *exp, -		    register char *start, register char *end, -		    char ch, int *signp) -{ -	double tmp; - -	if (fract) -	(void)modf(fract * 10, &tmp); -	else -		tmp = to_digit(ch); -	if (tmp > 4) -		for (;; --end) { -			if (*end == '.') -				--end; -			if (++*end <= '9') -				break; -			*end = '0'; -			if (end == start) { -				if (exp) {	/* e/E; increment exponent */ -					*end = '1'; -					++*exp; -				} -				else {		/* f; add extra digit */ -				*--end = '1'; -				--start; -				} -				break; -			} -		} -	/* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ -	else if (*signp == '-') -		for (;; --end) { -			if (*end == '.') -				--end; -			if (*end != '0') -				break; -			if (end == start) -				*signp = 0; -		} -	return (start); -} - -int __cvt_double(double number, register int prec, int flags, int *signp, -		 int fmtch, char *startp, char *endp) -{ -	register char *p, *t; -	register double fract; -	int dotrim = 0, expcnt, gformat = 0; -	double integer, tmp; - -	expcnt = 0; -	if (number < 0) { -		number = -number; -		*signp = '-'; -	} else -		*signp = 0; - -	fract = modf(number, &integer); - -	/* get an extra slot for rounding. */ -	t = ++startp; - -	/* -	 * get integer portion of number; put into the end of the buffer; the -	 * .01 is added for modf(356.0 / 10, &integer) returning .59999999... -	 */ -	for (p = endp - 1; integer; ++expcnt) { -		tmp = modf(integer / 10, &integer); -		*p-- = to_char((int)((tmp + .01) * 10)); -	} -	switch (fmtch) { -	case 'f': -	case 'F': -		/* reverse integer into beginning of buffer */ -		if (expcnt) -			for (; ++p < endp; *t++ = *p); -		else -			*t++ = '0'; -		/* -		 * if precision required or alternate flag set, add in a -		 * decimal point. -		 */ -		if (prec || flags&ALT) -			*t++ = '.'; -		/* if requires more precision and some fraction left */ -		if (fract) { -			if (prec) -				do { -					fract = modf(fract * 10, &tmp); -					*t++ = to_char((int)tmp); -				} while (--prec && fract); -			if (fract) -				startp = round(fract, (int *)NULL, startp, -				    t - 1, (char)0, signp); -		} -		for (; prec--; *t++ = '0'); -		break; -	case 'e': -	case 'E': -eformat:	if (expcnt) { -			*t++ = *++p; -			if (prec || flags&ALT) -				*t++ = '.'; -			/* if requires more precision and some integer left */ -			for (; prec && ++p < endp; --prec) -				*t++ = *p; -			/* -			 * if done precision and more of the integer component, -			 * round using it; adjust fract so we don't re-round -			 * later. -			 */ -			if (!prec && ++p < endp) { -				fract = 0; -				startp = round((double)0, &expcnt, startp, -				    t - 1, *p, signp); -			} -			/* adjust expcnt for digit in front of decimal */ -			--expcnt; -		} -		/* until first fractional digit, decrement exponent */ -		else if (fract) { -			/* adjust expcnt for digit in front of decimal */ -			for (expcnt = -1;; --expcnt) { -				fract = modf(fract * 10, &tmp); -				if (tmp) -					break; -			} -			*t++ = to_char((int)tmp); -			if (prec || flags&ALT) -				*t++ = '.'; -		} -		else { -			*t++ = '0'; -			if (prec || flags&ALT) -				*t++ = '.'; -		} -		/* if requires more precision and some fraction left */ -		if (fract) { -			if (prec) -				do { -					fract = modf(fract * 10, &tmp); -					*t++ = to_char((int)tmp); -				} while (--prec && fract); -			if (fract) -				startp = round(fract, &expcnt, startp, -				    t - 1, (char)0, signp); -		} -		/* if requires more precision */ -		for (; prec--; *t++ = '0'); - -		/* unless alternate flag, trim any g/G format trailing 0's */ -		if (gformat && !(flags&ALT)) { -			while (t > startp && *--t == '0'); -			if (*t == '.') -				--t; -			++t; -		} -		t = exponent(t, expcnt, fmtch); -		break; -	case 'g': -	case 'G': -		/* a precision of 0 is treated as a precision of 1. */ -		if (!prec) -			++prec; -		/* -		 * ``The style used depends on the value converted; style e -		 * will be used only if the exponent resulting from the -		 * conversion is less than -4 or greater than the precision.'' -		 *	-- ANSI X3J11 -		 */ -		if (expcnt > prec || (!expcnt && fract && fract < .0001)) { -			/* -			 * g/G format counts "significant digits, not digits of -			 * precision; for the e/E format, this just causes an -			 * off-by-one problem, i.e. g/G considers the digit -			 * before the decimal point significant and e/E doesn't -			 * count it as precision. -			 */ -			--prec; -			fmtch -= 2;		/* G->E, g->e */ -			gformat = 1; -			goto eformat; -		} -		/* -		 * reverse integer into beginning of buffer, -		 * note, decrement precision -		 */ -		if (expcnt) -			for (; ++p < endp; *t++ = *p, --prec); -		else -			*t++ = '0'; -		/* -		 * if precision required or alternate flag set, add in a -		 * decimal point.  If no digits yet, add in leading 0. -		 */ -		if (prec || flags&ALT) { -			dotrim = 1; -			*t++ = '.'; -		} -		else -			dotrim = 0; -		/* if requires more precision and some fraction left */ -		if (fract) { -			if (prec) { -				/* If no integer part, don't count initial -				 * zeros as significant digits. */ -				do { -					fract = modf(fract * 10, &tmp); -					*t++ = to_char((int)tmp); -				} while(!tmp && !expcnt); -				while (--prec && fract) { -					fract = modf(fract * 10, &tmp); -					*t++ = to_char((int)tmp); -				} -			} -			if (fract) -				startp = round(fract, (int *)NULL, startp, -				    t - 1, (char)0, signp); -		} -		/* alternate format, adds 0's for precision, else trim 0's */ -		if (flags&ALT) -			for (; prec--; *t++ = '0'); -		else if (dotrim) { -			while (t > startp && *--t == '0'); -			if (*t != '.') -				++t; -		} -	} -	return (t - startp); -} - -#endif /* defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) */ | 
