#include "ftoa_engine.h"
#include "dtoa_conv.h"
#include "sectionname.h"
ATTRIBUTE_CLIB_SECTION
int
dtoa_prf (double val, char *s, unsigned char width, unsigned char prec,
unsigned char flags)
{
int exp;
int n;
unsigned char vtype;
unsigned char sign;
unsigned char ndigs;
unsigned char buf[9];
ndigs = prec < 60 ? prec + 1 : 60;
exp = __ftoa_engine (val, (char *)buf, 7, ndigs);
vtype = buf[0];
sign = 0;
if ((vtype & (FTOA_MINUS | FTOA_NAN)) == FTOA_MINUS)
sign = '-';
else if (flags & DTOA_PLUS)
sign = '+';
else if (flags & DTOA_SPACE)
sign = ' ';
if (vtype & FTOA_NAN) {
ndigs = sign ? 4 : 3;
width = (width > ndigs) ? width - ndigs : 0;
if (!(flags & DTOA_LEFT)) {
while (width) {
*s++ = ' ';
width--;
}
}
if (sign) *s++ = sign;
if (flags & DTOA_UPPER) {
*s++ = 'N'; *s++ = 'A'; *s++ = 'N';
} else {
*s++ = 'n'; *s++ = 'a'; *s++ = 'n';
}
while (width) {
*s++ = ' ';
width--;
}
*s = 0;
return DTOA_NONFINITE;
}
if (vtype & FTOA_INF) {
ndigs = sign ? 4 : 3;
width = (width > ndigs) ? width - ndigs : 0;
if (!(flags & DTOA_LEFT)) {
while (width) {
*s++ = ' ';
width--;
}
}
if (sign) *s++ = sign;
if (flags & DTOA_UPPER) {
*s++ = 'I'; *s++ = 'N'; *s++ = 'F';
} else {
*s++ = 'i'; *s++ = 'n'; *s++ = 'f';
}
while (width) {
*s++ = ' ';
width--;
}
*s = 0;
return DTOA_NONFINITE;
}
n = (sign ? 1 : 0) + (exp>0 ? exp+1 : 1) + (prec ? prec+1 : 0);
width = width > n ? width - n : 0;
if (!(flags & DTOA_LEFT) && !(flags & DTOA_ZFILL)) {
while (width) {
*s++ = ' ';
width--;
}
}
if (sign) *s++ = sign;
if (!(flags & DTOA_LEFT)) {
while (width) {
*s++ = '0';
width--;
}
}
ndigs += exp;
sign = buf[1];
if ((vtype & FTOA_CARRY) && sign == '1')
ndigs -= 1;
if ((signed char)ndigs < 1)
ndigs = 1;
else if (ndigs > 8)
ndigs = 8;
n = exp > 0 ? exp : 0;
do {
if (n == -1)
*s++ = '.';
flags = (n <= exp && n > exp - ndigs) ? buf[exp - n + 1] : '0';
if (--n < -prec)
break;
*s++ = flags;
} while (1);
if ( n == exp && (sign > '5' || (sign == '5' && !(vtype & FTOA_CARRY))) )
flags = '1';
*s++ = flags;
while (width) {
*s++ = ' ';
width--;
}
*s++ = 0;
return 0;
}