#include "libioP.h"
#ifdef _IO_USE_DTOA
int
_IO_outfloat (value, sb, type, width, precision, flags, sign_mode, fill)
double value;
_IO_FILE *sb;
int type;
int width;
int precision;
int flags;
int sign_mode;
int fill;
{
int count = 0;
#define PUT(x) do {if (_IO_putc(x, sb) < 0) goto error; count++;} while (0)
#define PUTN(p, n) \
do {int _n=n; count+=_n; if (_IO_sputn(sb, p,_n) != _n) goto error;} while(0)
#define PADN(fill, n) \
do {int _n = n; count+=_n; if (_IO_padn(sb, fill, _n) != _n) goto error;} while (0)
int pad_kind = flags & (_IO_LEFT|_IO_RIGHT|_IO_INTERNAL);
int skip_zeroes = 0;
int show_dot = (flags & _IO_SHOWPOINT) != 0;
int decpt;
int sign;
int mode;
int exponent_size;
int print_sign;
int trailing_zeroes, useful_digits;
int padding, unpadded_width;
char *p;
char *exponent_start;
register int i;
#define EBUF_SIZE 12
#define EBUF_END &ebuf[EBUF_SIZE]
char ebuf[EBUF_SIZE];
char *end;
int exp = 0;
switch (type)
{
case 'f':
mode = 3;
break;
case 'e':
case 'E':
exp = type;
mode = 2;
if (precision != 999)
precision++;
break;
case 'g':
case 'G':
exp = type == 'g' ? 'e' : 'E';
if (precision == 0) precision = 1;
if (!(flags & _IO_SHOWPOINT))
skip_zeroes = 1;
type = 'g';
mode = 2;
break;
}
if (precision == 999 && mode != 3)
mode = 0;
p = _IO_dtoa(value, mode, precision, &decpt, &sign, &end);
useful_digits = end-p;
exponent_start = EBUF_END;
if (mode == 0)
precision = useful_digits;
if (mode != 3 && decpt != 9999)
{
i = decpt - 1;
if ((type != 'g' && type != 'F') || i < -4 || i >= precision)
{
char sign;
if (i >= 0)
sign = '+';
else
sign = '-', i = -i;
do {
*--exponent_start = (i % 10) + '0';
i /= 10;
} while (i >= 10);
*--exponent_start = i + '0';
*--exponent_start = sign;
*--exponent_start = exp;
}
}
exponent_size = EBUF_END - exponent_start;
if (mode == 1)
precision = 1;
if (exponent_size)
decpt = 1;
if (decpt == 9999)
{
decpt = useful_digits;
precision = 0;
show_dot = 0;
}
if (skip_zeroes)
trailing_zeroes = 0;
else if (type == 'f')
trailing_zeroes = useful_digits <= decpt ? precision
: precision-(useful_digits-decpt);
else if (exponent_size)
trailing_zeroes = precision - useful_digits;
else
trailing_zeroes = useful_digits <= decpt ? precision - decpt
: precision-useful_digits;
if (trailing_zeroes < 0) trailing_zeroes = 0;
if (trailing_zeroes != 0 || useful_digits > decpt)
show_dot = 1;
if (sign_mode == 0)
print_sign = sign ? '-' : 0;
else if (sign_mode == '+')
print_sign = sign ? '-' : '+';
else
print_sign = sign ? '-' : ' ';
unpadded_width =
(print_sign != 0) + trailing_zeroes + exponent_size + show_dot
+ useful_digits
+ (decpt > useful_digits ? decpt - useful_digits
: decpt > 0 ? 0 : 1 - decpt);
padding = width > unpadded_width ? width - unpadded_width : 0;
if (padding > 0 && pad_kind != _IO_LEFT && pad_kind != _IO_INTERNAL)
PADN(fill, padding);
if (print_sign)
PUT(print_sign);
if (pad_kind == _IO_INTERNAL && padding > 0)
PADN(fill, padding);
if (decpt > 0)
{
if (useful_digits >= decpt)
PUTN(p, decpt);
else
{
PUTN(p, useful_digits);
PADN('0', decpt-useful_digits);
}
if (show_dot)
{
PUT('.');
if (useful_digits > decpt)
PUTN(p + decpt, useful_digits-decpt);
}
}
else
{
PUT('0');
if (show_dot)
{
PUT('.');
PADN('0', -decpt);
PUTN(p, useful_digits);
}
}
PADN('0', trailing_zeroes);
if (exponent_size)
PUTN(exponent_start, exponent_size);
if (pad_kind == _IO_LEFT && padding > 0)
PADN(fill, padding);
return count;
error:
return EOF;
}
#endif