diff options
Diffstat (limited to 'libc/stdio')
-rw-r--r-- | libc/stdio/Makefile | 13 | ||||
-rw-r--r-- | libc/stdio/printf.c | 38 |
2 files changed, 44 insertions, 7 deletions
diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 3801fce2c..2ad7cd737 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -24,6 +24,15 @@ TOPDIR=../ include $(TOPDIR)Rules.mak LIBC=$(TOPDIR)libc.a +PRINTF_FLAGS = + +ifeq ($(HAS_FLOATS),true) + PRINTF_FLAGS += -DWANT_DOUBLE +endif + +ifeq ($(HAS_LONG_LONG),true) + PRINTF_FLAGS += -DWANT_LONG_LONG +endif MSRC=stdio.c MOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ @@ -32,7 +41,7 @@ MOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ MSRC2=printf.c MOBJ2=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o snprintf.o \ - vsnprintf.o asprintf.o vfnprintf.o + vsnprintf.o asprintf.o vfnprintf.o fnprintf.o MSRC3=scanf.c MOBJ3=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o @@ -54,7 +63,7 @@ $(MOBJ): $(MSRC) $(STRIPTOOL) -x -R .note -R .comment $*.o $(MOBJ2): $(MSRC2) - $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(CC) $(CFLAGS) $(PRINTF_FLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o $(MOBJ3): $(MSRC3) diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 0fa7cd038..3a7dda007 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -64,10 +64,16 @@ * call vsnprintf which allocates a fake file on the stack. * Removed WANT_FPUTC option. Always use standard putc macro to avoid * problems with the fake file used by the *s*printf functions. - * Added asprintf. + * Fixed bug parsing flags -- did not restart scan. + * Added function asprintf. * Fixed 0-pad prefixing bug. * Converted sizeof(int) == sizeof(long) tests to compile time vs run time. * This saves 112 bytes of code on i386. + * Fixed precision bug -- when negative set to default. + * Added function fnprintf to support __dtostr. + * Added floating point support for doubles. Yeah! + * + * TODO: long double support */ /*****************************************************************************/ @@ -76,12 +82,15 @@ /* The optional support for long longs and doubles comes in two forms. * * 1) Normal (or partial for doubles) output support. Set to 1 to turn on. - * Adds about 70 bytes for doubles, about 220 bytes for long longs, + * Adds about 130 bytes for doubles, about 220 bytes for long longs, * and about 275 for both to the base code size of 1163 on i386. */ +/* These are now set in the Makefile based on Config. */ +/* #define WANT_LONG_LONG 0 #define WANT_DOUBLE 0 +*/ /* 2) An error message is inserted into the stream, an arg of the * appropriate size is removed from the arglist, and processing @@ -209,6 +218,19 @@ int fprintf(FILE * fp, const char *fmt, ...) } #endif +#ifdef L_fnprintf +int fnprintf(FILE * fp, size_t size, const char *fmt, ...) +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); + rv = vfnprintf(fp, size, fmt, ptr); + va_end(ptr); + return rv; +} +#endif + #ifdef L_vprintf int vprintf(const char *fmt, va_list ap) { @@ -263,7 +285,8 @@ extern char *__ultostr(char *buf, unsigned long uval, int base, int uppercase); extern char *__ltostr(char *buf, long val, int base, int uppercase); extern char *__ulltostr(char *buf, unsigned long long uval, int base, int uppercase); extern char *__lltostr(char *buf, long long val, int base, int uppercase); -extern char *__dtostr(char *buf, double x); +extern int __dtostr(FILE * fp, size_t size, double x, + char flag[], int width, int preci, char mode); enum { FLAG_PLUS = 0, @@ -379,7 +402,7 @@ int vfnprintf(FILE * op, size_t max_size, const char *fmt, va_list ap) if (dpoint) { preci = i; if (i<0) { - preci = 0; + preci = -5; } } else { width = i; @@ -512,7 +535,12 @@ int vfnprintf(FILE * op, size_t max_size, const char *fmt, va_list ap) } else if (p-u_spec < 27) { /* floating point */ #endif /* WANT_DOUBLE || WANT_DOUBLE_ERROR */ #if WANT_DOUBLE - p = __dtostr(tmp + sizeof(tmp) - 1, va_arg(ap, double)); + if (preci < 0) { + preci = 6; + } + cnt += __dtostr(op, max_size, va_arg(ap, double), + flag, width, preci, *fmt); + goto nextfmt; #elif WANT_DOUBLE_ERROR (void) va_arg(ap,double); /* carry on */ p = (char *) dbl_err; |