summaryrefslogtreecommitdiff
path: root/libc/stdio
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-01-11 11:42:17 +0000
committerEric Andersen <andersen@codepoet.org>2001-01-11 11:42:17 +0000
commitae97a89e1a1a9833080dccc81f6cd26784e1b964 (patch)
tree6ff1ddc7e3980591c7fd0bbd5d9b8ac82da12886 /libc/stdio
parentabdc3e4d06db2b9d93c509774fc7c4fde918ec8e (diff)
A large update from Manuel Novoa III <mnovoa3@bellsouth.net>.
Diffstat (limited to 'libc/stdio')
-rw-r--r--libc/stdio/Makefile9
-rw-r--r--libc/stdio/printf.c66
-rw-r--r--libc/stdio/stdio.c195
3 files changed, 97 insertions, 173 deletions
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;