Refactor xvfprintf to prepare for pluggable dtoa

This commit is contained in:
Doug Currie 2016-01-08 17:30:21 -05:00
parent be33d016e9
commit 4ef9394c0b
2 changed files with 59 additions and 29 deletions

View File

@ -345,39 +345,12 @@ int xvfprintf(pic_state *pic, xFILE *stream, const char *fmt, va_list ap) {
ival = va_arg(ap, int);
cnt += print_int(pic, stream, ival, 10);
break;
#if PIC_ENABLE_LIBC
case 'f': {
char buf[100];
sprintf(buf, "%g", va_arg(ap, double));
char buf[64];
pic_dtoa(va_arg(ap, double), buf);
cnt += xfputs(pic, buf, stream);
break;
}
#else
# define fabs(x) ((x) >= 0 ? (x) : -(x))
case 'f': {
double dval = va_arg(ap, double);
long lval;
if (dval < 0) {
dval = -dval;
xputc(pic, '-', stream);
cnt++;
}
lval = (long)dval;
cnt += print_int(pic, stream, lval, 10);
xputc(pic, '.', stream);
cnt++;
dval -= lval;
if ((ival = fabs(dval) * 1e4 + 0.5) == 0) {
cnt += xfputs(pic, "0000", stream);
} else {
if (ival < 1000) xputc(pic, '0', stream); cnt++;
if (ival < 100) xputc(pic, '0', stream); cnt++;
if (ival < 10) xputc(pic, '0', stream); cnt++;
cnt += print_int(pic, stream, ival, 10);
}
break;
}
#endif
case 'c':
ival = va_arg(ap, int);
cnt += xfputc(pic, ival, stream);

View File

@ -231,6 +231,7 @@ atof(const char *nptr)
u = u * 10 + (*nptr++ - '0');
}
if (c == '.') {
nptr++;
/* after '.' */
g = 0, e = 0;
while (isdigit(c = *nptr)) {
@ -280,6 +281,62 @@ atof(const char *nptr)
#if PIC_ENABLE_STDIO
# include <stdio.h>
PIC_INLINE void
pic_dtoa(double dval, char *buf)
{
sprintf(buf, "%g", dval);
}
#else
PIC_INLINE void
pic_dtoa(double dval, char *buf)
{
# define fabs(x) ((x) >= 0 ? (x) : -(x))
long lval, tlval;
int ival;
int scnt, ecnt, cnt = 0;
if (dval < 0) {
dval = -dval;
buf[cnt++] = '-';
}
lval = tlval = (long)dval;
scnt = cnt;
do {
buf[cnt++] = '0' + (tlval % 10);
} while ((tlval /= 10) != 0);
ecnt = cnt;
while (scnt < ecnt) {
char c = buf[scnt];
buf[scnt++] = buf[--ecnt];
buf[ecnt] = c;
}
buf[cnt++] = '.';
dval -= lval;
if ((ival = fabs(dval) * 1e4 + 0.5) == 0) {
buf[cnt++] = '0';
buf[cnt++] = '0';
buf[cnt++] = '0';
buf[cnt++] = '0';
} else {
if (ival < 1000) buf[cnt++] = '0';
if (ival < 100) buf[cnt++] = '0';
if (ival < 10) buf[cnt++] = '0';
scnt = cnt;
do {
buf[cnt++] = '0' + (ival % 10);
} while ((ival /= 10) != 0);
ecnt = cnt;
while (scnt < ecnt) {
char c = buf[scnt];
buf[scnt++] = buf[--ecnt];
buf[ecnt] = c;
}
}
buf[cnt] = 0;
}
#endif
#if defined(__cplusplus)