From ae97a89e1a1a9833080dccc81f6cd26784e1b964 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 11 Jan 2001 11:42:17 +0000 Subject: A large update from Manuel Novoa III . --- libc/stdio/Makefile | 9 +-- libc/stdio/printf.c | 66 ++++++++---------- libc/stdio/stdio.c | 195 +++++++++++++++++----------------------------------- 3 files changed, 97 insertions(+), 173 deletions(-) (limited to 'libc/stdio') diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 49408c95a..5314af07b 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -28,10 +28,11 @@ LIBC=$(TOPDIR)libc.a MSRC=stdio.c MOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ puts.o fread.o fwrite.o fopen.o fclose.o fseek.o rewind.o ftell.o \ - setbuffer.o setvbuf.o ungetc.o + setbuffer.o setvbuf.o ungetc.o _alloc_stdio_buffer.o _free_stdio_buffer.o MSRC2=printf.c -MOBJ2=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o snprintf.o vsnprintf.o +MOBJ2=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o snprintf.o \ + vsnprintf.o _sprintf_fake_file.o vfnprintf.o MSRC3=scanf.c MOBJ3=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o @@ -60,8 +61,8 @@ $(MOBJ3): $(MSRC3) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o -$(COBJS): - $(CC) $(CFLAGS) $< -c $*.c -o $*.o +$(COBJS): %.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ $(STRIPTOOL) -x -R .note -R .comment $*.o $(OBJ): Makefile diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 634885e67..ffca106e4 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -8,7 +8,7 @@ * "It's not reality that's important, but how you perceive things." */ -/* Altered to use stdarg, made the core function vfprintf. +/* Altered to use stdarg, made the core function vfnprintf. * Hooked into the stdio package using 'inside information' * Altered sizeof() assumptions, now assumes all integers except chars * will be either @@ -20,7 +20,7 @@ /* * Manuel Novoa III Dec 2000 * - * The previous vfprintf routine was almost completely rewritten with the + * The previous vfnprintf routine was almost completely rewritten with the * goal of fixing some shortcomings and reducing object size. * * The summary of changes: @@ -52,6 +52,8 @@ * Converted to use my (un)signed long (long) to string routines, which are * smaller than the previous functions and don't require static buffers. * + * Other Modifications: + * Modified sprintf, snprintf, vsprintf, vsnprintf to share on fake-file. */ /*****************************************************************************/ @@ -122,6 +124,14 @@ extern int vfnprintf(FILE * op, size_t max_size, register __const char *fmt, register va_list ap); +extern FILE __sprintf_fake_file[1]; + +#ifdef L__sprintf_fake_file +FILE __sprintf_fake_file[1] = { + {0, 0, (char *) (unsigned) -1, 0, (char *) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; +#endif #ifdef L_printf int printf(const char *fmt, ...) @@ -139,19 +149,14 @@ int printf(const char *fmt, ...) #ifdef L_sprintf int sprintf(char *sp, const char *fmt, ...) { - static FILE string[1] = { - {0, 0, (char *) (unsigned) -1, 0, (char *) (unsigned) -1, -1, - _IOFBF | __MODE_WRITE} - }; - va_list ptr; int rv; va_strt(ptr, fmt); - string->bufpos = sp; - rv = vfnprintf(string, -1, fmt, ptr); + __sprintf_fake_file->bufpos = sp; + rv = vfnprintf(__sprintf_fake_file, -1, fmt, ptr); va_end(ptr); - *(string->bufpos) = 0; + *(__sprintf_fake_file->bufpos) = 0; return rv; } #endif @@ -160,19 +165,14 @@ int sprintf(char *sp, const char *fmt, ...) #ifdef L_snprintf int snprintf(char *sp, size_t size, const char *fmt, ...) { - static FILE string[1] = { - {0, 0, (char *) (unsigned) -1, 0, (char *) (unsigned) -1, -1, - _IOFBF | __MODE_WRITE} - }; - va_list ptr; int rv; va_strt(ptr, fmt); - string->bufpos = sp; - rv = vfnprintf(string, size, fmt, ptr); + __sprintf_fake_file->bufpos = sp; + rv = vfnprintf(__sprintf_fake_file, size, fmt, ptr); va_end(ptr); - *(string->bufpos) = 0; + *(__sprintf_fake_file->bufpos) = 0; return rv; } #endif @@ -200,38 +200,28 @@ int vprintf(const char *fmt, va_list ap) #ifdef L_vsprintf int vsprintf(char *sp, __const char *fmt, va_list ap) { - static FILE string[1] = { - {0, 0, (char *) (unsigned) -1, 0, (char *) (unsigned) -1, -1, - _IOFBF | __MODE_WRITE} - }; - int rv; - string->bufpos = sp; - rv = vfnprintf(string, -1, fmt, ap); - *(string->bufpos) = 0; + __sprintf_fake_file->bufpos = sp; + rv = vfnprintf(__sprintf_fake_file, -1, fmt, ap); + *(__sprintf_fake_file->bufpos) = 0; return rv; } #endif -#ifdef L_vsprintf +#ifdef L_vsnprintf int vsnprintf(char *sp, size_t size, __const char *fmt, va_list ap) { - static FILE string[1] = { - {0, 0, (char *) (unsigned) -1, 0, (char *) (unsigned) -1, -1, - _IOFBF | __MODE_WRITE} - }; - int rv; - string->bufpos = sp; - rv = vfnprintf(string, size, fmt, ap); - *(string->bufpos) = 0; + __sprintf_fake_file->bufpos = sp; + rv = vfnprintf(__sprintf_fake_file, size, fmt, ap); + *(__sprintf_fake_file->bufpos) = 0; return rv; } #endif -#ifdef L_vfprintf +#ifdef L_vfnprintf extern char *__ultostr(char *buf, unsigned long uval, int base, int uppercase); extern char *__ltostr(char *buf, long val, int base, int uppercase); @@ -591,6 +581,10 @@ int vfnprintf(FILE * op, size_t max_size, const char *fmt, va_list ap) return (cnt); } +#endif + +#ifdef L_vfprintf + int vfprintf(FILE * op, register __const char *fmt, register va_list ap) { return (vfnprintf(op, -1, fmt, ap)); diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index fbec9d5a9..32f4b925b 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -28,8 +28,6 @@ #undef STUB_FWRITE -void __init_stdio(void); - extern FILE *__IO_list; /* For fflush at exit */ #define FIXED_BUFFERS 2 @@ -38,47 +36,72 @@ struct fixed_buffer { int used; }; -extern struct fixed_buffer _fixed_buffers[2]; +extern struct fixed_buffer _fixed_buffers[FIXED_BUFFERS]; -#ifdef L__stdio_init +extern unsigned char *_alloc_stdio_buffer(size_t size); +extern void _free_stdio_buffer(unsigned char *buf); -#define buferr (stderr->unbuf) /* Stderr is unbuffered */ +#ifdef L__alloc_stdio_buffer -FILE *__IO_list = 0; /* For fflush at exit */ +unsigned char *_alloc_stdio_buffer(size_t size) +{ + if (size == BUFSIZ) { + int i; -static char *bufin; -static char *bufout; -#ifndef buferr -static char *buferr; + for (i = 0; i < FIXED_BUFFERS; i++) + if (!_fixed_buffers[i].used) { + _fixed_buffers[i].used = 1; + return _fixed_buffers[i].data; + } + } + return malloc(size); +} #endif -FILE stdin[1] = { -#if 0 - {bufin, bufin, bufin, bufin, bufin + BUFSIZ, -#else - {0, 0, 0, 0, 0, +#ifdef L__free_stdio_buffer + +void _free_stdio_buffer(unsigned char *buf) +{ + int i; + + for (i = 0; i < FIXED_BUFFERS; i++) { + if (buf == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + return; + } + } + free(buf); +} #endif - 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} -}; -FILE stdout[1] = { -#if 0 - {bufout, bufout, bufout, bufout, bufout + BUFSIZ, -#else - {0, 0, 0, 0, 0, +#ifdef L__stdio_init + +#if FIXED_BUFFERS < 2 +#error FIXED_BUFFERS must be >= 2 #endif - 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} -}; -FILE stderr[1] = { -#if 0 +#define bufin (_fixed_buffers[0].data) +#define bufout (_fixed_buffers[1].data) +#define buferr (_stdio_streams[3].unbuf) /* Stderr is unbuffered */ + +struct fixed_buffer _fixed_buffers[FIXED_BUFFERS]; + +FILE _stdio_streams[3] = { + {bufin, bufin, bufin, bufin, bufin + BUFSIZ, + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN | __MODE_FREEBUF}, + {bufout, bufout, bufout, bufout, bufout + BUFSIZ, + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN | __MODE_FREEBUF}, {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), -#else - {0, 0, 0, 0, 0, -#endif 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} }; +/* + * Note: the following forces lining of the __init_stdio function if + * any of the stdio functions are used (except perror) since they all + * call fflush directly or indirectly. + */ +FILE *__IO_list = 0; /* For fflush at exit */ + /* Call the stdio initiliser; it's main job it to call atexit */ void __stdio_close_all(void) @@ -96,52 +119,17 @@ void __stdio_close_all(void) } } -static int first_time = 0; - -struct fixed_buffer _fixed_buffers[2]; - - void __init_stdio(void) { - if (first_time) - return; - first_time = 1; - - stdin->bufpos = bufin = _fixed_buffers[0].data; /*(char *)malloc(BUFSIZ) */ ; - stdin->bufread = bufin; - stdin->bufwrite = bufin; - stdin->bufstart = bufin; - stdin->bufend = bufin + sizeof(_fixed_buffers[0].data); - stdin->fd = 0; - stdin->mode = _IOFBF | __MODE_READ | __MODE_IOTRAN | __MODE_FREEBUF; - _fixed_buffers[0].used = 1; - - stdout->bufpos = bufout = _fixed_buffers[1].data; /*(char *)malloc(BUFSIZ); */ - stdout->bufread = bufout; - stdout->bufwrite = bufout; - stdout->bufstart = bufout; - stdout->bufend = bufout + sizeof(_fixed_buffers[1].data); - stdout->fd = 1; - stdout->mode = _IOFBF | __MODE_WRITE | __MODE_IOTRAN | __MODE_FREEBUF; - _fixed_buffers[1].used = 1; -#if 0 - stderr->bufpos = buferr = (char *) malloc(BUFSIZ); -#else - stderr->bufpos = buferr; -#endif - stderr->bufread = buferr; - stderr->bufwrite = buferr; - stderr->bufstart = buferr; - stderr->bufend = buferr + sizeof(buferr); - stderr->fd = 2; - stderr->mode = _IONBF | __MODE_WRITE | __MODE_IOTRAN; - if (isatty(1)) stdout->mode |= _IOLBF; +#if 0 + /* taken care of in _start.c and exit.c now*/ atexit(__stdio_close_all); +#endif } #endif @@ -152,8 +140,6 @@ FILE *fp; { register int v; - __init_stdio(); - v = fp->mode; /* If last op was a read ... */ if ((v & __MODE_READING) && fflush(fp)) @@ -199,8 +185,6 @@ FILE *fp; { int ch; - __init_stdio(); - if (fp->mode & __MODE_WRITING) fflush(fp); @@ -243,8 +227,6 @@ FILE *fp; int len, cc, rv = 0; char *bstart; - __init_stdio(); - if (fp == NULL) { /* On NULL flush the lot. */ if (fflush(stdin)) return EOF; @@ -406,8 +388,6 @@ FILE *fp; int len, v; unsigned bytes, got = 0; - __init_stdio(); - v = fp->mode; /* Want to do this to bring the file pointer up to date */ @@ -611,8 +591,6 @@ const char *mode; int fopen_mode = 0; FILE *nfp = 0; - __init_stdio(); - /* If we've got an fp close the old one (freopen) */ if (fp) { /* Careful, don't de-allocate it */ @@ -684,8 +662,6 @@ const char *mode; /* If this isn't freopen create a (FILE) and buffer for it */ if (fp == 0) { - int i; - fp = nfp; fp->next = __IO_list; __IO_list = fp; @@ -700,15 +676,7 @@ const char *mode; } else fp->mode |= _IOFBF; - for (i = 0; i < FIXED_BUFFERS; i++) - if (!_fixed_buffers[i].used) { - fp->bufstart = _fixed_buffers[i].data; - _fixed_buffers[i].used = 1; - break; - } - - if (i == FIXED_BUFFERS) - fp->bufstart = malloc(BUFSIZ); + fp->bufstart = _alloc_stdio_buffer(BUFSIZ); if (fp->bufstart == 0) { /* Oops, no mem *//* Humm, full buffering with a two(!) byte * buffer. */ @@ -733,8 +701,6 @@ FILE *fp; { int rv = 0; - __init_stdio(); - if (fp == 0) { errno = EINVAL; return EOF; @@ -747,15 +713,7 @@ FILE *fp; fp->fd = -1; if (fp->mode & __MODE_FREEBUF) { - int i; - - for (i = 0; i < FIXED_BUFFERS; i++) - if (fp->bufstart == _fixed_buffers[i].data) { - _fixed_buffers[i].used = 0; - break; - } - if (i == FIXED_BUFFERS) - free(fp->bufstart); + _free_stdio_buffer(fp->bufstart); fp->mode &= ~__MODE_FREEBUF; fp->bufstart = fp->bufend = 0; } @@ -793,15 +751,7 @@ size_t size; return; if (fp->mode & __MODE_FREEBUF) { - int i; - - for (i = 0; i < FIXED_BUFFERS; i++) - if (fp->bufstart == _fixed_buffers[i].data) { - _fixed_buffers[i].used = 0; - break; - } - if (i == FIXED_BUFFERS) - free(fp->bufstart); + _free_stdio_buffer(fp->bufstart); } fp->mode &= ~(__MODE_FREEBUF | __MODE_BUF); @@ -827,15 +777,7 @@ size_t size; { fflush(fp); if (fp->mode & __MODE_FREEBUF) { - int i; - - for (i = 0; i < FIXED_BUFFERS; i++) - if (fp->bufstart == _fixed_buffers[i].data) { - _fixed_buffers[i].used = 0; - break; - } - if (i == FIXED_BUFFERS) - free(fp->bufstart); + _free_stdio_buffer(fp->bufstart); } fp->mode &= ~(__MODE_FREEBUF | __MODE_BUF); fp->bufstart = fp->unbuf; @@ -847,23 +789,10 @@ size_t size; size = BUFSIZ; } if (buf == 0) { - if (size == BUFSIZ) { - int i; - - for (i = 0; i < FIXED_BUFFERS; i++) - if (!_fixed_buffers[i].used) { - _fixed_buffers[i].used = 1; - buf = _fixed_buffers[i].data; - break; - } - if (i == FIXED_BUFFERS) - buf = malloc(size); - } else { - buf = malloc(size); - } + buf = _alloc_stdio_buffer(size); + if (buf == 0) + return EOF; } - if (buf == 0) - return EOF; fp->bufstart = buf; fp->bufend = buf + size; -- cgit v1.2.3