diff options
Diffstat (limited to 'libio')
-rw-r--r-- | libio/Makefile | 2 | ||||
-rw-r--r-- | libio/iolibio.h | 5 | ||||
-rw-r--r-- | libio/libio.h | 2 | ||||
-rw-r--r-- | libio/obprintf.c | 164 | ||||
-rw-r--r-- | libio/stdio.h | 10 |
5 files changed, 180 insertions, 3 deletions
diff --git a/libio/Makefile b/libio/Makefile index 0c34125ac6..4266ad4e59 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -32,7 +32,7 @@ routines := \ \ clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar \ memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \ - vdprintf vscanf vsnprintf \ + vdprintf vscanf vsnprintf obprintf \ \ libc_fatal diff --git a/libio/iolibio.h b/libio/iolibio.h index e5de77ea85..92df6a6fd2 100644 --- a/libio/iolibio.h +++ b/libio/iolibio.h @@ -32,6 +32,11 @@ extern int _IO_sprintf __P((char *, const char*, ...)); extern int _IO_ungetc __P((int, _IO_FILE*)); extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list)); extern int _IO_vsprintf __P((char*, const char*, _IO_va_list)); + +struct obstack; +extern int _IO_obstack_vprintf __P ((struct obstack *, const char *, + _IO_va_list)); +extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...)); #ifndef _IO_pos_BAD #define _IO_pos_BAD ((_IO_fpos_t)(-1)) #endif diff --git a/libio/libio.h b/libio/libio.h index 129c7312c2..0cd6b39c24 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -97,7 +97,7 @@ the executable file might be covered by the GNU General Public License. */ /* Magic numbers and bits for the _flags field. The magic numbers use the high-order bits of _flags; - the remaining bits are abailable for variable flags. + the remaining bits are available for variable flags. Note: The magic numbers must all be negative if stdio emulation is desired. */ diff --git a/libio/obprintf.c b/libio/obprintf.c new file mode 100644 index 0000000000..bd629f1ee0 --- /dev/null +++ b/libio/obprintf.c @@ -0,0 +1,164 @@ +/* Print output of stream to given obstack. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include "libioP.h" +#include <string.h> +#include <errno.h> +#include <obstack.h> +#include <stdarg.h> + + +struct _IO_obstack_file +{ + struct _IO_FILE file; + const void *vtable; + struct obstack *obstack; +}; + + +static int +_IO_obstack_overflow (_IO_FILE *fp, int c) +{ + struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; + + /* Make room for another character. This might as well allocate a + new chunk a memory and moves the old contents over. */ + if (c != EOF) + obstack_1grow (obstack, c); + + /* Setup the buffer pointers again. */ + fp->_IO_write_base = obstack_base (obstack); + fp->_IO_write_ptr = obstack_next_free (obstack); + fp->_IO_write_end = fp->_IO_write_base + obstack_room (obstack); + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, fp->_IO_write_end - fp->_IO_write_ptr); + + return c; +} + + +static _IO_size_t +_IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) +{ + struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; + + if (fp->_IO_write_ptr + n > fp->_IO_write_end) + { + /* We need some more memory. First shrink the buffer to the + space we really currently need. */ + obstack_blank (obstack, fp->_IO_write_ptr - fp->_IO_write_end); + + /* Now grow for N bytes. */ + obstack_blank (obstack, n); + + /* Setup the buffer pointers again. */ + fp->_IO_write_base = obstack_base (obstack); + fp->_IO_write_ptr = obstack_next_free (obstack); + fp->_IO_write_end = (fp->_IO_write_base + obstack_room (obstack)); + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, fp->_IO_write_end - fp->_IO_write_ptr); + } + else + { + memcpy (fp->_IO_write_ptr, data, n); + fp->_IO_write_ptr += n; + } + + return n; +} + + +/* the jump table. */ +static struct _IO_jump_t _IO_obstack_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, NULL), + JUMP_INIT(overflow, _IO_obstack_overflow), + JUMP_INIT(underflow, NULL), + JUMP_INIT(uflow, NULL), + JUMP_INIT(pbackfail, NULL), + JUMP_INIT(xsputn, _IO_obstack_xsputn), + JUMP_INIT(xsgetn, NULL), + JUMP_INIT(seekoff, NULL), + JUMP_INIT(seekpos, NULL), + JUMP_INIT(setbuf, NULL), + JUMP_INIT(sync, NULL), + JUMP_INIT(doallocate, NULL), + JUMP_INIT(read, NULL), + JUMP_INIT(write, NULL), + JUMP_INIT(seek, NULL), + JUMP_INIT(close, NULL), + JUMP_INIT(stat, NULL) +}; + + +int +_IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) +{ + struct obstack_FILE + { + struct _IO_obstack_file ofile; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } new_f; + int result; + +#ifdef _IO_MTSAFE_IO + new_f.ofile.file._lock = &new_f.lock; +#endif + + _IO_init ((_IO_FILE *) &new_f.ofile, 0); + _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; + _IO_str_init_static (&new_f.ofile.file, obstack_base (obstack), + (obstack_object_size (obstack) + + obstack_room (obstack)), obstack_next_free (obstack)); + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, + (new_f.ofile.file._IO_write_end + - new_f.ofile.file._IO_write_ptr)); + new_f.ofile.obstack = obstack; + + result = _IO_vfprintf ((_IO_FILE *) &new_f, format, args); + + /* Shrink the buffer to the space we really currently need. */ + obstack_blank (obstack, (new_f.ofile.file._IO_write_ptr + - new_f.ofile.file._IO_write_end)); + + return result; +} +weak_alias (_IO_obstack_vprintf, obstack_vprintf) + + +int +_IO_obstack_printf (struct obstack *obstack, const char *format, ...) +{ + int result; + va_list ap; + va_start (ap, format); + result = _IO_obstack_vprintf (obstack, format, ap); + va_end (ap); + return result; +} +weak_alias (_IO_obstack_printf, obstack_printf) diff --git a/libio/stdio.h b/libio/stdio.h index 7e09786215..75d22f94c0 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -138,7 +138,7 @@ extern char* tmpnam __P ((char*)); #ifdef __USE_REENTRANT extern char* tmpnam_r __P ((char*)); #endif -#ifdef __USE_SVID +#if defined(__USE_SVID) || defined(__USE_XOPEN) extern char *tempnam __P ((__const char *__dir, __const char *__pfx)); #endif extern char *__stdio_gen_tempname __P ((char *__buf, size_t bufsize, @@ -162,6 +162,14 @@ extern int vsscanf __P ((__const char *, __const char *, _G_va_list)); extern int __vsscanf __P ((__const char *, __const char *, _G_va_list)); #endif +#ifdef __USE_GNU +struct obstack; +extern int obstack_vprintf __P ((struct obstack *__obstack, + __const char *__fmt, _G_va_list)); +extern int obstack_printf __P ((struct obstack *__obstack, __const char *__fmt, + ...)); +#endif + #if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE) extern FILE *fdopen __P ((int, __const char *)); extern int fileno __P ((FILE*)); |