summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authormrg <mrg@NetBSD.org>1998-03-29 08:32:21 +0000
committermrg <mrg@NetBSD.org>1998-03-29 08:32:21 +0000
commit5f094689c8d52818e87b683c91c519f2e23fe90b (patch)
tree164a57302042fdc4389271aacf0d90d1bbe74c23 /gnu
parent1d9ec375c03e61d8a3d986cfa9e47e8060cf509a (diff)
initial import of the egcs 1.0.2 c++ io library
Diffstat (limited to 'gnu')
-rw-r--r--gnu/dist/libio/ChangeLog2451
-rw-r--r--gnu/dist/libio/Makefile.in127
-rw-r--r--gnu/dist/libio/NEWS57
-rw-r--r--gnu/dist/libio/PlotFile.cc157
-rw-r--r--gnu/dist/libio/PlotFile.h89
-rw-r--r--gnu/dist/libio/README30
-rw-r--r--gnu/dist/libio/SFile.cc82
-rw-r--r--gnu/dist/libio/SFile.h55
-rw-r--r--gnu/dist/libio/builtinbuf.cc78
-rw-r--r--gnu/dist/libio/builtinbuf.h68
-rw-r--r--gnu/dist/libio/cleanup.c17
-rw-r--r--gnu/dist/libio/config.shared486
-rw-r--r--gnu/dist/libio/config/hpux.mt3
-rw-r--r--gnu/dist/libio/config/isc.mt4
-rw-r--r--gnu/dist/libio/config/linux.mt28
-rw-r--r--gnu/dist/libio/config/linuxaxp1-libc-lock.h112
-rw-r--r--gnu/dist/libio/config/linuxaxp1-stdio-lock.h36
-rw-r--r--gnu/dist/libio/config/linuxaxp1.mt10
-rw-r--r--gnu/dist/libio/config/linuxlibc1.mt26
-rw-r--r--gnu/dist/libio/config/mn10200.mt3
-rw-r--r--gnu/dist/libio/config/mtsafe.mt2
-rw-r--r--gnu/dist/libio/config/netware.mt16
-rw-r--r--gnu/dist/libio/config/sco4.mt3
-rw-r--r--gnu/dist/libio/configure.in133
-rw-r--r--gnu/dist/libio/dbz/Makefile.in218
-rw-r--r--gnu/dist/libio/dbz/README25
-rw-r--r--gnu/dist/libio/dbz/altbytes7
-rw-r--r--gnu/dist/libio/dbz/byteflip.c38
-rw-r--r--gnu/dist/libio/dbz/case.c129
-rw-r--r--gnu/dist/libio/dbz/case.h12
-rw-r--r--gnu/dist/libio/dbz/configure.in17
-rw-r--r--gnu/dist/libio/dbz/dbz.1221
-rw-r--r--gnu/dist/libio/dbz/dbz.3z547
-rw-r--r--gnu/dist/libio/dbz/dbz.c1768
-rw-r--r--gnu/dist/libio/dbz/dbz.h32
-rw-r--r--gnu/dist/libio/dbz/dbzmain.c519
-rw-r--r--gnu/dist/libio/dbz/fake.c144
-rw-r--r--gnu/dist/libio/dbz/firstlast2550
-rw-r--r--gnu/dist/libio/dbz/getmap6
-rw-r--r--gnu/dist/libio/dbz/random.c31
-rw-r--r--gnu/dist/libio/dbz/revbytes7
-rw-r--r--gnu/dist/libio/dbz/stdio.h1
-rw-r--r--gnu/dist/libio/depend352
-rw-r--r--gnu/dist/libio/editbuf.cc717
-rw-r--r--gnu/dist/libio/editbuf.h185
-rw-r--r--gnu/dist/libio/filebuf.cc215
-rw-r--r--gnu/dist/libio/filedoalloc.c110
-rw-r--r--gnu/dist/libio/fileops.c814
-rw-r--r--gnu/dist/libio/floatconv.c2375
-rw-r--r--gnu/dist/libio/floatio.h51
-rw-r--r--gnu/dist/libio/fstream.cc110
-rw-r--r--gnu/dist/libio/fstream.h92
-rw-r--r--gnu/dist/libio/gen-params734
-rw-r--r--gnu/dist/libio/genops.c944
-rw-r--r--gnu/dist/libio/include/empty.h37
-rw-r--r--gnu/dist/libio/indstream.cc121
-rw-r--r--gnu/dist/libio/indstream.h77
-rw-r--r--gnu/dist/libio/ioassign.cc49
-rw-r--r--gnu/dist/libio/ioextend.cc132
-rw-r--r--gnu/dist/libio/iofclose.c62
-rw-r--r--gnu/dist/libio/iofdopen.c134
-rw-r--r--gnu/dist/libio/iofeof.c43
-rw-r--r--gnu/dist/libio/ioferror.c43
-rw-r--r--gnu/dist/libio/iofflush.c49
-rw-r--r--gnu/dist/libio/iofflush_u.c40
-rw-r--r--gnu/dist/libio/iofgetpos.c55
-rw-r--r--gnu/dist/libio/iofgets.c56
-rw-r--r--gnu/dist/libio/iofopen.c64
-rw-r--r--gnu/dist/libio/iofprintf.c51
-rw-r--r--gnu/dist/libio/iofputs.c49
-rw-r--r--gnu/dist/libio/iofread.c49
-rw-r--r--gnu/dist/libio/iofscanf.c48
-rw-r--r--gnu/dist/libio/iofsetpos.c56
-rw-r--r--gnu/dist/libio/ioftell.c53
-rw-r--r--gnu/dist/libio/iofwrite.c54
-rw-r--r--gnu/dist/libio/iogetc.c48
-rw-r--r--gnu/dist/libio/iogetdelim.c125
-rw-r--r--gnu/dist/libio/iogetline.c112
-rw-r--r--gnu/dist/libio/iogets.c71
-rw-r--r--gnu/dist/libio/ioignore.c47
-rw-r--r--gnu/dist/libio/iolibio.h63
-rw-r--r--gnu/dist/libio/iomanip.cc90
-rw-r--r--gnu/dist/libio/iomanip.h176
-rw-r--r--gnu/dist/libio/iopadn.c70
-rw-r--r--gnu/dist/libio/ioperror.c22
-rw-r--r--gnu/dist/libio/iopopen.c251
-rw-r--r--gnu/dist/libio/ioprims.c80
-rw-r--r--gnu/dist/libio/ioprintf.c47
-rw-r--r--gnu/dist/libio/ioputc.c42
-rw-r--r--gnu/dist/libio/ioputs.c49
-rw-r--r--gnu/dist/libio/ioscanf.c47
-rw-r--r--gnu/dist/libio/ioseekoff.c54
-rw-r--r--gnu/dist/libio/ioseekpos.c48
-rw-r--r--gnu/dist/libio/iosetbuffer.c46
-rw-r--r--gnu/dist/libio/iosetvbuf.c100
-rw-r--r--gnu/dist/libio/iosprintf.c50
-rw-r--r--gnu/dist/libio/iosscanf.c47
-rw-r--r--gnu/dist/libio/iostdio.h114
-rw-r--r--gnu/dist/libio/iostream.cc990
-rw-r--r--gnu/dist/libio/iostream.h272
-rw-r--r--gnu/dist/libio/iostream.texi1971
-rw-r--r--gnu/dist/libio/iostreamP.h26
-rw-r--r--gnu/dist/libio/iostrerror.c12
-rw-r--r--gnu/dist/libio/ioungetc.c46
-rw-r--r--gnu/dist/libio/iovfprintf.c890
-rw-r--r--gnu/dist/libio/iovfscanf.c790
-rw-r--r--gnu/dist/libio/iovsprintf.c61
-rw-r--r--gnu/dist/libio/iovsscanf.c58
-rw-r--r--gnu/dist/libio/isgetline.cc143
-rw-r--r--gnu/dist/libio/isgetsb.cc59
-rw-r--r--gnu/dist/libio/isscan.cc45
-rw-r--r--gnu/dist/libio/istream.h25
-rw-r--r--gnu/dist/libio/libio.h356
-rw-r--r--gnu/dist/libio/libioP.h641
-rw-r--r--gnu/dist/libio/osform.cc66
-rw-r--r--gnu/dist/libio/ostream.h25
-rw-r--r--gnu/dist/libio/outfloat.c211
-rw-r--r--gnu/dist/libio/parsestream.cc317
-rw-r--r--gnu/dist/libio/parsestream.h156
-rw-r--r--gnu/dist/libio/peekc.c42
-rw-r--r--gnu/dist/libio/pfstream.cc92
-rw-r--r--gnu/dist/libio/pfstream.h59
-rw-r--r--gnu/dist/libio/procbuf.cc55
-rw-r--r--gnu/dist/libio/procbuf.h50
-rw-r--r--gnu/dist/libio/sbform.cc40
-rw-r--r--gnu/dist/libio/sbgetline.cc31
-rw-r--r--gnu/dist/libio/sbscan.cc45
-rw-r--r--gnu/dist/libio/stdfiles.c51
-rw-r--r--gnu/dist/libio/stdio/ChangeLog133
-rw-r--r--gnu/dist/libio/stdio/Makefile.in35
-rw-r--r--gnu/dist/libio/stdio/clearerr.c30
-rw-r--r--gnu/dist/libio/stdio/clearerr_u.c28
-rw-r--r--gnu/dist/libio/stdio/configure.in48
-rw-r--r--gnu/dist/libio/stdio/fdopen.c9
-rw-r--r--gnu/dist/libio/stdio/feof.c43
-rw-r--r--gnu/dist/libio/stdio/feof_u.c37
-rw-r--r--gnu/dist/libio/stdio/ferror.c43
-rw-r--r--gnu/dist/libio/stdio/ferror_u.c37
-rw-r--r--gnu/dist/libio/stdio/fgetc.c40
-rw-r--r--gnu/dist/libio/stdio/fileno.c49
-rw-r--r--gnu/dist/libio/stdio/fputc.c41
-rw-r--r--gnu/dist/libio/stdio/fputc_u.c38
-rw-r--r--gnu/dist/libio/stdio/freopen.c44
-rw-r--r--gnu/dist/libio/stdio/fseek.c42
-rw-r--r--gnu/dist/libio/stdio/getc.c48
-rw-r--r--gnu/dist/libio/stdio/getc_u.c37
-rw-r--r--gnu/dist/libio/stdio/getchar.c40
-rw-r--r--gnu/dist/libio/stdio/getchar_u.c35
-rw-r--r--gnu/dist/libio/stdio/getline.c13
-rw-r--r--gnu/dist/libio/stdio/getw.c13
-rw-r--r--gnu/dist/libio/stdio/obprintf.c168
-rw-r--r--gnu/dist/libio/stdio/popen.c23
-rw-r--r--gnu/dist/libio/stdio/putc.c42
-rw-r--r--gnu/dist/libio/stdio/putc_u.c31
-rw-r--r--gnu/dist/libio/stdio/putchar.c35
-rw-r--r--gnu/dist/libio/stdio/putchar_u.c30
-rw-r--r--gnu/dist/libio/stdio/putw.c15
-rw-r--r--gnu/dist/libio/stdio/rewind.c38
-rw-r--r--gnu/dist/libio/stdio/setbuf.c35
-rw-r--r--gnu/dist/libio/stdio/setfileno.c17
-rw-r--r--gnu/dist/libio/stdio/setlinebuf.c36
-rw-r--r--gnu/dist/libio/stdio/snprintf.c51
-rw-r--r--gnu/dist/libio/stdio/stdio.h219
-rw-r--r--gnu/dist/libio/stdio/vasprintf.c72
-rw-r--r--gnu/dist/libio/stdio/vfprintf.c35
-rw-r--r--gnu/dist/libio/stdio/vfscanf.c36
-rw-r--r--gnu/dist/libio/stdio/vprintf.c33
-rw-r--r--gnu/dist/libio/stdio/vscanf.c41
-rw-r--r--gnu/dist/libio/stdio/vsnprintf.c136
-rw-r--r--gnu/dist/libio/stdiostream.cc159
-rw-r--r--gnu/dist/libio/stdiostream.h79
-rw-r--r--gnu/dist/libio/stdstrbufs.cc126
-rw-r--r--gnu/dist/libio/stdstreams.cc153
-rw-r--r--gnu/dist/libio/stream.cc170
-rw-r--r--gnu/dist/libio/stream.h59
-rw-r--r--gnu/dist/libio/streambuf.cc364
-rw-r--r--gnu/dist/libio/streambuf.h488
-rw-r--r--gnu/dist/libio/strfile.h63
-rw-r--r--gnu/dist/libio/strops.c303
-rw-r--r--gnu/dist/libio/strstream.cc116
-rw-r--r--gnu/dist/libio/strstream.h113
181 files changed, 29459 insertions, 0 deletions
diff --git a/gnu/dist/libio/ChangeLog b/gnu/dist/libio/ChangeLog
new file mode 100644
index 00000000000..73bf40993bd
--- /dev/null
+++ b/gnu/dist/libio/ChangeLog
@@ -0,0 +1,2451 @@
+1998-02-24 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ Changes for _G_IO_IO_FILE_VERSION == 0x20001:
+ * libioP.h (_IO_showmanyc_t, _IO_SHOWMANYC, _IO_imbue_t,
+ _IO_IMBUE): New definitions.
+ (struct _IO_jump_t): Add __showmanyc and __imbue fields.
+ (_IO_file_fopen): Add new fourth argument.
+ * filebuf.cc (filebuf::open): Pass new fourth argument to
+ _IO_file_fopen.
+ * iolibio.h (_IO_freopen): Likewise.
+ * streambuf.cc (streambuf::showmanyc, streambuf::imbue): New
+ functions.
+ * streambuf.h (_IO_wchar_t): Define to _G_wchar_t.
+ (ios::fill): Remove casts.
+ (struct streambuf): Add showmanyc and imbue members.
+
+ * iostream.cc (ostream::operator<<(double n)) [__GLIBC_MINOR__ >=
+ 1]: Initialize new fields is_char of struct printf_info.
+ (ostream::operator<<(long double n)) [__GLIBC_MINOR__ >= 1]:
+ Likewise.
+
+Tue Feb 24 20:57:39 1998 H.J. Lu (hjl@gnu.org)
+
+ * configure.in (topsrcdir): New.
+ (CHECK_SUBDIRS, configdirs): Check ${topsrcdir}/gcc instead.
+ (config-ml.in): Use ${topsrcdir}/config-ml.in.
+
+ * tests/configure.in (topsrcdir): New.
+ (CHECK): Check ${topsrcdir}/gcc instead.
+
+ * configure.in (CHECK_SUBDIRS): Set to testsuite only if
+ ${srcdir}/../gcc exists.
+ (configdirs): Include testsuite only if ${srcdir}/../gcc exists.
+
+ * tests/Makefile.in (check): Depend on $(CHECK).
+
+ * tests/configure.in (CHECK): Set to "check-iostream
+ check-stdio" if ${srcdir}/../../gcc doesn't exists.
+
+1998-02-17 Andreas Schwab (schwab@issan.informatik.uni-dortmund.de)
+
+ * iostream.cc (istream::operator>>(long double&))
+ [!_G_HAVE_LONG_DOUBLE_IO]: Scan value into separate variable, in
+ case long double is bigger than double.
+ (ostream::operator<<(double)) [_G_HAVE_PRINTF_FP]: Fix order of
+ initializers of struct printf_info to match declaration order,
+ to work around g++ bug.
+ (ostream::operator<<(long double)) [_G_HAVE_PRINTF_FP]: Likewise.
+
+ * gen-params: Add missing quotes. Avoid useless use of command
+ substitution.
+
+Tue Feb 17 21:52:44 1998 H.J. Lu (hjl@gnu.org)
+
+ * config/linux.mt (IO_OBJECTS): Add iogetline.o.
+ * config/linuxlibc1.mt: Ditto.
+
+ * iogetline.c (_IO_getline_info): Renamed from _IO_getline.
+ (_IO_getline): Just call _IO_getline_info.
+
+ * isgetline.cc (istream::getline, istream::get, _sb_readline):
+ Call _IO_getline_info instead of _IO_getline and get the EOF
+ information.
+ * sbgetline.cc (streambuf::sgetline): Ditto.
+
+ * libioP.h (_IO_getline_info): New declaration.
+
+ * iogetline.c (_IO_getline): Handle the case when there is no
+ buffer.
+
+ * filebuf.cc (filebuf::open): Call _IO_file_open if
+ _G_HAVE_IO_FILE_OPEN is 1.
+
+ * libio.h (_IO_fpos64_t, _IO_off64_t): Defined if
+ _G_IO_IO_FILE_VERSION == 0x20001.
+
+ * libioP.h (_IO_file_open): New declaration.
+
+ * libio.h (_IO_FILE, _IO_stdin_, _IO_stdout_, _IO_stderr_,
+ _IO_seekoff, _IO_seekpos): Add support for libio in egcs 2.1.
+ * libioP.h (_IO_seekoff_t, _IO_seekpos_t, _IO_seek_t,
+ _IO_seekoff, _IO_seekpos, _IO_default_seekoff,
+ _IO_default_seekpos, _IO_default_seek, _IO_file_seekoff,
+ _IO_file_seek, _IO_str_seekoff, _IO_pos_BAD, _IO_pos_as_off,
+ _IO_pos_0): Ditto.
+ * streambuf.h (streamoff, streampos): Ditto.
+
+ * gen-params (__extension__): Use only if gcc version >= 2.8.
+
+Sun Feb 15 21:11:25 1998 Krister Walfridsson (cato@df.lth.se)
+
+ * fileops.c: #include <unistd.h>.
+ * ioprims.c: Likewise.
+ * dbz/dbz.c (putconf): Handle systems which use "long long" as type
+ for "off_t".
+ * dbz/dbzmain.c (mkfiles): Likewise.
+
+Fri Dec 19 09:35:48 1997 H.J. Lu (hjl@gnu.org)
+
+ * configure.in (target frags): Add *-linux-gnu.
+
+ * streambuf.cc (streambuf::~streambuf): Don't delete _lock
+ for _IO_stdin/_IO_stdout/_IO_stderr.
+
+Thu Nov 27 01:32:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (insatll): Change gxx_includedir to gcc_include_dir.
+ * config.shared (gxx_includedir): Remove default definition.
+ * config/linux.mt: Change gxx_includedir to gxx_include_dir.
+ * config/linuxaxp1.mt: Likewise.
+
+Wed Nov 26 16:08:50 1997 Richard Henderson (rth@cygnus.com)
+
+ * configure.in (target frags): Add powerpc*-linux-gnulibc1.
+ (stdio-lock): Similarly.
+
+ * configure.in (target frags): Add alpha*-linux-gnulibc1.
+ (pic frags): Its alpha*- not alpha-.
+ (stdio-lock): Kill everything. Add alpha*-linux-gnulibc1.
+ * libio.h: Check __GLIBC_MINOR__ to find stdio-lock.h. If not
+ _IO_MTSAFE_IO & GLIBC, make sure the lock pointer is still there.
+ * libioP.h: Check __GLIBC_MINOR__ to find libc-lock.h.
+
+ * config/linuxaxp1-libc-lock.h: New file.
+ * config/linuxaxp1-stdio-lock.h: New file.
+ * config/linuxaxp1.mt: New file.
+
+ * gen-params (va_list): Check for and use __gnuc_va_list.
+ (NULL): Work around some linux kernel headers and redefine NULL.
+
+Tue Nov 18 09:53:58 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * stdstrbufs.cc (DEF_STDFILE): Use STD_VTABLE.
+
+Tue Nov 11 01:40:17 1997 Oleg Krivosheev <kriol@fnal.gov>
+
+ * iomanip.h: Fix guiding decls.
+
+Wed Oct 29 23:01:47 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * gen-params: Override NULL.
+
+Wed Oct 22 19:19:32 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * libio.h (_IO_LOCK_T): Handle glibc 2 when _IO_MTSAFE_IO is
+ not defined.
+
+ * iovsscanf.c (vsscanf): Make it weak alias of _IO_vsscanf if
+ __linux__ is defined instead of __ELF__
+
+ * config/linuxlibc1.mt (USER_INCLUDES): Add libio.h.
+
+1997-10-15 Ulrich Drepper <drepper@cygnus.com>
+
+ * configure.in: Create compatibility code in bits/libc-lock.h file.
+
+Thu Oct 9 07:08:41 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * libio.h (_IO_LOCK_T): Handle glibc 2 when _IO_MTSAFE_IO is
+ not defined.
+
+ * filedoalloc.c (_IO_file_doallocate): Don't call
+ _IO_cleanup_registration_needed if __linux__ is defined.
+
+ * iofclose.c (fclose): Make it weak alias of _IO_fclose if
+ __ELF__ is defined.
+
+ * iovsprintf.c (vsprintf): Make it weak alias of _IO_vsprintf
+ if __ELF__ is defined.
+
+ * iovsscanf.c (vsscanf): Make it weak alias of _IO_vsscanf if
+ __ELF__ is defined.
+
+ * config/linuxlibc1.mt (MT_CFLAGS): Defined as -D_G_HAVE_MMAP.
+ (IO_OBJECTS): Add filedoalloc.o fileops.o genops.o iofclose.o
+ iovsprintf.o iovsscanf.o strops.o.
+
+Fri Oct 3 10:13:13 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * iostream.cc, libio.h: Convert other uses of #ifdef
+ _G_HAVE_PRINTF_FP to #if.
+
+1997-10-02 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * iostream.cc (operator<<): Use `#if _G_HAVE_PRINTF_FP', not ifdef.
+
+Thu Oct 2 10:36:49 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * gen-params: Fix __printf_fp test.
+ * config/linuxlibc1.mt (gxx_includedir): Don't define.
+
+Thu Oct 2 10:36:26 1997 Ulrich Drepper <drepper@rtl.cygnus.com>
+
+ * config/linuxlibc1.mt (_G_CONFIG_H): Don't define.
+ * gen-params: Add test for __printf_fp.
+
+Sun Sep 28 12:09:04 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * iomanip.h: Use new friend <> syntax.
+
+Sun Sep 28 12:04:21 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * libio.h: Don't use _IO_LOCK_T if it's not defined.
+
+Fri Sep 26 20:56:41 1997 Ulrich Drepper <drepper@rtl.cygnus.com>
+
+ Based on a patch by H.J. Lu (hjl@gnu.ai.mit.edu).
+
+ * Makefile.in (STDIO_OBJECTS): New. Defined as stdfiles.o.
+ (LIBIO_OBJECTS): Add $(STDIO_OBJECTS).
+ (PICFLAG): New, empty. moved to here from config.shared.
+
+ * config.shared (DISTCLEAN): Add target-mkfrag.
+ (PICFLAG): Removed.
+
+ * configure.in (*-linux-gnulibc1): Remove warning.
+ (*-linux-gnu): Use linux.mt mtsafe.mt.
+ (alpha-*-linux*): Use mh-elfalphapic.
+
+ * gen-params (_G_ullong): Also check unsigned long long int.
+ (_G_llong): Also check long long int.
+
+ * libio.h (_IO_lock_t): Add support for the Linux libc 5.
+ (_IO_peekc): Defined as _IO_peekc_unlocked if _IO_MTSAFE_IO
+ is not defined.
+
+ * iostream.cc (__cvt_double): Fix a typo in declaration.
+ (info): Use expr != 0 to initialize the bit fields. Don't
+ initialize "extra" for the Linux libc 5.
+
+ * streambuf.h (_G_NEED_STDARG_H): Changed from _IO_NEED_STDARG_H.
+
+ * config/linux.mt (STDIO_OBJECTS): New, empty.
+ (MT_CFLAGS): Removed.
+
+ * config/linuxlibc1.mt: Rewrite. it's identical to linux.mt but
+ IO_OBJECTS mentions files not in early libc5 versions.
+
+ * config/mtsafe.mt: New.
+
+ * dbz/Makefile.in (check): Support make -j.
+
+ * tests/tFile.cc (tempfile): Fix a typo.
+
+Fri Sep 19 11:52:25 1997 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (LIBIO_OBJECTS): Depend on _G_CONFIG_H.
+
+1997-09-17 04:08 Ulrich Drepper <drepper@cygnus.com>
+
+ * iostream.cc: Add forward declaration for __cvt_double.
+ * libio.h: Define _IO_USE_DTOA is _G_HAVE_PRINTF_FP is not defined.
+ * strops.c (_IO_str_count): Correct last change.
+
+1997-09-17 02:50 Ulrich Drepper <drepper@cygnus.com>
+
+ * libioP.h: Define __set_errno if not already defined.
+ * fileops.c: Don't try to define __set_errno, it's already defined.
+
+1997-09-15 02:37 Ulrich Drepper <drepper@cygnus.com>
+
+ * config/linux.mt: Rewrite for use with glibc 2.
+ * config/linuxlibc1.mt: Old content of linux.mt, fir libc4 and
+ libc5.
+
+ * config.shared (COMPILE.c): Allow new flags in MT_CFLAGS be
+ passed.
+ (COMPILE.cc): Likewise.
+
+ * configure.in (*-linux*): Remove goal. We now have...
+ (*-linux-gnulibc1): For libc4 and libc5. Emit warning.
+ (*-linux-gnu)): For glibc 2.
+ Create links to find headers for multi-threading if necessary.
+
+ * fileops.c: Make thread-safe by using _IO_cleanup_region_start
+ etc to handle cancelation. Acquire locks in functions which are
+ called directly.
+ (_IO_file_read, _IO_file_write): Remove dead code.
+
+ * include/empty.h: Define stub macros for locking.
+
+ * iolibio.h: Add prototypes for obstack printing functions.
+
+ * ioseekoff.c (_IO_seekoff): Lock stream before working.
+ * ioseekpos.c (_IO_seekpos): Likewise.
+
+ * iostream.cc: Add support for long double I/O.
+ Use __printf_fp from glibc is available.
+ Use _IO_cleanup_region_start to handle cancelation correctly.
+ * iostream.h (class ostream): Change opfx and osfx to lock/unlock
+ stream
+ (class istream): Likewise for ipfx, ipfx0, ipfx1, and isfx.
+ Declare new function lock and unlock for ostream and istream.
+ * osform.cc: Use _IO_cleanup_region_start to handle cancelation
+ correctly.
+
+ * libio.h: Update from glibc version. Pretty printing.
+ * libioP.h: Likewise.
+
+ * outfloat.c: Only compile if _IO_USE_DTOA is defined.
+
+ * stdio/feof.c: Make thread safe.
+ * stdio/ferror.c: Likewise.
+ * stdio/getc.c : Likewise.
+ * stdio/putc.c : Likewise.
+ * stdio/stdio.h: Declare function of thread-safe API.
+
+ * stdio/obprintf.c: New file.
+ * stdio/vasprintf.c: New file.
+
+ * stdio-lock.h: Removed.
+
+ * stdstrbufs.c: Add definitions for thread-safe streams.
+
+ * streambuf.cc: Initialize lock.
+
+ * strops.c (_IO_str_count): Undo last change.
+
+ * tests/tFile.cc: Support parallel builds by avoiding fixed
+ name for test file.
+
+Thu Sep 11 18:43:56 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (iostream.list): Remove STDIO_WRAP_OBJECTS.
+
+Mon Sep 8 01:30:27 1997 Weiwen Liu <liu@hepunix.physics.yale.edu>
+
+ * libio.h: Fix typo.
+
+Sun Sep 7 23:00:18 1997 Jim Wilson (wilson@cygnus.com)
+
+ * linux.mt (LIBIOSTREAM_DEP): Change stdio.list to stmp-stdio.
+
+Fri Sep 5 09:58:43 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (iostream.list): Instead of adding stdio.list, add
+ STDIO_WRAP_OBJECTS.
+ (iostream.list): Lose dependency on stmp-stdio, not necessary for
+ our stuff. The stdio stuff is present here just for uniformity
+ with glibc.
+
+Thu Sep 4 17:26:22 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * parsestream.cc (general_parsebuf): Cast return of malloc to char*.
+
+1997-09-04 16:11 Ulrich Drepper <drepper@cygnus.com>
+
+ Change compared to version initially intended to in:
+ * strops.c (_IO_str_count): Still use _IO_write_ptr, not
+ _IO_write_end, for now.
+
+ * iofeof.c, ioferror.c, iofflush_u.c, iogetc.c, ioputc.c, peekc.c,
+ stdio-lock.h: New files.
+
+ * include: New dir.
+ * include/empty.h: New header.
+
+ * filedoalloc.c: Update and reformat copyright.
+ Don't use DEFUN.
+ Use __set_errno throughout the code to support multi-threaded
+ programs.
+ Correct layout to follow the Coding Standard.
+ Add casts to prevent warnings.
+ * fileops.c: Likewise.
+ * genops.c: Likewise.
+ * iofclose.c: Likewise.
+ * iofdopen.c: Likewise.
+ * iofflush.c: Likewise.
+ * iofgetpos.c: Likewise.
+ * iofgets.c: Likewise.
+ * iofopen.c: Likewise.
+ * iofprintf.c: Likewise.
+ * iofputs.c: Likewise.
+ * iofread.c: Likewise.
+ * iofsetpos.c: Likewise.
+ * ioftell.c: Likewise.
+ * iofwrite.c: Likewise.
+ * iogetdelim.c: Likewise.
+ * iogetline.c: Likewise.
+ * iogets.c: Likewise.
+ * iopadn.c: Likewise.
+ * iopopen.c: Likewise.
+ * ioputs.c: Likewise.
+ * ioseekoff.c: Likewise.
+ * iosetbuffer.c: Likewise.
+ * iosetvbuf.c: Likewise.
+ * iosprintf.c: Likewise.
+ * ioungetc.c: Likewise.
+ * iovsprintf.c: Likewise.
+ * iovsscanf.c: Likewise.
+ * libio.h: Likewise.
+ * libioP.h: Likewise.
+ * stdfiles.c: Likewise.
+ * strfile.h: Likewise.
+ * strops.c: Likewise.
+
+ * Makefile.in (IO_OBJECTS): Add peekc.o, iogetc.o, ioputc.o,
+ iofeof.o, and ioferror.o.
+ (iostream.list): Depend upon stmp-stdio. Add the entries
+ from stdio.list to iostream.list.
+ (stmp-stdio): New name for what was the stdio/stdio.list rule.
+ All it now does is cd down into stdio and build stdio.list.
+
+ * configure.in (ALL): Add libiostream.a.
+
+ * libio.h [_IO_MTSFE_IO]: Include header declaring locking code.
+ Otherwise define opaque _IO_lock_t.
+ Define _IO_cookie_file.
+ Rename _IO_getc to _IO_getc_unlocked, _IO_peekc to _IO_peekc_unlocked,
+ _IO_putc to _IO_putc_unlocked, _IO_feof to _IO_feof_unclocked, and
+ _IO_ferror to _IO_ferror_unlocked.
+ Add prototypes for _IO_getc, _IO_putc, _IO_feof, _IO_ferror,
+ and _IO_peekc_locked.
+ Add declarations for _IO_flockfile, _IO_funlockfile, and
+ _IO_ftrylockfile. If !_IO_MTSAFE_IO define _IO_flockfile,
+ _IO_funlockfile, _IO_ftrylockfile, _IO_cleanup_region_start, and
+ _IO_cleanup_region_end as empty macros.
+
+ * libioP.h: Change type of finish function to take an additional int
+ argument and change declaration of finish functions.
+ Add prototypes for _IO_seekoff and _IO_seekpos.
+ If _G_HAVE_MMAP is defined use stream buffers allocated with mmap.
+ Redefine FREE_BUF and ALLOC_BUF macros to help in both situations.
+ (FILEBUF_LITERAL): If we compile for a thread-safe library also
+ initialize lock member.
+
+ * filedoalloc.c: Take care for systems already defining _POSIX_SOURCE.
+ Keep name space clean on systems which require this.
+ (_IO_file_doallocate): Adopt ALLOC_BUF call for changed semantic.
+
+ * fileops.c: Keep name space clean on systems which require this.
+ (_IO_file_attach): Don't fail if seek failed because it's used on a
+ pipe.
+ (_IO_file_underflow): Update buffer pointers before calling `read'
+ since the `read' might not return anymore.
+ (_IO_file_overflow): If stream allows no writes set error flag.
+ (_IO_seekoff): Make sure that after flushing the file pointer in
+ the underlying file is exact.
+ (_IO_file_read): Don't restart `read' syscall if it return EINTR.
+ This violates POSIX.
+ (_IO_file_write): Likewise for `write'.
+ (_IO_cleanup): Install as exit handler in glibc.
+
+ * genops.c (_IO_setb): Correctly use FREE_BUF.
+ (_IO_default_doallocate): Correctly use ALLOC_BUF.
+ (_IO_init): Initialize lock in stream structure.
+ (_IO_default_finish): Destroy lock.
+ (_IO_get_column): Don't compile since it's not needed.
+ (_IO_nobackup_default): Likewise.
+
+ * iopopen.c: Take care for systems already defining _POSIX_SOURCE.
+ Correct _IO_fork and _IO_dup2 prototypes.
+
+ * iofclose.c: Acquire lock before starting the work.
+ * iofflush.c: Likewise.
+ * iofgetpos.c: Likewise.
+ * iofgets.c: Likewise.
+ * iofputs.c: Likewise.
+ * iofread.c: Likewise.
+ * iofsetpos.c: Likewise.
+ * ioftell.c: Likewise.
+ * iofwrite.c: Likewise.
+ * iogetdelim.c: Likewise.
+ * iogets.c: Likewise.
+ * ioputs.c: Likewise.
+ * iosetbuffer.c: Likewise.
+ * iosetvbuf.c: Likewise.
+ * ioungetc.c: Likewise.
+
+ * iofdopen.c: Create and initialize lock for new stream.
+ * iofopen.c: Likewise.
+ * iopopen.c (_IO_popen): Likewise.
+ * iovsprintf.c: Likewise.
+ * iovsscanf.c: Likewise.
+
+ * genops.c: Make weak aliases for various functions.
+ * iofclose.c: Likewise.
+ * iofdopen.c: Likewise.
+ * iofflush.c: Likewise.
+ * iofgetpos.c: Likewise.
+ * iofgets.c: Likewise.
+ * iofopen.c: Likewise.
+ * iofputs.c: Likewise.
+ * iofread.c: Likewise.
+ * iofsetpos.c: Likewise.
+ * ioftell.c: Likewise.
+ * iofwrite.c: Likewise.
+ * iogetdelim.c: Likewise.
+ * iogets.c: Likewise.
+ * ioputs.c: Likewise.
+ * iosetbuffer.c: Likewise.
+ * iosetvbuf.c: Likewise.
+ * ioungetc.c: Likewise.
+ * iovsprintf.c: Likewise.
+ * iovsscanf.c: Likewise.
+
+ * iofflush_u.c: New file. fflush_unlocked implementation.
+
+ * iostream.h [_G_HAVE_LONG_DOUBLE_IO]: Declare real long double
+ output operator.
+
+ * peekc.c: New file. Implement _IO_peekc_locked function.
+
+ * stdfiles.c: If we compile for a thread-safe library also define
+ lock variable.
+
+Tue Aug 26 12:24:01 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * testsuite/Makefile.in (check): Don't depend on site.exp.
+ (just-check): Depend on site.exp.
+
+Wed Aug 20 02:01:34 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * iostream.h: Add copy assignment ops for _IO_?stream_withassign.
+
+Tue Jul 22 10:31:41 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config.shared (CHECK_SUBDIRS): Use install-sh, not install.sh.
+
+Wed Jun 25 12:20:55 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config.shared (DOING_GPERF): Look for this, defining TOLIBGXX
+ and LIBS for it.
+
+Wed Jun 18 11:03:34 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config.shared (FLAGS_TO_PASS): Don't include RUNTEST.
+
+Tue Jun 17 22:23:48 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config.shared (FLAGS_TO_PASS): Pass RUNTEST and RUNTESTFLAGS.
+
+Fri May 16 21:08:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * iovfprintf.c: Declare __cvt_double before use.
+
+ * floatconv.c (d2b): Use _G_int32_t instead of int for the
+ e and bits parameters.
+ (_IO_strtod): Use _G_int32_t.
+
+ * gen-params: Look for NO_USE_DTOA and USE_INT32_FLAGS.
+
+ * strops.c (_IO_str_init_static): use _G_int32_t appropriately.
+
+ * libio.h: If _G_NO_USE_DTOA is set, then don't define
+ _IO_USE_DTOA.
+
+ * config/mn10200.mt: Don't use dtoa, it only works
+ for "real" doubles.
+
+Thu May 15 17:44:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in: Set CHECK_SUBDIRS to testsuite if we're doing
+ a cross compile.
+
+ * config.shared(check): Only run make check in the directories
+ specified by CHECK_SUBDIRS. Set CHECK_SUBDIRS to SUBDIRS
+ if it has no previous value.
+
+Thu May 1 17:35:19 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (test, tpipe): Add $(CFLAGS).
+
+Wed Apr 30 12:16:29 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in: Don't turn on multilib here.
+
+Sat Apr 26 13:38:21 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in (configdirs): Add testsuite directory.
+
+ * testsuite/ChangeLog:
+ * testsuite/Makefile.in:
+ * testsuite/libio.tests/tiomanip.exp:
+ * testsuite/libio.tests/tstdiomisc.exp:
+ * testsuite/libio.tests/tiomisc.exp:
+ * testsuite/libio.tests/tFile.exp:
+ * testsuite/libio.tests/tfformat.exp:
+ * testsuite/libio.tests/tiformat.exp:
+ * testsuite/libio.tests/hounddog.exp:
+ * testsuite/libio.tests/putbackdog.exp:
+ * testsuite/configure.in:
+ * testsuite/lib/libio.exp:
+ * testsuite/config/default.exp:
+ New files for DejaGnu-style testsuite.
+
+Fri Apr 4 03:16:44 1997 Ulrich Drepper <drepepr@cygnus.com>
+
+ * configure.in: Enable multilibing by default.
+ Update multilib template to read config-ml.in.
+
+ * floatconv.c: Enable use in cross targets which use the
+ newlib ieeefp.h header.
+
+Thu Jan 23 09:16:16 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * libioP.h (_IO_file_attach): Delete redundant decl.
+
+Tue Jan 21 22:13:45 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * streambuf.h (class ios): Take out STREAMSIZE member, since we
+ only need (and should only have) the global one.
+
+Tue Jan 7 14:02:40 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * iostream.h (long long fns): Use __extension__.
+
+ * gen-params: Use _G_llong and _G_ullong instead of long long for
+ deduced types.
+
+Fri Dec 6 13:13:30 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dbz/dbz.c: Use off_t.
+
+Sat Nov 23 15:44:37 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (install): Don't install _G_config.h with other headers.
+
+Mon Nov 18 17:12:41 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * config.shared (SUBDIRS): Use -O instead of -O3 for debugging.
+
+Sun Nov 3 12:43:34 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * iostream.cc (write_int): Treat string literals as const.
+
+Thu Sep 26 10:09:18 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * depend: Regenerate.
+
+Wed Sep 25 22:54:45 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * config.shared (depend.new): Deal with headers that don't end in .h.
+
+Thu Aug 29 17:05:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+
+Mon Aug 5 01:26:32 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * config{ure.in,.shared} (DISTCLEAN): Add multilib.out.
+
+Fri Aug 2 17:39:35 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * libio.h (NULL): Use __null.
+ * libioP.h (NULL): Ditto.
+ * streambuf.h (NULL): Ditto.
+ * ioextend.cc (get_array_element): Use NULL instead of (void*)0.
+
+Fri Jul 5 18:26:41 1996 Jim Wilson <wilson@cygnus.com>
+
+ * strfile.h (struct _IO_streambuf): New struct type.
+ (struct _IO_strfile): Use it.
+
+Tue Jun 18 18:24:21 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * fstream.h (fstreambase): Make __my_fb mutable.
+ From Joe Buck.
+
+Tue Jun 18 11:03:53 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * dbz/fake.c (main): Set return type to int.
+ * dbz/dbzmain.c (main): Likewise.
+ * dbz/byteflip.c (main): Likewise.
+
+Mon Jun 17 14:05:36 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * gen-params: Check if clog conflicts with system libraries.
+ * stdstreams.cc: If it does, use __IO_clog.
+ * iostream.h: Likewise.
+
+Tue Jun 11 13:39:31 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * stdiostream.h (istdiostream (FILE*)): Put istream base
+ initializer before init for __f.
+ (ostdiostream (FILE*)): Likewise for ostream base init.
+
+Tue May 14 11:47:21 1996 Per Bothner <bothner@andros.cygnus.com>
+
+ * strfile.h (_IO_str_fields): Removed _len field.
+ (_IO_STR_DYNAMIC, _IO_STR_FROZEN): new macros.
+ * strstream.h (strstreambuf::is_static): Removed.
+ (strstreambuf::frozen): Use _IO_STR_DYNAMIC instead of is_static.
+ * strstream.h, strstream.cc: Remove support for !_IO_NEW_STREAMS.
+ * strstream.cc (strstreambuf::init_dynamic): Don't set _s._len.
+ * strops.c (_IO_str_init_static): Better handling of the
+ negative (== unbounded) size case.
+ (_IO_str_overflow, _IO_str_underflow, _IO_str_count): Re-write
+ to not use _s._len, and otherwise cleanup/fix.
+ * strstream.h, strstream.cc (strstreambase::strstreambase()): Call
+ ios::init here.
+ (other constructors): Simplify - init already called.
+
+Tue May 14 10:55:21 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ Change so that strstreambuf default constructor does no allocation.
+ * strstream.h (strstreambuf::init_dynamic): Default initial size = 0.
+ * strstream.cc (strstreambuf::init_dynamic): Don't allocate a
+ buffer (yet) if initial_size is 0.
+ * strops.c (_IO_str_overflow): Add 100 to size of re-allocated
+ buffer, to handle case when initial size is 0.
+
+ * iostdio.h (remove, rename, tmpfile, tempnam): Comment out.
+
+Mon May 13 23:19:39 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * fileops.c (_IO_file_close_it): Just call _IO_do_flush rather
+ than _IO_file_sync, to avoid useless lseek.
+
+Tue May 14 10:48:48 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * floatconv.c (_IO_strtod): Force rv into the stack.
+
+ * config.shared (gxx_includedir): Now $(includedir)/g++.
+
+Sat Apr 27 02:37:49 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * libioP.h (JUMP*): Implement for thunks.
+ (_IO_jump_t): Add second dummy field for thunks.
+
+Thu Apr 25 13:20:00 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * config.shared (CXX): Use gcc, not g++.
+
+Wed Apr 24 10:29:50 1996 Doug Evans <dje@blues.cygnus.com>
+
+ * config.shared (depend.new): Delete $(srcdir)/ from foo.{c,cc}
+ for SunOS VPATH.
+ * depend: Regenerated.
+
+Fri Apr 19 17:24:51 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Version 2.8.0b3.
+
+Wed Apr 10 17:16:01 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in (ALL): Don't build iostream.a.
+
+Mon Apr 8 14:44:11 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iosetvbuf.c (_IO_setvbuf): Clear _IO_UNBUFFERED unless _IONBF.
+
+Mon Apr 8 15:08:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+
+Fri Apr 5 17:48:56 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.shared (MOSTLYCLEAN): Also remove ${EXTRA_MOSTLYCLEAN}.
+
+Fri Mar 22 23:25:00 1996 Ulrich Drepper <drepepr@gnu.ai.mit.edu>
+
+ * genops.c (_IO_sputbackc, _IO_sungetc): Clear EOF flag if putsh
+ back was successful.
+
+Wed Mar 27 11:54:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Version 2.8.0b2.
+
+Fri Mar 22 15:39:36 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * fileops.c (_IO_do_write): Revert previous fix. (It fails to
+ handle the case that fp->_IO_read_end != fp->_IO_write_base.)
+ (_IO_file_overflow): Instead, if _IO_read_ptr is at the end of
+ the buffer, reset all the read pointers to _IO_buf_base.
+
+Tue Mar 12 12:03:17 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * fileops.c (_IO_do_write): Even if to_do==0, must re-set buffer
+ pointers. Bug and solution from Luke Blanshard <luke@cs.wisc.edu>.
+
+Wed Feb 28 10:00:24 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Version 2.8.0b1.
+
+Tue Feb 27 18:08:16 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iopopen.c (_IO_proc_open): Use (char*)0 rather than imprecise NULL.
+
+ * streambuf.h (ios): Add ios::binary; deprecate ios::bin.
+ * filebuf.cc (filebuf::open): Handle ios::binary.
+
+Fri Feb 9 12:40:19 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cleanup.c (_IO_cleanup_registration_needed) [!_G_HAVE_ATEXIT]: Init
+ to NULL.
+ * filedoalloc.c (_IO_cleanup_registration_needed): Remove decl.
+
+Thu Feb 8 08:12:50 1996 Brendan Kehoe <brendan@cygnus.com>
+
+ * filedoalloc.c (_IO_cleanup_registration_needed): Revert previous
+ change, since cleanup.c only defines it if _G_HAVE_ATEXIT.
+
+Wed Feb 7 15:10:17 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * filedoalloc.c (_IO_cleanup_registration_needed): Declare as extern.
+
+Tue Dec 12 17:21:13 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * indstream.h, instream.cc (indirectbuf::uflow): New method.
+ * indstream.cc (indirectbuf::underflow): Fix to use sgetc, not sbumpc.
+ Fixes bug reported by Kevin Beyer <beyer@cs.wisc.edu>.
+
+ * indstream.cc (indirectbuf::seekpos): Add paranoia test.
+
+Fri Dec 8 14:55:34 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stream.h: Add warning to not use these functions.
+ * stream.cc (str, chr): Re-implement here (from libg++).
+
+Tue Nov 28 15:07:01 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.shared: Use test instead of [ to avoid DEC Unix lossage.
+
+Thu Nov 23 14:51:43 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iopopen.c: Move #include <sys/types.h> ahead of #include <signal.h>
+ to deal with BSDI's literal implementation of Posix.
+
+Sat Nov 25 11:21:55 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (install): Set rootme.
+ * config.shared (TOPDIR): Set with ${foo-...} rather than ${foo=...}.
+ (INSTALL): Handle absolute, dot, relative-not-dot values of srcdir.
+ (TEXIDIR): Likewise.
+
+Tue Nov 21 14:12:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check ${with_cross_host} rather than comparing
+ ${host} and ${target}.
+
+Mon Nov 20 13:55:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in: Match *-sco3.2v[45]*.
+
+Wed Nov 15 20:19:31 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config.shared (FLAGS_TO_PASS): Also pass SHLIB and SHCURSES.
+
+Tue Nov 14 01:41:08 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.shared (TO_REAL_TOPDIR): Define.
+ (MULTITOP): Deleted.
+ (MULTISRCTOP, MULTIBUILDTOP): New.
+ (TOPDIR): Change MULTITOP to MULTIBUILDTOP, and use TO_REAL_TOPDIR.
+ (INSTALL): Add with_multisrctop, TO_REAL_TOPDIR.
+ (TEXIDIR): Use TO_REAL_TOPDIR.
+ (LIBS): Delete MULTITOP.
+ (FLAGS_TO_PASS): Add NM.
+ (CXXINCLUDES): Delete MULTITOP.
+ (depend.new): Delete adding MULTITOP to ../ build tree references.
+ Add MULTISRCTOP to ../ source tree references.
+ * configure.in: Delete call to cfg-ml-com.in. Call config-ml.in
+ instead of cfg-ml-pos.in.
+
+Sun Nov 12 16:30:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (VERSION): Set to 2.7.1.
+ * configure.in: Add warning for Linux.
+ * config.shared (DISTCLEAN): Add EXTRA_DISTCLEAN.
+
+ * editbuf.h (edit_mark::index_in_buffer): Avoid unused param warning.
+
+ * iostream.cc (istream::operator>> (char*)): Improve ANSI compliance.
+
+Fri Nov 10 08:41:37 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config.shared (check): Add missing semicolon.
+
+Thu Nov 9 17:27:22 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in (ALL): Remove $(OSPRIM_OBJECTS).
+ * config.shared (check): Set LD_LIBRARY_PATH.
+ * NEWS: Fix typo.
+ * iogetdelim.c (_IO_getdelim): Index *lineptr, rather than lineptr.
+ From alan@spri.levels.unisa.edu.au (Alan Modra).
+
+Mon Nov 6 15:03:33 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * streambuf.cc, editbuf.cc, isgetline.cc, parsestream.cc:
+ Fixes to avoid -Wall warnings.
+
+Fri Nov 3 16:41:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gen-params [!__STDC__]: Include varargs.h instead of stdarg.h.
+
+Thu Nov 2 15:04:03 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.shared: Re-write if X then Y else true fi to (not X) || Y.
+
+Wed Nov 1 13:26:44 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iostream.h (istream::ipfx): Add default argument value.
+ Reported by Yotam Medini <yotam_medini@tmai.com>.
+
+ * libioP.h (_IO_blen): Fix typo.
+ Reported by Bryan T. Vold <btv@ldl.healthpartners.com>.
+
+Fri Oct 27 19:26:20 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (_G_config.h): Set CC to $(CC) rather than to $(CXX),
+ now that CXX defaults to g++ and CC default to gcc (when found).
+ * config.shared: Simplify CXX and CC, since they get overridden
+ by ../configure anyway.
+
+Wed Oct 25 19:45:50 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * iostdio.h: Wrap including the file with #ifndef _IOSTDIO_H.
+
+Wed Oct 25 11:14:25 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * libio.h (_IO_seekoff, _IO_seekpos): New declarations.
+ * libioP.h (_IO_seekoff, _IO_seekpos): Remove declarations.
+ * libioP.h: Cleanup; remove old !_IO_UNIFIED_JUMPTABLES stuff.
+
+ * filebuf.cc (filebuf::~filebuf): Only call SYSYCLOSE if currently
+ open. Bug found by Martin Gerbershagen <ger@ezis-ulm.de>.
+
+ * streambuf.h (streambuf::pubseekoff, streambuf::pubseekpos):
+ Added, from ANSI draft.
+ * filebuf.cc (filebuf::open), iostream.cc (variables places), SFile.cc:
+ Use pubseekoff/pubseekpos rather than sseekoff/sseekpos.
+
+ * Makefile.in (install): Don't install libiostream.a.
+
+ * filedoalloc.c: Also #include <unistd.h>.
+
+Mon Oct 9 18:09:54 1995 Jason Molenda <crash@phydeaux.cygnus.com>
+
+ * config.shared (SUFFIXES): add .c.
+
+Tue Sep 26 16:08:01 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * procbuf.cc: Move #pragma implementation to beginning.
+
+Wed Sep 20 17:53:33 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * procbuf.h, procbuf.cc: Add #pragma interface/implementation stuff.
+
+Wed Sep 20 18:59:00 1995 John Eaton <jwe@bevo.che.wisc.edu>
+
+ * procbuf.h: Protect from being included multiple times.
+
+Wed Sep 20 15:47:14 1995 John Eaton <jwe@bevo.che.wisc.edu>
+
+ * procbuf.h (procbuf): Add '_next' pointer field for compatibility
+ with _IO_proc_file.
+
+Wed Sep 20 13:54:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.shared: Add support for maintainer-clean target as a
+ synonym for realclean.
+ * dbz/Makefile.in: Likewise.
+
+Mon Sep 11 12:11:19 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iopopen.c: #include <sys/types.h> before <sys/wait.h>.
+ This is in accordance with Posix, and needed for ISC.
+
+Fri Sep 8 00:11:55 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gen-params: Use double quotes in the eval setting $TYPE to
+ $VALUE, to preserve any single quotes in $VALUE.
+
+Mon Aug 21 11:39:09 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gen-params: Test for an appropriate version of gcc before using
+ mode attributes.
+
+ * config.shared: Add $(PICDIR) to $ALL.
+
+Mon Aug 7 17:51:40 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gen-params: Generate new macro _G_HAVE_SYS_CDEFS.
+ * libio.h: If _G_HAVE_SYS_CDEFS, get __P from <sys/cdefs.h>.
+
+Fri Aug 4 23:21:17 1995 Paul Eggert <eggert@twinsun.com>
+
+ * gen-params: When following typedef changes, allow typedefs
+ that do not have a space before the defined type name,
+ e.g. `typedef void *__gnuc_va_list;' as in Linux. Also,
+ not require a space in the definiens, e.g. `typedef void*foo;'.
+
+Thu Aug 3 17:54:15 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iostream.h, iostream.cc (istream::sync): Added missing method.
+
+Thu Aug 3 17:49:34 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in: Remove netbsd special case.
+ * config/netbsd.mt: Removed; no longer used.
+
+Tue Jun 20 16:07:12 1995 Paul Eggert <eggert@twinsun.com>
+
+ * gen-params: Take transitive closure of `typedef' relation.
+ This is needed for BSD/OS 2.0, which has
+ fpos_t -> off_t -> quad_t -> long long.
+
+Mon Jul 24 18:28:10 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.shared (TOPDIR): Delete extra '/', $rootme may be empty.
+
+Sat Jul 22 13:27:45 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.shared (depend.new): Fix quoting in DO NOT EDIT line.
+
+ * Makefile.in (_G_config.h): Add multilib support.
+ (install): Likewise.
+ * config.shared: Likewise.
+ * configure.in: Likewise.
+
+Wed Jun 28 17:40:25 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * PlotFile.h, SFile.h, builtinbuf.h, editbuf.h, fstream.h,
+ indstream.h, iomanip.h, iostream.h, parsestream.h, pfstream.h,
+ procbuf.h, stdiostream.h, stream.h, streambuf.h, strstream.h: Wrap
+ with extern "C++".
+
+Thu Jun 22 04:34:01 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gen-params: Surround attributes with __.
+
+Mon Jun 19 00:33:22 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * config.shared (SUBDIRS): Massage broken shells that require
+ 'else true'.
+
+Sat Jun 17 11:25:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * streambuf.h: Declare inline members inline in class.
+
+Thu Jun 15 20:45:13 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (VERSION): Update to version 2.7.0.
+
+Wed Jun 14 21:41:11 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * Makefile.in (STDIO_WRAP_OBJECTS): Remove stdfiles.o.
+ (LIBIO_OBJECTS): Add stdfiles.o.
+
+Wed Jun 7 16:11:36 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * config.shared (all): Appease bash.
+
+Wed Jun 7 11:16:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * configure.in (MOSTLYCLEAN): Remove stamp-picdir.
+
+ * config.shared (MOSTLYCLEAN): Ditto.
+ (CLEAN): Don't.
+
+Mon Jun 5 18:29:39 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * config/mh-*pic: Removed.
+
+ * configure.in (MOSTLYCLEAN): Remove pic objects.
+ (frags): Use toplevel pic fragments.
+
+ * config.shared (CXXFLAGS): Use -O3.
+ (PICFLAG, PICDIR): New macros.
+ (all): Depend on $(PICDIR).
+ (FLAGS_TO_PASS): Pass PICFLAG.
+ (.x.o): Also build pic object.
+ (stamp-picdir): Create directory for pic objects.
+ (MOSTLYCLEAN): Remove pic objects.
+ (CLEAN): Remove stamp-picdir.
+
+ * Makefile.in (iostream.list): Depend on stamp-picdir.
+ (c++clean): Don't remove _G_config.h.
+
+Mon Jun 5 15:03:47 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * strstream.h, strstream.cc (strstream::strstream()): Re-implement to
+ be like ostrstream::ostrestream(), and not leak memory.
+
+ * streambuf.h: Use #if !_IO_UNIFIED_JUMPTABLES instead of #ifndef.
+
+ * iolibio.h (_IO_rewind): Add missing flags when calling _IO_seekoff.
+
+Thu May 25 22:30:21 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/netbsd.mt (G_CONFIG_ARGS): Add defn for off_t. Another
+ layer of typedefs has been added and the gen-params script can
+ not handle it.
+
+Wed May 10 03:02:58 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * iolibio.h (_IO_rewind): Add new argument to _IO_seekoff.
+
+ * config/linux.mt (LIBIOSTREAM_OBJECTS): Include $(STDIO_WRAP_OBJECTS).
+ (LIBIOSTREAM_DEP): Include stdio.list.
+ (LIBIOSTREAM_USE): Include `cat stdio.list`.
+
+ * Makefile.in (LIBIOSTREAM_DEP): New variable.
+ (LIBIOSTREAM_USE): Ditto.
+ (libiostream.a): Use them.
+ (iostream.list): Ditto.
+ (stdio.list): New rule.
+ (stdio/stdio.list): Ditto.
+
+Tue May 9 18:29:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * libioP.h (_IO_jump_t): Change TYPE for __dummy from int to
+ _G_size_t.
+
+Sat May 6 13:50:37 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * libio.h (_IO_UNIFIED_JUMPTABLES): #define as true.
+ (_IO_FILE): Remove _jumps field (#if _IO_UNIFIED_JUMPTABLES).
+
+ * libioP.h (enum _IO_seekflags_): Removed.
+
+ * libioP.h (_IO_setbuf_t): Change return value of setpos jumptable
+ function to match C++ streambuf::setpos. (Return NULL on failure.)
+ * fileops.c (_IO_file_setbuf), genops.c (_IO_default_setbuf),
+ filebuf.cc, iosetvbuf.c: Update to use new setbuf conventions.
+
+ * streambuf.h (streambuf): Re-order virtual functions more logically.
+ * streambuf.cc (streambuf::uflow), streambuf.h: New virtual.
+ * libioP.h (struct _IO_jump_t): Define using new JUMP_FIELD macro.
+ And re-order in more logical order consistent with streambuf vtable.
+ * fileops.c (_IO_file_jumps), iopopen.c (_IO_proc_jumps), iovfprintf.c
+ (_IO_helper_jumps), streambuf.cc (_IO_streambuf_jumps), strops.c
+ (_IO_str_jumps): Update accordingly, using JUMP_INIT macro.
+ * stdfiles.c: Set vtable to point to _IO_file_jumps.
+ * filebuf.cc, iopopen.c, iovfprintf.c (helper_vfprintf), iovsprintf.c,
+ iovsscanf.c: Use macros and #if to set jumptables.
+
+ * streambuf.c: _IO_streambuf_jumps and the _IO_sb_* methods are not
+ needed #if _IO_UNIFIED_JUMPTABLES.
+ * filebuf.cc (filebuf::__new): Also no longer needed.
+ * fstream.cc (fstreambase::__fb_init, fstreambase::fstreambase): Fix.
+ * stdstrbufs.c: Use filebuf vtable instead of builtinbuf's.
+ * builtinbuf.h, builtinbuf.cc (builtinbuf): Commented out #if
+ _IO_UNIFIED_JUMPTABLES - no longer needed.
+ * strstream.cc (SET_STR_JUMPS): Does nothing now.
+
+ * builtinbuf.cc, fileops.c, genops.c, iofgetpos.c, iofsetpos.c,
+ ioftell.c, iopopen.c, ioseekoff.c, ioseekpos.c, iosetvbuf.c,
+ iovfprintf.c, iovfscanf.c, strops.c: Use DEFUN and DEFUN_VOID.
+ * filebuf.cc, fileops.c, genops.c, iopopen.c, ioseekoff.c, ioseekpos.c,
+ iosetvbuf.c, iovfscanf.c: Use new JUMP_* and IO_OVERFLOW/... macros.
+
+ * libioP.h (_IO_seekpos_t): Third arg is now an int (using _IOS_INPUT
+ and _IOS_OUTPUT), not an enum _IO_seekflags_. Flags values are
+ changed, and their sense inverted (to match streambuf::seekpos).
+ * libioP.h (_IO_seekoff_t): Similarly match streambuf::seekoff.
+ * filebuf.cc, fileops.c (_IO_file_fopen, _IO_file_seekoff), genops.c
+ (_IO_default_seekpos, _IO_default_seekpos), iofgetpos.c, iofsetpos.c,
+ iolibio.h (_IO_fseek), ioftell.c, ioseekoff.c, ioseekpos.c,
+ iostream.cc, streambuf.cc, strops.c (_IO_str_seekoff), strstream.cc:
+ New seekpos/seekoff conventions.
+ * iostreamP.h (convert_to_seekflags): Removed - no longer needed.
+
+ * iolibio.h (_IO_fread): New declaration.
+
+ * dbz/Makefile.in: Re-arrange for cleaner dependencies.
+
+Fri May 5 15:55:22 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * libioP.h (_IO_JUMPS. JUMP_FIELD, JUMP0, JUMP1, JUMP2, JUMP3,
+ JUMP_INIT, _IO_FINISH, _IO_OVERFLOW, ... _IO_SYSSTAT): New macros
+ in preparation for new unified jumptable/vtable implementation.
+ * cleanup.c, filedoalloc.c, iofclose.c, iofflush.c, iofiledoalloc.c,
+ ioprims.c, iosetbuffer.c, iostrerror.c, ioungetc.c: Use DEFUN.
+ * filedoalloc.c, iofclose, iofflush, iosetbuffer.c: Use new macros.
+
+ * iofopen.c, iofdopen.c: Use macros and #if for new jumptables.
+
+ * gen-params: Do not #include <sys/types.h>.
+ Add missing quote in 'eval'.
+ Do add #include <sys/types.h> in test for <sys/resource.h>.
+ * config/netbsd.mt: New file, defining _G_CONFIG_ARGS (for fpos_t).
+ * configure.in: Use netbsd.mt for NetBSD.
+
+Wed May 3 15:03:47 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * libioP.h (DEFUN, DEFUN_VOID, AND): New macros, from ansidecl.h.
+ * iofdopen.c, iofgets.c, iofopen.c, iofputs.c, iofread.c, iofwrite.c,
+ iogetdelim.c, iogetline.c, iogets.c, ioignore.c, iopadn.c, ioperror.c,
+ ioputs.c, iovsprintf.c, iovsscanf.c, outfloat.c: Use DEFUN.
+
+Mon May 1 16:22:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gen-params: #include <sys/types.h>. Don't use __WCHAR_TYPE__ in
+ definition of _G_wchar_t. Use __attribute__ ((mode)) to get
+ specific-sized ints under gcc, don't worry about int8 or int64
+ otherwise. Provide defaults if deduction fails.
+
+Thu Apr 27 18:27:53 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * streambuf.h (ios::~ios): Delete _arrays.
+ (_IO_NEW_STREAMS): Turn on.
+ * libio.h (__adjust_column): Remove bogus declaration.
+ * genops.c (_IO_set_column): Fix typo (in commented-out code).
+
+Tue Apr 25 17:14:29 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * config.shared (CXXINCLUDES): Use a shell variable with a
+ different name from the make variable.
+ * configure.in: Update accordingly.
+
+Mon Apr 17 17:19:40 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * streambuf.h (__adjust_column): Remove redundant declaration.
+
+Sat Apr 15 11:39:25 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.shared (do-clean-dvi): Also remove *.cps.
+
+ * gen-params: Use ${SED} instead of sed.
+
+ * libio.h: Remove #if'd out stuff (confuses makedepend).
+
+ * stdstreams.cc (STD_STR): Standard streams start with ios::dec set.
+
+Fri Apr 14 23:46:31 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iostream.h, iostream.cc (istream::read, ostream::write):
+ Use streamsize for the length parameter.
+
+ * streambuf.h: Removed redundant __overflow and __underflow.
+
+ * fstream.h, fstream.cc: Add void fstreambase::attach(int).
+
+ * iosscanf.c (_IO_sscanf): Fix non-__STDC__ missing declaration.
+
+Mon Apr 3 15:40:55 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * indstream.*: Fix prototypes of xsputn and xsgetn.
+
+ * fileops.c: Avoid ??? trigraph.
+
+Mon Mar 27 16:16:38 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * iomanip.h (operator<< (ostream&, const omanip<TP>&): Define
+ separately.
+ (operator>> (istream&, const imanip<TP>&): Ditto.
+
+Mon Mar 27 08:56:00 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * builtinbuf.cc (builtinbuf::setbuf): Cast NULL to streambuf*, to
+ avoid warning/error about conversion from void*.
+ * indstream.cc (indirectbuf::seekoff): Likewise.
+ (indirectbuf::seekpos): Likewise.
+ * filebuf.cc (filebuf::setbuf): Likewise.
+ (filebuf::close): Cast NULL to filebuf*.
+
+Wed Mar 1 14:23:18 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in (DISTCLEAN): Add, with target-mkfrag.
+
+Fri Feb 24 01:01:08 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * configure.in (frags): Don't require so many dashes in the
+ canonical target name.
+
+Sat Feb 18 13:18:30 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * streambuf.cc (streambuf::sync): Always return 0, even for
+ non-flushed output. This is required by the ANSI/ISO draft.
+ * genops.c (_IO_sync): Likewise always return 0.
+
+Fri Feb 17 16:33:28 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * fileops.c (_IO_file_close_it): Call _IO_file_sync, rather
+ than _IO_do_flush, because we want to adjust the file pointer
+ if reading and not at end (as in SVR4, and as in fflush).
+ Also, make sure to return error indication if sync fails.
+ (_IO_file_sync): Ignore seek error if it is ESPIPE.
+ (_IO_file_seekoff): If not readable, do dumb lseek.
+ * iofclose.c (_IO_fclose): If closing a non-filebuf, return -1
+ if _IO_ERR_SEEN.
+
+Fri Feb 17 19:31:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gen-params: Check for struct tms in <sys/times.h>, defining
+ HAVE_SYS_TIMES accordingly.
+
+Wed Feb 15 21:05:11 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * strops.c (_IO_str_count): Use LEN macro.
+ (_IO_str_seekoff): Update _len field.
+
+Mon Feb 6 19:29:00 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gen-params: Default to short, long and long long for 16, 32 and
+ 64 bit types, in case detection fails.
+
+Wed Jan 25 18:07:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * gen-params (_G_wint_t): Allow for broken promotions.
+
+Tue Jan 24 16:15:40 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * stdstrbufs.cc (_IO_fake_stdiobufs): Add an extra layer of struct,
+ to force correct alignment on i960s.
+ (DEF_STDIOBUF, _IO_{stdin,stdout,stderr}_buf): Update accordingly.
+
+Thu Jan 19 18:30:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * config.shared (CXXINCLUDES): Add libstdc++ to includes for
+ building libg++.
+ (LIBS): Also link with libstdc++ when building libg++ toys.
+ Don't set EXPORT_ALL_VARIABLES; users will have to set
+ LD_LIBRARY_PATH themselves.
+
+Fri Dec 30 16:38:13 1994 Mike Stump <mrs@cygnus.com>
+
+ * config/linux.mt: Fix build problem on linux 1.0.8.
+
+Thu Dec 22 11:49:45 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/netware.mt: Use gcc to pre-link iostream.nlm's objects
+ instead of using nlmconv, so that references to functions in
+ libgcc.a are resolved.
+
+ * configure.in: Append .mt to target makefile fragment file names.
+
+ * floatconv.c (tens, tinytens, bigtens): Added const qualifier.
+
+Tue Dec 20 09:59:50 1994 Mike Stump <mrs@cygnus.com>
+
+ * gen-params (VTABLE_LABEL_PREFIX): Since some systems have GNU nm
+ as nm, and they demangle by default, we have to notice this, and
+ try --no-cplus (linux) or --no-demangle when running nm.
+
+Wed Dec 14 18:13:58 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * gen-params: To determine vt-name-mangling using dummy.C add
+ #include and #prama interface/implementation to avoid problem with
+ assemblers that don't emit local symbols. Reported under HPUX 8
+ by Thomas Arend <arend@blasius.Chemietechnik.Uni-Dortmund.DE>.
+
+ * streambuf.h (ios::ios): Move inline definition after
+ that of ios::init (which ios::ios calls).
+
+Sun Dec 4 19:50:32 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * fileops.c (_IO_file_init, _IO_file_close_it, _IO_file_sync):
+ Set _offset to _IO_pos_BAD, to support applications that follow
+ POSIX.1 rules on mixing file handles.
+
+ * fileops.c (_IO_file_overflow): Handle case that buffer was
+ allocated (perhaps by setvbuf) but _IO_write_base is still 0.
+
+ * iostdio.h (setbuffer): #define as _IO_setbuffer.
+ * streambuf.h, filebuf.cc: Removed filebuf::do_write.
+
+Tue Nov 29 23:38:57 1994 Per Bothner (bothner@rtl.cygnus.com)
+
+ * floatconv.c (setword0, setword1): Fix typo.
+
+Tue Nov 29 15:37:29 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.shared: Move -fno-implicit-template from CXXFLAGS
+ to LIBCXXFLAGS. Tests are better run without it.
+
+ * floatconv.c (word0, word1): Re-place/re-implement using unions
+ instead of casts to avoid optimizer problems.
+
+ * dbz/dbzmain.c: Renamed dirname -> dir_name to avoid OSF
+ header file braindamage.
+
+Sat Nov 5 19:44:00 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * config.shared (LIBCFLAGS): Define.
+ (LIBCXXFLAGS): Define.
+ (DOING_LIBGXX): Define TOLIBGXX. Change LIBS to use -lg++. Add
+ LD_LIBRARY_PATH and .EXPORT_ALL_VARIABLES:.
+ (FLAGS_TO_PASS): Add LIBC{,XX}FLAGS.
+ (XC{,XX}FLAGS): Set to LIBCFLAGS or CFLAGS depending on $LIBDIR.
+ (COMPILE.c): Define, use in .c.o rule.
+ (COMPILE.cc): Define, use in .cc.o rule.
+
+Sat Nov 5 15:12:12 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (VERSION): Update to 0.67.
+
+ * streambuf.h (ios::dont_close): Is now set by default.
+ * fstream.h, fstream.cc (__fb_init): New function. Clears
+ ios::dont_close. Change fstreambase constructors to call it.
+ * strstream.cc: *strstream constructors must clear ios::dont_close.
+ * iostream.cc: Simplify - don't need to set ios::dont_close.
+ * ioassign.cc: Simplify - assume ios::dont_close is always set.
+
+ * fstream.h, fstream.cc: If _IO_NEW_STREAMS, put the
+ filebuf as a member __my_fb.
+ * strstream.{h,cc}: Likewile use a strstreambuf member __my_sb.
+ * streambuf.h, stdstreams.cc, ioextend.cc:
+ Fix if _IO_NEW_STREAMS to not use ios::dont_close.
+
+ * streambuf.h (class ios): Move rdbuf later, to avoid
+ inability of g++ to inline.
+ * filebuf.cc (filebuf::~filebuf): Call _IO_do_flush.
+
+ * config.shared: Emit rules to make depend.
+ * depend: New file.
+
+Fri Nov 4 17:19:11 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * README: Fix typos.
+ * libio.h: Add comment. Update Copyright notice.
+
+Fri Nov 4 21:46:30 1994 Paul Eggert <eggert@twinsun.com>
+
+ * libio.h (__P): Change argument name spelling from
+ `paramlist' to `protos' for compatibility with BSDI 1.1.
+
+Thu Nov 3 00:45:16 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * config.shared (CXXFLAGS): Add -fno-implicit-templates.
+
+Mon Oct 24 15:57:35 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.shared: Define NOSTDIC and use it for libio too.
+
+Thu Oct 20 19:45:35 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * iogetdelim.c: #include <stdlib.h>.
+
+Thu Oct 20 17:09:52 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * iostream.h: Add classes _IO_istream_withassign and
+ _IO_ostream_withassign. Re-type cin, cout, cerr, clog.
+ (class iostream): Don't add extra _gcount field.
+ * ioassign.cc: New file. Implement operator= for cin etc.
+ * streambuf.h (class ios): Change return type of operator=.
+ * Makefile.in (IOSTREAM_OBJECTS): Add ioassign.o.
+
+ * Makefile.in: Re-arrange, so linux.mt overrides can work.
+
+ * fileops.c (_IO_file_seekoff): Optimize seeks within buffer.
+
+Wed Oct 19 14:25:47 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * gen-params (wint_t): Return to using __WCHAR_TYPE__ for
+ compatibility with gcc versions prior to 2.6.1.
+
+Tue Oct 18 17:08:18 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in: Define _G_CONFOG_H as _G_config.h for Linux. Use it.
+ (IO_OBJECTS): Add iogetdelim.o.
+ * config/linux.mt: New file.
+ * configure.in: Select config/linux.mt if Linux.
+ * iogetdelim.c: Verious cleanups, many from
+ Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>.
+ * libioP.h: Add _IO_getdelim. Use (void) for no-parameter functions.
+
+Thu Oct 13 16:30:56 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * libio.h: Rename USE_DTOA to _IO_USE_DTOA for namespace reasons.
+ * iostream.cc, iovfscanf.c, iovfprintf, floatconv.c:
+ Update USE_DTOA -> _IO_USE_DTOA.
+
+ * libio.h (_IO_feof, _IO_ferror): Move to here ...
+ * iolibio: ... from here
+
+ * iostream.cc (istream::get, istream::ignore, istream::read):
+ Set _gcount to 0 if ipfx0 failed.
+
+ * iostream.cc (flush): Do virtual function call, rather than
+ going through jumptable. (To get correct method in derived class.)
+ Bug and fix from John Wiegley <jw@cis.ohio-state.edu>.
+
+ * iofdopen.c (O_ACCMODE): Define using O_RDWR, not O_RDWRITE.
+
+ * streambuf.h (ios::rdbuf(streambuf*)): New.
+ * streambuf.h (ios::operator=): Make private (i.e. dis-allow).
+
+Wed Oct 12 19:09:20 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * gen-params: Define _G_NO_NRV and _G_NO_EXTERN_TEMPLATES if not
+ compiling with g++.
+
+Thu Oct 6 16:03:43 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iostream.texi (ostrstream::str): Note that NUL is not written
+ automatically.
+
+Wed Oct 5 17:28:29 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iogetdelim.c (_IO_getdelim): New function.
+
+Wed Oct 5 15:40:22 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/netware.mt: New file, first cut at Netware NLM support.
+ * configure.in (*-*-netware*): Use config/netware.mt.
+
+ * config.shared (NLMCONV, LD): New definition.
+
+ * gen-params: check for nm in ${binutils}/nm.new.
+ * config.shared: Likewise.
+
+Tue Oct 4 12:20:01 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iomanip.h (omanip::operator<<): Make 2nd arg be const.
+ Bug and fix reported by Greg McGary <gkm@magilla.cichlid.com>.
+
+ * strstream.cc (strstreambuf::pcount): Simplify, to match
+ ANSI/ISO specification.
+
+Mon Sep 26 15:19:52 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * gen-params: Include <wchar.h> and <wctype.h> if they exist.
+
+Thu Sep 8 14:41:41 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * iostream.h (class istream): Declare operator>>(long double&).
+ (class ostream): Define operator<<(long double).
+
+ * iostream.cc (istream::operator>>(long double&)): Define.
+
+Wed Sep 7 14:42:29 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iostream.texi (Overflow): Fix bugs in example.
+
+Fri Sep 2 17:45:57 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iostream.tex: Document a little on how to write your
+ own streambuf-derived class, with an example.
+
+Tue Aug 30 13:03:57 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * floatconv.c (s2b): Declare X and Y to be _G_int32_t.
+ (diff, quorem): Declare BORROW, Y, and Z likewise.
+ (ulp): Declare L likewise.
+ (_IO_strtod): Declare L and AADJ likewise.
+ (_IO_dtoa): Declare L and D likewise. Cast division of D by DS to
+ _G_int32_t.
+
+Mon Aug 29 16:01:54 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iosetvbuf.c (_IO_setvbuf): If setting _IOFBF and no
+ buffer was specified, call __doallocate.
+
+ * fileops.c, floatconv.c: Add a bunch of parentheses to
+ shut up gcc warnings. Patch from H.J.Lu.
+
+ * stdiostream.cc (stdiobuf::sys_read): Inline call to getc
+ for the normal case (size==1).
+
+Sat Aug 20 12:14:52 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (VERSION): Increase to 0.66.
+
+Fri Aug 19 17:28:41 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iolibio.h: Added _IO_printf prototype.
+ Added extern "C" { ... } wrappers #ifdef __cplusplus.
+ Bugs reported by Neal Becker <neal@ctd.comsat.com>.
+
+Wed Aug 17 18:17:15 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * fileops.c (_IO_file_seekoff): For _IO_seek_cur, adjust for
+ read-ahead before jumping to label dumb.
+
+Wed Aug 3 13:15:01 1994 H.J. Lu (hjl@nynexst.com)
+
+ * libioP.h (CHECK_FILE(FILE,RET)): new, which checks for
+ FILE == NULL and _IO_MAGIC_MASK.
+ (COERCE_FILE(FILE)): merged into CHECK_FILE(FILE,RET)
+ with typo fixes.
+
+ * iofread.c, iofwrite.c: add CHECK_FILE(fp, 0);
+ * iofclose.c: add CHECK_FILE(fp, EOF); remove _IO_MAGIC_MASK check.
+
+ * iofflush.c, iofgetpos.c, iofputs.c, iofscanf.c,
+ iofsetpos.c, iofvbuf.c, ioungetc.c:
+ Add CHECK_FILE(fp, EOF) and remove COERCE_FILE(fp).
+
+ * iofgets.c: add CHECK_FILE(fp, NULL) and remove COERCE_FILE(fp).
+ * iofprintf.c: add CHECK_FILE(fp, -1) and remove COERCE_FILE(fp).
+ * ioftell.c: add CHECK_FILE(fp, -1L) and remove COERCE_FILE(fp).
+ * iosetbuffer.c: add CHECK_FILE(fp, ) and remove COERCE_FILE(fp).
+
+Fri Aug 12 15:35:39 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iofdopen.c (_IO_fdopen): #define O_ACCMODE if it isn't.
+ Still set O_APPEND if "a" is given, but don't unset it
+ if it isn't. Added comment.
+
+Mon Aug 8 13:11:00 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gen-params (VTABLE_LABEL_PREFIX): Changes in the implementation.
+ For look for _*vt[$_.]7*filebuf in the nm output, because that
+ matches what g++ produces and has produced. Thus it should be
+ somewhat more robust.
+
+Sun Aug 7 22:52:49 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gen-params (CC): Remove no-longer-needed -I options
+ passed to xgcc (now they are implied by the -B options).
+
+Wed Jul 20 16:41:13 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (tooldir): Added definition, so we can do
+ 'make install' in this directory.
+ Bug reported by Klamer Schutte <schutte@tpd.tno.nl>.
+
+Mon Jul 18 18:02:34 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gen-params (VTABLE_LABEL_PREFIX): Remove filename sppearing
+ by itself. Add comment explaining what is going on.
+
+Tue Dec 21 13:02:48 1993 H.J. Lu (hjl@jalod)
+
+ * libio.h: define _IO_uid_t and _IO_HAVE_ST_BLKSIZE
+ as _G_xxxxxxxx.
+
+Tue Dec 21 13:02:48 1993 H.J. Lu (hjl@jalod)
+
+ * iopopen.c: Don't include <errno.h>. It is included in "libioP.h".
+
+ * iopopen.c (_IO_proc_close) : check if fp is on the list
+ before close it.
+
+Thu Jul 14 16:38:47 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gen-params (CONFIG_NM): Make sed scripts to find vtable name
+ mangling more robost for different forms of nm output.
+
+Tue Dec 21 13:02:48 1993 H.J. Lu (hjl@jalod)
+
+ * iofopen.c (_IO_fopen): don't check [redundantly] fp == NULL after
+ IO_file_init(&fp->_file).
+
+ * iomanip.h (template<class TP> class iapp):
+ change ostream to istream.
+
+Tue Jul 12 14:09:02 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (VERSION): Increase to 0.65.
+ * libioP.h (builtinbuf_vtable): Only define #ifdef __cplusplus.
+
+ * gen-params (_G_int8_t): Only define if defined(__STDC__),
+ because K&R C compilers don't have signed char.
+ (_G_int64_t, _G_uint64_t): Only define if defined(__GNUC__)
+ because other compilers may not have long long.
+
+Sun Mar 06 13:10:21 1994 H.J. Lu (hjl@nynexst.com)
+
+ * floatconv.c (_IO_dtoa ()): fix a small memory leak, set the
+ "on_stack" field to be 0 if "result" is not NULL.
+
+Sat Mar 05 13:18:20 1994 H.J. Lu (hjl@nynexst.com)
+
+ * floatconv.c (_IO_dtoa ()): if the number of digits of the
+ floating point number is more than the previous one, free the
+ old string and allocate a new one.
+ [Minor optimization to avoid Bcopy. -PB]
+
+Mon Jul 11 10:53:41 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * fileops.c (_IO_file_underflow): 'count' should be unsigned,
+ since it contains the return value of read. Reported by
+ Teemu Torma <tot@trema.fi>.
+
+Tue Dec 21 13:02:48 1993 H.J. Lu (hjl@nynexst.com)
+
+ * floatconv.c (_IO_strtod ()): make "+" and "-" as error.
+
+Sat Jul 9 15:09:21 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Make sure _IO_FILE::_flags is always initialized correctly, for the
+ C functions (fopen, fdopen, popen), and not just the C++ functions.
+ * fileops.c (_IO_file_init): Set _flags to CLOSED_FILEBUF_FLAGS.
+ * fileops.c (_IO_file_fopen): Remove bogus assignment.
+ * filebuf.cc (filebuf constructors): Don't pass CLOSED_FILEBUF_FLAGS
+ to streambuf constructor - _IO_file_init does it instead.
+ * filebuf.cc (CLOSED_FILEBUF_FLAGS): Removed.
+ * iopopen.c (_IO_proc_open): Use _IO_mask_flags.
+
+Thu Jun 30 08:49:53 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * dbz/Makefile.in (mostlyclean): Add target.
+
+Wed Jun 29 09:30:12 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * gen-params: Woops, can't run a C program to determine target
+ characteristics. Sigh.
+
+Tue Jun 28 03:11:33 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * gen-params: Add _G_{,u}int{8,16,64}_t, use a short C program to
+ determine what all these should be rather than trying to compare
+ the MAX numbers in the shell.
+
+Sun Jun 26 21:04:24 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdiostream.h, stdiostream.cc (stdiobuf::xsgetn): Removed.
+ Too hairy. If we want to optimize it, we should do so in
+ filebuf::xsgetn (or rather _IO_file_xsgetn).
+
+ * stdiostream.h (class stdiobuf), stdiostream.cc: Fix parameter
+ and return types of virtual function to matcher base types (Oops!).
+ * streamstream.cc (stdiobuf::xsgetn, stdiobuf::xsputn):
+ Optimize to call fread.fwrite directly if !buffered.
+ * fileops.c: Fix comment.
+
+Fri Jun 24 11:28:18 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdiostream.h (istdiostream, ostdiostream): New classes.
+
+ More robust final cleanup.
+ * cleanup.c (_IO_register_cleanup): Register _IO_cleanup,
+ rather than _IO_flush_all.
+ * filedoalloc.c: Update comment.
+ * genops.c (_IO_unbuffer_all): New. Makes all files unbuffered.
+ * genops.c (_IO_cleanup), libioP.h: New function. Call
+ _IO_flush_all, and then _IO_unbuffer_all. This is in case C++
+ destructors try to do output *after* _IO_cleanup is called.
+
+ Construct standard stdiobufs statically (using type punning).
+ * stdstrbufs.c; Unless _STDIO_USES_IOSTREAM declare standard
+ stdiobufs (for stdin, stdout, and stderr), using type punning
+ (struct _IO_fake_stdiobuf). This avoids constructor-time problems.
+ * stdstreams.cc: Remove the declarations of the stdiobufs.
+ Instead use the new (fake) ones in stdstrbufs.cc. We no longer
+ have to call ios::sync_with_stdio at constructor time.
+
+ Preliminary support for new ANSI streambuf::uflow virtual.
+ * libioP.h (struct _IO_jump_t): Add __uflow field.
+ * genops.c (_IO_default_uflow), libioP.h: New function.
+ * fileops.c (_IO_file_jumps), iopopen.c (IO_proc_jumps),
+ iovfprintf.c (_IO_helper_jumps), strops.c (_IO_str_jumps),
+ streambuf.cc (_IO_streambuf_jumps): Add _IO_default_uflow.
+ * genops.c (__uflow): New function.
+ (save_for_backup): New function. Some code shared by
+ __underflow and __uflow, moved out from the former.
+ (_IO_default_uflow): New function.
+ * libio.h (_IO_getc): Call __uflow, not __underflow.
+
+Wed Jun 22 20:22:49 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Make sure that the vtable of a streambuf is always valid,
+ which makes ios::rdbuf simpler and faster.
+ * gen-params: Add code to determine _G_VTABLE_LABEL_HAS_LENGTH,
+ _G_VTABLE_LABEL_PREFIX, _G_VTABLE_LABEL_PREFIX_ID, and
+ _G_USING_THUNKS, which describe how virtual function tables are named.
+ * stdfiles.c (FILEBUF_LITERAL): Moved to libioP.h.
+ * libioP.h (builtinbuf_vtable): New (complicated) declaration.
+ * filebuf.cc (filebuf::__new), strstream.cc (SET_STR_JUMPS):
+ Initialize vtable to builtinbuf_vtable, not NULL.
+ * stdstrbufs.cc: New file. Same as stdfiles.c, except that
+ vtable is initialized to builtinbuf_vtable, not NULL.
+ * streambuf.h (ios::rdbuf): Can now simplify/optimize, due to
+ above changes. Always, just return _strbuf.
+ * builtinbuf.h, builtinbuf.cc (builtinbuf::vtable,
+ builtinbuf::get_builtin_vtable): Removed. No longer needed.
+ * streambuf.h, builtinbuf.cc (ios::_IO_fix_vtable): No longer needed.
+ Only defined #ifdef _STREAM_COMPAT, for binary compatibility.
+ * Makefile.in: Move stdfiles.o from IO_OBJECTS to STDIO_WRAP_OBJECTS.
+ (IOSTREAM_OBJECT): Add stdstrbufs.o.
+ * Makefile.in (_G_config.h): Pass $(CXXFLAGS) as part of $(CXX).
+
+Fri Feb 11 11:08:01 1994 SBPM Marc GINGOLD (marc@david.saclay.cea.fr)
+
+ * iovfprintf.c (helper_vfprintf): add
+ hp->_IO_file_flags = _IO_MAGIC|(_IO_IS_FILEBUF+_IO_NO_READS);
+ [This is needed because _IO_vfprintf checks for _IO_UNBUFFERED. -PB]
+ [Actually: don't set _IO_IS_FILEBUF. -PB]
+
+Wed Jun 22 13:49:22 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdiostream.cc, stdiostream.h (stdiobuf::buffered): New methods.
+
+ * iofdopen.c (_IO_fdopen): Various minor improvements.
+
+ * iovfscanf.c: Don't return EOF on control_failure.
+
+Tue Dec 21 13:02:48 1993 H.J. Lu (hjl@nynexst.com)
+
+ * iovfscanf.c: Enforce the sequence of the conversion specifications.
+
+Fri Jun 17 20:57:22 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iofdopen.c: Use fcntl to check that requested access mode is
+ compatible with existing access mode, and to change the
+ O_APPEND file status flag if need be.
+
+Thu Jun 16 17:33:50 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * streambuf.h (ios::init): Initialize all the fields.
+ This may be overkill, but the current ANSI working paper requires it.
+ * streambuf.h (ios::ios): Reimplement in terms of ios::init.
+ * iostream.cc (Non-default constructors istream::istream,
+ ostream::ostream, iostream::iostream): Cannot use a mem-initializer,
+ because it is ignored if initializing a derived class. Instead,
+ call ios::init.
+
+Wed Jun 15 13:35:37 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdstreams.cc (ISTREAM_DEF): Fix typo (it's a _fake_istream, not
+ a _fake_ostream). Reported by Jason Shirk <jshirk@gomez.intel.com>.
+
+ * stdiostream.h, stdiostream.cc (stdiobuf::~stdiobuf): New.
+ Call _IO_do_flush.
+ * stdiostream.cc (stdiobuf::sync): Call _IO_do_flush rather
+ than filebuf::sync (to avoid bad seeks).
+
+ * libioP.h (_IO_do_flush): Add missing parentheses.
+
+Fri Jun 3 19:16:57 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * config.shared (CXXFLAGS): Remove -fno-implicit-templates.
+
+ * iomanip.h: Add explicit external instantiations.
+
+Wed Jun 1 14:14:44 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * libio.h (struct _IO_FILE_plus): Move definition from here ...
+ * libioP.h (struct _IO_FILE_plus): ... to here. Since this
+ file is private to the implementation, we can rename the fields
+ from the implementor's to the user's name anme space.
+ (This avoids a lossage on SCO, whose stdio.h has a #define _file.)
+ * iofdopen.c, iofopen.c, stdfiles.c: Fix field references accordingly.
+ * iopopen.c (struct_IO_proc_file): Rename fields from
+ implementor's name space to user's, and update usages.
+ * streambuf.h (streambuf::_vtable): Re-implement to not need
+ struct _IO_FILE_plus.
+ * strfile.h (struct _IO_strfile_): Likewise.
+
+Wed Jun 1 13:57:48 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * config.shared (CXXFLAGS): Use -fno-implicit-templates instead of
+ -fexternal-templates.
+
+Tue May 31 08:49:28 1994 Mike Stump (mrs@cygnus.com)
+
+ * genops.c, iofclose.c, iofdopen.c, iofopen.c, iopopen.c: Be
+ consistent about protecting #include <stdlib.h>.
+
+ * ioputs.c: Add #include <string.h>, to avoid warning on alpha.
+
+ * iofdopen.c: Add #include <stdlib.h>, so that malloc works on
+ machines where sizeof(int) != sizeof(void *).
+
+Mon May 30 17:26:49 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * pfstream.cc (ipfstream::ipfstream, opfstream::opfstream):
+ Reverse sense of test of return value of procbuf::open.
+ (It returns NULL on failure.)
+
+ * filedoalloc.c (_IO_file_doallocate): Remove dead code for
+ USE_MALLOC_BUF. Add code to return EOF if ALLOC_BUF fails.
+
+Sat May 28 13:47:47 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * iomanip.cc: Explicitly instantiate smanip<int> and
+ smanip<ios::fmtflags>.
+
+Wed May 25 16:04:12 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * strfile.h: Use __P instead of _PARAMS.
+
+Fri May 20 11:42:17 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * libio.h: Rename _PARAMS macro to __P for better glibc and BSD
+ compatibility. (Also define _PARAMS for backwards compatibility.)
+ * cleanup.c, iolibio.h, ioperror.c, iovfprintf.c, iovfscanf.c,
+ libioP.h: Use __P instead of _PARAMS.
+ * iostdio.h: Use __P instead of _ARGS.
+
+ * fileops.c (_IO_file_read): Minor stylistic tweak. (It is
+ preferable to test errno *after* the error return.)
+
+Fri May 13 15:25:36 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * iostream.*: Add insertor and extractor for bool (just pretend
+ it's an int).
+
+Fri May 13 14:12:03 1994 Mike Stump (mrs@cygnus.com)
+
+ * gen-params: Check for builtin bool support.
+
+Wed May 11 00:48:35 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ Make libg++ build with gcc -ansi -pedantic-errors
+ * gen-params: #ifdef __STRICT_ANSI__, #define _G_NO_NRV.
+ * pfstream.cc (ipfstream::ipfstream): Wrap use of variable-size
+ array in #ifndef __STRICT_ANSI__.
+
+Fri May 6 12:42:21 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (VERSION): Increase to 0.64.
+
+ * isgetline.cc (istream::getline): The delimiter should *not*
+ be included in the gcount().
+
+ * filedoalloc.c: #include <stdlib.h> (If __STDC__) to get malloc.
+ * iostream.h (ostream::put): Remove overloaded versions, to match
+ new working paper. (Actually just put inside _STREAM_COMPAT, for now.)
+
+Tue May 3 14:14:57 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * genops.c (_IO_default_finish): Make robust when called
+ multiple times on the same _IO_FILE*. (One way this can
+ happen is by the builtinbuf destructor being followed by the
+ streambuf destructor.)
+
+Mon May 2 13:55:26 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * gen-params: Actually determine wint_t rather than depending on
+ cpp to provide it or defaulting to the underlying type for
+ wchar_t.
+
+Sat Apr 30 14:47:30 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * gen-params: Add _G_wint_t, allow __*_TYPE__ to override values
+ at compile time, fix definition of _G_ARGS.
+
+Fri Apr 29 16:55:37 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * libio.h: Remove #pragma interface. (There is no implementation.)
+
+Mon Mar 28 14:22:26 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iostream.cc (ostream::operator<<(double)): Add/fix support
+ for printing '+' when ios::showpos is set.
+ (Fixes bug reported by Doug Moore <dougm@cs.rice.edu>.)
+ * iostream.cc (istream::read): Set eofbit as well as failbit on eof.
+ * iostream.cc (ostream::operator<<(int)): Fix conversion
+ to unsigned (used to lose on INT_MIN).
+ * iostream.cc (ostream::operator<<(long)): Use (unsigned long),
+ rather than (unsigned) for temporary.
+
+ * config.shared, Makefile.in: Remove definitions and uses
+ of XTRAFLAGS. It is no longer needed, since it is
+ now implied by the -B flag.
+
+Fri Mar 25 00:31:22 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * builtinbuf.h: Add put /**/ around comment on trailing #endif.
+
+ * Makefile.in (c++clean): Make clean in tests subdir, too.
+
+Wed Mar 23 16:42:09 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Remove Makefile.tem before creating it.
+ Needed when configuring from read-only source trees.
+
+Wed Mar 16 14:06:42 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdstreams.cc: Fix so that stdiobuf are used for cin/cout/cerr,
+ unless _STDIO_USES_IOSTREAM is defined.
+ * filebuf.cc (filebuf::setbuf): Fix confusion about return
+ value from _IO_file_setbuf.
+
+Sun Mar 13 00:54:12 1994 Paul Eggert (eggert@twinsun.com)
+
+ * config.shared: Ensure that `all' precedes `.PHONY';
+ BSDI 1.1 needs this.
+
+Sat Mar 12 03:58:00 1994 Paul Eggert (eggert@twinsun.com)
+
+ * config.shared: Output a definition of INSTALL that uses
+ $${rootme}, not ${rootme}. Most `make's don't care, but BSDI
+ 1.1 `make' does.
+
+Fri Mar 4 17:33:01 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iopopen.c: #define _POSIX_SOURCE.
+ * isgetline.c (istream::getline): Various fixes.
+
+Thu Mar 3 17:58:20 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iostream.cc (write_int): Fix test for when to add initial '0'
+ when ios::oct and ios::showbase are set.
+ For hex, showbase adds initial 0x (or 0X) regardless of val==0.
+ Bugs reported by Phil Roth <proth@cs.uiuc.edu>.
+
+Mon Feb 21 13:18:20 1994 H.J. Lu (hjl@nynexst.com)
+
+ * libio.h (_IO_PENDING_OUTPUT_COUNT(_fp)): return the
+ pending output count in _fp.
+
+Fri Feb 25 09:26:57 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * gen-params: For HAVE_SYS_WAIT, compile dummy.c, not dummy.C.
+
+Tue Feb 22 11:19:09 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * streambuf.h, genops.c, libioP.h: Rename references to
+ _IO_FILE fields other_gbase => _IO_save_base,
+ _aux_limit => _IO_backup_base, and _other_egptr => _IO_save_end.
+ * libio.h: Remove no-longer needed macros _other_gbase,
+ _aux_limit, and _other_egptr.
+ * genops.c (__underflow, _IO_default_finishh, _IO_unsave_markers):
+ Check _IO_save_base for NULL before FREEing it or calling
+ _IO_free_backup_area.
+
+Thu Feb 17 15:26:59 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gen-params: Improve deduction of _G_uint32 and _G_int32.
+ Should now work for 16-bit, 32-bit, or 64-bit targets.
+ * gen-params: Check for sys/wait.h using ${CC}, since it's
+ now used in a C file, not a C++ file.
+ * floatconv.c: Typedef _G_uint32_t as unsigned32, and use
+ unsigned32 in place of unsigned long. (Needed for Alpha.)
+
+Tue Feb 8 13:40:15 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * fileops.c (_IO_file_close_it): Simplify by using _IO_do_flush.
+ * fileops.c (_IO_file_finish): Don't call _IO_file_close_it -
+ do it inline. Call _IO_do_flush even if _IO_DELETE_DONT_CLOSE.
+ * fileops.c (_IO_file_attach): Set _IO_DELETE_DONT_CLOSE.
+ * genops.c (_IO_flush_all): Only call overflow if there is
+ something to write.
+ * iofclose.c (_IO_fclose): Check that magic number is correct,
+ and clear it when done. Avoids crashing some buggy applications.
+ * iogetline.c (_IO_getline): Don't gratuitously increment old_len.
+ * iogets.c (_IO_gets): Take care to get required ANSi semantics.
+
+Sun Feb 6 19:50:39 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * iomanip.cc: Explicitly instantiate operator<< and >>.
+
+Fri Feb 4 12:28:22 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * config.shared (CXXFLAGS): Use -fexternal-templates.
+
+ * iomanip.h: Uncomment #pragma interface.
+
+Thu Jan 20 13:48:40 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ If no characters are read by fgets, ANSI C doesn't allow '\0' to
+ be written to the buffer, but it is required by ANSI C++
+ for istream::get and istream::getline. Both use _IO_getline ...
+ * iogetline.c (_IO_getline): Don't write a '\0' at the end
+ of the read data. The input buffer length does not include
+ space for a '\0'.
+ * iofgets.c, iogets.c: Change appropriately.
+ Also check for _IO_ERR_SEEN, as required by ANSI.
+ * isgetline.cc: Update accordingly.
+
+Mon Jan 17 13:24:26 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * Makefile.in (c++clean): Added target for compiler testing
+ (i.e. make c++clean all).
+
+Mon Jan 10 11:20:42 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * libio.h (_IO_putc): Add parentheses.
+ Patch from Rik Faith <faith@cs.unc.edu>.
+
+Tue Jan 4 01:32:28 1993 Hongjiu Lu (hjl@nynexst.com)
+
+ * genops.c (_IO_default_xsputn):
+ (_IO_default_xsgetn):
+ * ioignore.c: change "_IO_size_t count" to
+ "_IO_ssize_t count".
+ * iogetline.c: change "_IO_size_t len" to
+ "_IO_ssize_t len".
+
+Mon Dec 20 00:31:21 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.shared (CXXINCLUDES): Fix quoting of $(NOSTDINC).
+
+Sun Dec 19 21:03:45 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (VERSION): Increase to 0.63.
+
+Fri Dec 17 13:02:44 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iofread.c (_IO_fread): Return 0 if either size or count is 0.
+ * iofwrite.c (_IO_fwrite): Return 0 if either size or count is 0.
+ (This is consistent with fread, and most implementations, but not
+ with a literal reading of the ANSI spec.)
+ * iovfscanf.c (_IO_vfscanf): If got EOF while skipping spaces,
+ set seen_eof and break (instead of returning).
+ * sbscan.cc (streambuf::vscan): Set error state before returning.
+ * streambuf.h: Add a forward declarations for class istream
+ to work around a g++ vtable name mangling bug. (Patch from
+ harry@pdsrc.hilco.com via Jeffrey A Law <law@snake.cs.utah.edu>.)
+ * NEWS: New file.
+
+Sat Dec 11 16:21:08 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iovfprintf.c (struct helper_file, _IO_helper_overflow,
+ helper_vfprintf, _IO_helper_jumps): New structs and functions.
+ (_IO_vfprintf): Use helper_vfprintf to make printing to
+ unbuffered files more efficient.
+ * genops.c (_IO_default_underflow), libioP.h: New function.
+
+ * iovsscanf.c (_IO_vsscanf): The input string's length marks
+ its logical end-of-file.
+
+Wed Dec 8 13:20:46 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * indstream.cc (indirectbuf::sync()): Don't crash if get_stream()
+ or put_stream() are NULL; sync() both streams even if error.
+
+Sun Dec 5 19:24:29 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * iostreamP.h (convert_to_seekflags): Use _IO_seek_set instead of
+ 0 inside the conditial expressions.
+
+ * iofsetpos.c (_IO_fsetpos): Delete unused var `pos'.
+
+Sat Dec 4 15:57:26 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * filedoalloc.c (_IO_file_doallocate): Change type of couldbetty
+ to int, and type of size to _IO_size_t, instead of size_t.
+ (Change needed for Ultrix, which incorrectly deliberately doesn't
+ define size_t in <sys/types.h> if _POSIX_SOURCE is defined.)
+
+Thu Dec 2 22:43:03 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * fileops.c (_IO_file_finish): Remove redundant call to _IO_un_link.
+ * iofclose.c (_IO_fclose): Don't call fp->_jumps->__close; it's
+ too low-level. Instead call _IO_file_close_it.
+ * dbz/Makefile.in (rclean, distclean): Add some missing files.
+
+Wed Dec 1 13:19:14 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config/hpux.mt (MATH_H_INLINES): No longer define.
+ Patch from Jeffrey A Law <law@snake.cs.utah.edu>.
+
+Fri Nov 26 13:28:36 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.shared (CINCLUDES): Define default if libg++.
+ * iofread.c: Use _IO_sgetn.c.
+ * iolibio.h (_IO_clearerr): Fix typo.
+ * genops.c (_IO_seekmark): Return 0 on success.
+ * floactconv.c (Binit): Change to static.
+ * iofclose.c (_IO_fclose): Check if file is _IO_stdin, _IO_stdout,
+ or _IO_stderr; if so don't try to free it. Fix from hjl@nynexst.com.
+
+ * genops.c (_IO_default_sync), libioP.h: New function.
+ * libioP.h (_IO_default_close): Use _IO_default_sync -same interface.
+
+ * Makefile.in: Increase version to 0.62.
+ * iopopen.c (_IO_proc_close): Use waitpid (available in libibarty,
+ if needed), rather than wait. Don't block/ignore SIGINT etc,
+ as this is counter to Posix.2.
+ * iopopen.c: Chain open proc_files, and have the child close
+ the ones that are open (as required by Posix.2).
+
+ * fstream.h (fstreambase::rdbuf), strstream.h (strstreambase
+ ::rdbuf): Call ios::rdbuf() instead of getting _strbuf directly.
+
+ * sbscan.cc (streambuf::vscan): Comment out duplicate default arg.
+ * floatconv.c: Recognize Alpha and i860 as little-endian.
+ * streambuf.cc: Return two bogus value returns from void functions.
+ * iolibio.h, iofwrite.c: Fix buffer type to (const void*).
+ * libio.h: Predefine of struct _IO_FILE to help non-g++-compilers.
+ * libioP.h, pfstream.cc, stdfiles.c, iovfscanf.c: Cleanup syntax junk.
+ * stdstreams.cc: Minor simplification.
+ * streambuf.h, builtinbuf.cc: Add non-const ios::_IO_fix_vtable()
+ for temporary binary compatibility.
+
+ * filedoalloc.c, fileops.c: Add _POSIX_SOURCE.
+ * fileops.c, iofopen.c, iofputs.c, iostream.cc, strops.c,
+ strstream.cc, genops.c: Add some missing #includes.
+ * iofopen.c, iofdopen.c: Return NULL if malloc fails.
+ * iovfscanf.c: Fix return type in strtol prototype.
+ * fwrite.c: Remove bogus file.
+
+Wed Nov 17 14:09:42 1993 Per Bothner (bothner@cygnus.com)
+
+ * builtinbuf.cc (ios::_IO_fix_vtable), streambuf.h: Make method
+ const, to reduce problems with -Wcast-qual.
+
+Tue Nov 16 19:30:42 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config.shared (CXXINCLUDE): use ${} instead of $() for NOSTDINC
+
+Tue Nov 16 14:15:45 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iopopen.c (_IO_proc_close): Re-structure to avoid
+ declarations after statements.
+ * floatconv.c: If not __STDC__, #define DBL_MANT_DIG.
+ * config/isc.mt (G_CONFIG_ARGS): Remove bogus spaces.
+ Patch from David A. Avery <daa@nic.cerf.net>.
+
+Tue Nov 16 15:58:31 1993 Mark Eichin (eichin@cygnus.com)
+
+ * Makefile.in (_G_config.h): explicitly use $(SHELL) to run
+ gen-params, since we know it is a script (we're explicitly looking
+ in ${srcdir} for it) and /bin/sh might not be good enough.
+
+Mon Nov 15 13:26:22 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * builtinbuf.cc: Don't depend on initialization of static
+ variable builtinbuf::vtable, since that might happen after
+ we need it (for a static constructor). Instead, initialize
+ it when needed by inlining the code from get_builtin_vtable
+ into ios::_IO_fix_vtable().
+
+ * floatconv.c: Avoid using #elif, which some C compilers lack.
+ * iogetline.c, libioP.h: Make char parameter be int, to avoid
+ some default promotion anomalies.
+
+Fri Nov 5 11:49:46 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.shared (do-clean-dvi): Remove TeX work files.
+ * iopopen.c (extern _IO_fork): Don't use parameter type void.
+ * strops.c (_IO_str_init_static): Clear the allocate_buffer
+ function pointer, to mark the strfile as being static.
+ Bug fix from Mike Raisbeck <mike@pudding.rtr.COM>.
+
+Thu Nov 4 10:44:24 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * filebuf.cc (filebuf:): Use sseekoff rather than seekoff
+ (which loses if vtable pointer is NULL).
+
+ * iostream.cc (ostream::operator<<(long long n)): Fix thinko.
+
+ * Makefile.in (VERSION): Increase to 0.60.
+ * Makefile.in (IO_OBJECTS): Added iopopen.o.
+ * config.shared (DISTCLEAN): Also remove Make.pack.
+ * config.shared (CXXINCLUDES): Add $(NOSTDINC).
+
+ * config.shared (INSTALL): Fix so it ues the correct install.sh
+ whether $srcdir is absolute or relative.
+
+ * floatconv.c (DBL_MAX_10_EXP): Fix default value.
+
+Wed Nov 3 10:20:49 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * gen-params: Make more robust to allow random junk (NeXT
+ has spaces) before typedefs.
+
+ * fileops.c (_IO_file_overflow): Reduce code duplication.
+ * Makefile.in (IO_OBJECTS): Remove ioputs.o.
+
+ * iovfscanf.c, libio.h: Extra parameter to _IO_vfscanf,
+ for optionally setting an error indication..
+ * iofscanf.c, ioscanf.c, iofscanf.c, iovsscanf.c: Fix calls to
+ _IO_vfscanf to pass an extra NULL.
+ * sbscan.cc (streambuf::vscan): If passed an extra stream,
+ set its error state (using new _IO_vfscanf parameter.
+
+ * filedoalloc.c, fileops.c, genops.c, iogetline.c, ioignore.c,
+ libio.h, libioP.h, streambuf.cc streambuf.h, strfile.h, strops.c,
+ strstream.cc: Replace macros (_base, _ebuf, _eback, _gptr, _egptr,
+ _pbase, _pptr, _epptr) by field names (_IO_buf_base, _IO_buf_end,
+ _IO_read_base, _IO_read_pre, IO_read_end, _IO_write_base,
+ _IO_write_ptr, _IO_write_end).
+ * libio.h: Remove the old macros (which fixes a conflict.
+
+Mon Nov 1 15:22:12 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iostream.cc: Use _IO_sputn instead of sputn. _IO_sputn does
+ not require a vtable pointer, and is also slightly faster.
+
+ * builtinbuf.{h,cc} (builtinbuf::setbuf): Fix return and
+ parameter types.
+
+Mon Oct 25 12:56:33 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Kludge to make sure _IO_FILE buffers get flushed before exit.
+ * dbz/dbzmain.c, dbz/fake.c, dbz/byteflip.c:
+ Invoke DBZ_FINISH macro (if defined) before (normal) exits.
+ * dbz/Makefile.in (CFLAGS): Define DBZ_FINISH to call _IO_flush_all.
+
+Sat Oct 23 22:10:53 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (VERSION): Set to 0.60 for libg++ release.
+ * fileops.c (_IO_file_attach): Set _offset to _IO_pos_BAD.
+ * iostream.cc (ostream::flush): Fix thinkp.
+ * editbuf.cc, isgetsb.cc, isscan.cc, osform.cc, parsestream.cc,
+ pfstream.cc, sbform.cc, sbscan.cc, stdstreams.cc, stream.cc:
+ Replace #include "ioprivate.h" by #include "libioP.h" (and
+ sometimes stdarg.h, stdlib.h and/or string.h).
+ * ioprivate.h: Removed.
+
+
+Thu Oct 21 19:24:02 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * PlotFile.h, SFile.h, editbuf.cc, editbuf.h, filebuf.cc,
+ fstream.cc, fstream.h, indstream.cc, indstream.h, iomanip.cc,
+ iomanip.h, ioprivate.h, iostream.cc, iostream.h, isgetline.cc,
+ isgetsb.cc, parsestream.cc, parsestream.h, pfstream.cc,
+ pfstream.h, procbuf.cc, procbuf.h, stdiostream.cc, stdiostream.h,
+ stdstreams.cc, streambuf.cc, streambuf.h, strstream.cc,
+ strstream.h: Remove old (duplicate) copyright notices.
+
+ * iostream.cc: Fix calls to sync() to be safe in the presence
+ of vtable-less streambufs.
+
+Wed Oct 20 15:22:04 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * streambuf.h (streambuf::underflow, streambuf::overflow):
+ Don't make virtual functions pure.
+ * streambuf.cc (streambuf::underflow, streambuf::overflow):
+ Default definitions (return EOF).
+ * fstream.h: Add new (int fd, char* buf, int len) constructors.
+ These are deprecated, but added for AT&T compatibility.
+ * fstream.cc fstreambase::fstreambase(int fd, char *p, int l): New.
+
+Thu Oct 14 14:57:01 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: use 'mv -f' instead of 'mv'
+
+Tue Oct 12 05:01:44 1993 Mike Stump (mrs@cygnus.com)
+
+ * floatconv.c: Fix typo, change __STDC to __STDC__.
+
+Mon Oct 11 17:03:12 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * cleanup.c: It should be #if _G_HAVE_ATEXIT, not #ifdef.
+
+ * floatconv.c, iostrerror.c, iovfprintf.c, iovfscanf.c, libioP.h:
+ Bunch of fixes to allow use of non-ANSI (K&R) C compilers.
+
+ * Makefile.in (iostream.list): Use CC=$(CXX) to force use of gcc.
+ * README: New file.
+
+Fri Oct 8 16:19:58 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Move ioungetc.o from STDIO_WRAP_OBJECTS to
+ IO_OBJECTS (since it is needed for iovfscanf.c).
+ * iostrerror.c: Add declaration of strerror.
+
+Thu Oct 7 12:02:28 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * cleanup.c: New file, to cause flushing at exit.
+ * filedoalloc.c: Cause flushing on exit.
+ * Makefile.in (OSPRIM_OBJECTS): Add cleanup.o.
+ * gen-params: Check for atexit.
+
+Tue Oct 5 19:11:14 1993 Mike Stump (mrs@cygnus.com)
+
+ * ioperror.c (_IO_strerror): Add missing ()s in _PARAMS usage.
+
+Tue Oct 5 10:33:37 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iofprintf.c, iofscanf.c, ioprintf.c, ioscanf.c, iosprintf.c,
+ iosscanf.c: Remove bogus semi-colon after va_dcl.
+ * ioperror.c: Fix typos in declaration.
+
+Mon Oct 4 17:12:22 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * configure.in (CLEAN): Define (as _G_config.h *.a).
+
+ * fileops.c (_IO_file_read): Don't assume EINTR is defined.
+ * iosetbuf.c: Replace by generalized ...
+ * iosetbuffer.c: ... variant, derived from BSD.
+ * Makefile.in (STDIO_WRAP_OBJECTS): Change correspondingly.
+ * iosetvbuf.c (iosetvbuf): Minor ANSI tweak.
+ * iostdio.h (setbuf, setlinebuf): New #defines.
+ * iolibio.h (_IO_setbuf, _IO_setlinebuf): (Re-)define as macros.
+ * Makefile.in (LIBIO_OBJECTS): New macro.
+
+Tue Sep 28 14:15:52 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * libioP.h (_IO_proc_open, _IO_proc_close): Add missing return types.
+ * procbuf.cc: Belated fixes.
+
+Mon Sep 27 14:04:47 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: List new files. Add STDIO_WRAP_OBJECTS macro.
+ * floatconv.c (d2b): Use Exp_msk11 instead of Exp_msk1.
+ * iofgetpos.c (_IO_fgetpos), iofsetpos.c (_IO_fsetpos): Clean up.
+ * iolibio.h: New file. Declarations of _IO_foo, for most foo
+ where foo is a stdio function. (Remove these from libio.h.)
+ * iostream.h (istream::istreambuf, ostream::ostreambuf): Move
+ obsolete functions inside #ifdef _STREAM_COMPAT.
+ * libio.h, libioP.h, streambuf.h, parsestream.h, stdiostream.h:
+ Use _IO_fpos_t rather than _IO_pos_t.
+ * iopopen.c: New file type, for pipe (popen-like) streams.
+ * procbuf.cc: Now just a C++ wrapper for the files in iopopen.c.
+ * streambuf.h (ios::unsetf): Return complete old value of flags.
+ * iogets.c (_IO_gets(), ioungetc.c (_IO_ungetc), ioperror.c
+ (_IO_perror), iostrerror.c (_IO_strerror): New files and
+ functions, for stdio implementation.
+ * iostdio.h: Add declarations for various recently-added functions.
+
+Sun Sep 12 14:24:55 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * streambuf.h (ios::showpos):: Fix typo.
+
+Fri Aug 27 12:05:47 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iopadn.c (_IO_padn): Change to return count of chars written.
+ * outfloat.c, iovfprintf.c: Change for new _IO_padn interface.
+ * iostream.cc (ostream::operator<<): Make sure to set badbit
+ on a failure (many places). Use _IO_padn more.
+ * iostream.cc (ostream& ostream::operator<<(const void *p): Move to
+ * osform.cc: ... here, to reduce linking-in-the-world syndrome.
+ * osform.cc: Use rdbuf(), instead of _strbuf directly.
+
+ * genops.c (_IO_sgetn), libio.h: New function.
+ * streambuf.h (streambuf.h::sgetn): Use _IO_sgetn.
+ * SFile.cc (SFile::operator[]): Use sseekoff, not seekoff.
+
+Thu Aug 26 10:16:31 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config.shared (SUBDIRS): only recurse if the directory is configured
+
+Wed Aug 25 12:56:12 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config/{hpux.mt, isc.mt, sco4.mt}:
+ Moved from ../libg++/config (since they affect _G_config.h).
+ * configure.in: Set target_make_frag to one of the above files.
+
+Fri Aug 20 00:53:14 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * iofopen.c (iofopen): Fix type passed to _IO_un_link().
+ * Makefile.in (_G_config.h): Pass $CC (not $CXX) as CC.
+
+ * configure.in (configdirs): Add dbz and stdio.
+ * fileops.c (_IO_file_seekoff): Convert more old functionality.
+ * iofdopen.c: Use mode parameter to set _flags.
+ * iofscanf.c, ioputs.c, ioscanf.c, iosprintf.c: New files.
+ * Makefile.in (IO_OBJECTS): Added new objects.
+ * iostdio.h: Add feof. fscanf, puts, sprintf, vsprintf.
+ * libio.h: Add _IO_vprintf macro.
+ * iofopen.c: Invoke _IO_un_link if failure.
+ * iovsprintf.c: Write terminating NUL.
+
+ * libioP.h: Add COERCE_FILE macro (by default does nothing).
+ * iofclose.c, iofflush.c, iofgets.c, iofprintf.c, iofputs.c,
+ iofread.c, ioftell.c, iofwrite.c, iosetbuf.c, iosetvbuf.c:
+ Invoke COERCE_FILE macro.
+ * ioftell.c: Use _IO_seekoff.
+
+Wed Aug 18 22:49:56 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * sbform.cc (streambuf::form), sbscan.cc (streambuf::scan):
+ Remove cast to _IO_va_list. (Loses if array type.)
+
+ * libio.h: Handle _IO_va_list for systems that need <stdarg.h>.
+ * floatconv.h: Fix typo (reported by H.J.Lu).
+
+Wed Aug 18 19:34:04 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in (INSTALLDIR): handle native vs. cross case
+
+ * Makefile.in (install): don't use $TARGETLIB, set INSTALLDIR to
+ $(libdir)
+
+Wed Aug 18 12:10:03 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Rename iostream-files to iostream.list.
+ * configure.in: Add iostream.list to MOSTLYCLEAN.
+
+Tue Aug 17 18:56:59 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Depend on _G_config.h where appropriate.
+ * config.shared (CXXINCLUDES): If doing libg++, search ../libio.
+
+Tue Aug 17 17:34:24 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ New directory. Based on old libg++/iostream code,
+ but extensively re-written.
+
+
diff --git a/gnu/dist/libio/Makefile.in b/gnu/dist/libio/Makefile.in
new file mode 100644
index 00000000000..8117c7fd477
--- /dev/null
+++ b/gnu/dist/libio/Makefile.in
@@ -0,0 +1,127 @@
+# Copyright (C) 1993, 1995 Free Software Foundation
+#
+# This file is part of the GNU IO Library. This library is free
+# software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this library; see the file COPYING. If not, write to the Free
+# Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+srcdir = .
+
+VERSION = 2.8.0
+# The config file (overriden by Linux).
+_G_CONFIG_H=_G_config.h
+tooldir = $(exec_prefix)/$(target)
+INSTALLDIR = $(libdir)
+
+IO_OBJECTS = filedoalloc.o floatconv.o genops.o fileops.o \
+ iovfprintf.o \
+ iovfscanf.o ioignore.o iopadn.o \
+ iofgetpos.o iofread.o iofscanf.o \
+ iofsetpos.o iogetdelim.o iogetline.o \
+ ioprintf.o ioseekoff.o ioseekpos.o \
+ outfloat.o strops.o iofclose.o iopopen.o ioungetc.o peekc.o iogetc.o \
+ ioputc.o iofeof.o ioferror.o
+
+STDIO_OBJECTS = stdfiles.o
+
+# These emulate stdio functionality, but with a different name (_IO_ungetc
+# instead of ungetc), and using _IO_FILE instead of FILE.
+# They are not needed for C++ iostream, nor stdio, though some stdio
+# files are build using the same source files (see stdio/configure.in).
+# They are needed for iostdio.h. They are needed under Linux to avoid
+# version incompatibility problems with the C library.
+# iofclose.o is not here, because it is needed for stdio (by pclose).
+STDIO_WRAP_OBJECTS = iofdopen.o iofflush.o iofgets.o iofopen.o iofprintf.o iofputs.o iofwrite.o \
+ iogets.o ioperror.o ioputs.o ioscanf.o iosetbuffer.o iosetvbuf.o \
+ iosprintf.o iosscanf.o ioftell.o iovsscanf.o iovsprintf.o
+
+IOSTREAM_OBJECTS = builtinbuf.o filebuf.o fstream.o \
+ indstream.o ioassign.o ioextend.o iomanip.o iostream.o \
+ isgetline.o isgetsb.o isscan.o \
+ osform.o procbuf.o sbform.o sbgetline.o sbscan.o \
+ stdiostream.o stdstrbufs.o stdstreams.o stream.o streambuf.o strstream.o \
+ PlotFile.o SFile.o parsestream.o pfstream.o editbuf.o
+
+# These files define _IO_read etc, which are just wrappers for read(2) etc.
+# They need to be changed to use name-space-clean (e.g. __read) versions
+# for each specific libc.
+OSPRIM_OBJECTS = ioprims.o iostrerror.o cleanup.o
+
+LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(OSPRIM_OBJECTS)
+LIBIO_OBJECTS = $(IO_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS) \
+ $(STDIO_OBJECTS)
+
+LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS)
+LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS)
+
+USER_INCLUDES = *.h
+
+PICFLAG =
+
+#### package, host, target, and site dependent Makefile fragments come in here.
+##
+
+$(LIBIO_OBJECTS): $(_G_CONFIG_H)
+
+libio.a: $(_G_CONFIG_H) $(LIBIO_OBJECTS)
+ -rm -rf libio.a
+ $(AR) $(AR_FLAGS) libio.a $(LIBIO_OBJECTS)
+ $(RANLIB) libio.a
+
+libiostream.a: $(_G_CONFIG_H) $(LIBIOSTREAM_DEP)
+ -rm -rf libiostream.a
+ $(AR) $(AR_FLAGS) libiostream.a $(LIBIOSTREAM_USE)
+ $(RANLIB) libiostream.a
+
+test: test.o libio.a
+ $(CC) $(CFLAGS) -o test test.o libio.a
+tpipe: tpipe.o libio.a
+ $(CC) $(CFLAGS) -o tpipe tpipe.o libio.a
+
+iostream.list: stamp-picdir $(_G_CONFIG_H) $(LIBIOSTREAM_DEP)
+ @echo "$(LIBIOSTREAM_USE)"> iostream.list
+
+stmp-stdio:
+ @rootme=`pwd`/ ; export rootme; cd stdio ; \
+ $(MAKE) $(FLAGS_TO_PASS) stdio.list
+
+_G_config.h: ${srcdir}/gen-params
+ rootme=`pwd`/ ; export rootme; \
+ CC="$(CC)"; export CC; \
+ CXX="$(CXX) $(NOSTDINC) $(CXXFLAGS)"; export CXX; \
+ CONFIG_NM="$(NM)"; export CONFIG_NM; \
+ $(SHELL) ${srcdir}/gen-params LIB_VERSION=$(VERSION) $(G_CONFIG_ARGS) >tmp-params.h
+ mv tmp-params.h _G_config.h
+
+install:
+ rootme=`pwd`/ ; export rootme ; \
+ if [ -z "$(MULTISUBDIR)" ]; then \
+ if [ "$(_G_CONFIG_H)" != "" ]; then \
+ rm -f $(tooldir)/include/_G_config.h ; \
+ $(INSTALL_DATA) _G_config.h $(tooldir)/include/_G_config.h || exit 1; \
+ else true; \
+ fi ; \
+ cd $(srcdir); \
+ for FILE in $(USER_INCLUDES); do if [ $$FILE != _G_config.h ]; then \
+ rm -f $(gxx_include_dir)/$$FILE ; \
+ $(INSTALL_DATA) $$FILE $(gxx_include_dir)/$$FILE ; \
+ chmod a-x $(gxx_include_dir)/$$FILE ; \
+ else true; fi; done ; \
+ else true; \
+ fi
+ @rootme=`pwd`/ ; export rootme ; \
+ $(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install
+
+c++clean:
+ rm -rf $(IOSTREAM_OBJECTS)
+ @$(MAKE) $(FLAGS_TO_PASS) "DODIRS=tests" DO=clean subdir_do
diff --git a/gnu/dist/libio/NEWS b/gnu/dist/libio/NEWS
new file mode 100644
index 00000000000..1f3b7781e22
--- /dev/null
+++ b/gnu/dist/libio/NEWS
@@ -0,0 +1,57 @@
+*** Major changes in libio for egcs:
+
+* Better support for Linux.
+
+* Dejagnu testsuite.
+
+*** Major changes in libio version 2.7.0:
+
+* The data representations of _IO_FILE and streambufs have been modified.
+ The layout of the jump-table table _IO_jumps_t has been re-arranged
+ to match that of a virtual function table of a streambuf. Therefore,
+ we no longer need a separate _IO_FILE::_jumps pointer; instead it can
+ be shared with the virtual function table pointer. In addition to
+ saving space, this also removes the overhead when double indirection
+ was needed, and there are many simplificatons (e.g. we no longer need
+ the builtinbuf class.
+
+* The streambuf::uflow virtual has been added, to match the standard.
+
+* The ifstream, ofstream, and fstream classes now include the filebuf
+ as a member, rather than being pointed to it. Various related changes.
+
+* Version number changed to generally follow libg++ (and gcc).
+
+*** Major changes in libio version 0.66 (released with libg++ 2.6.1):
+
+* Some documentation and an example in iostream.texi on how to derive
+ your own class from streambuf.
+
+* New functions added to stdio: getline, detdelim, snprintf, vsnprintf.
+ This is for compatibility with the GNU C library.
+
+*** Major changes in libio version 0.65 (released with libg++ 2.6):
+
+* _IO_getline and streambuf::sgetline no longer write a '\0' at the end.
+
+* A number of improvements to get closer to the ANSI/ISO C++ working
+paper, such as:
+- Added (preliminary support for) new ANSI streambuf::uflow virtual.
+- Added istdiostream and ostdiostream classes.
+- Added ostream::operator<<(bool) and istream::operator>>(bool&).
+
+* More robust (and faster) initialization and cleanup of standard streambufs.
+
+* Many small bug fixes, portability improvements, and random enhancements.
+
+*** Major changes in libio version 0.63 (released with libg++ 2.5.3):
+
+* There is a g++ bug that causes inconsistent name mangling for the
+assembler name of the virtual function table for the istream class.
+A work-around has been put into streambuf.h, which will make g++
+always do the right thing. Note that this may require you to
+recompile programs that were incorrectly compiled by g++.
+
+* Functions that do printf-style formatting to the unbuffered
+streams have been optimized to write to a temporary buffer.
+
diff --git a/gnu/dist/libio/PlotFile.cc b/gnu/dist/libio/PlotFile.cc
new file mode 100644
index 00000000000..98b2d839555
--- /dev/null
+++ b/gnu/dist/libio/PlotFile.cc
@@ -0,0 +1,157 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992, 1993 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+ converted to use iostream library by Per Bothner (bothner@cygnus.com)
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with GCC to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <PlotFile.h>
+
+/*
+ PlotFile implementation module
+*/
+
+
+PlotFile& PlotFile:: cmd(char c)
+{
+ ofstream::put(c);
+ return *this;
+}
+
+PlotFile& PlotFile:: operator<<(const int x)
+{
+#if defined(convex)
+ ofstream::put((char)(x>>8));
+ ofstream::put((char)(x&0377));
+#else
+ ofstream::put((char)(x&0377));
+ ofstream::put((char)(x>>8));
+#endif
+ return *this;
+}
+
+PlotFile& PlotFile:: operator<<(const char *s)
+{
+ *(ofstream*)this << s;
+ return *this;
+}
+
+
+PlotFile& PlotFile:: arc(const int xi, const int yi,
+ const int x0, const int y0,
+ const int x1, const int y1)
+{
+ return cmd('a') << xi << yi << x0 << y0 << x1 << y1;
+}
+
+
+PlotFile& PlotFile:: box(const int x0, const int y0,
+ const int x1, const int y1)
+{
+ line(x0, y0, x0, y1);
+ line(x0, y1, x1, y1);
+ line(x1, y1, x1, y0);
+ return line(x1, y0, x0, y0);
+}
+
+PlotFile& PlotFile:: circle(const int x, const int y, const int r)
+{
+ return cmd('c') << x << y << r;
+}
+
+PlotFile& PlotFile:: cont(const int xi, const int yi)
+{
+ return cmd('n') << xi << yi;
+}
+
+PlotFile& PlotFile:: dot(const int xi, const int yi, const int dx,
+ int n, const int* pat)
+{
+ cmd('d') << xi << yi << dx << n;
+ while (n-- > 0) *this << *pat++;
+ return *this;
+}
+
+PlotFile& PlotFile:: erase()
+{
+ return cmd('e');
+}
+
+PlotFile& PlotFile:: label(const char* s)
+{
+ return cmd('t') << s << "\n";
+}
+
+PlotFile& PlotFile:: line(const int x0, const int y0,
+ const int x1, const int y1)
+{
+ return cmd('l') << x0 << y0 << x1 << y1;
+}
+
+PlotFile& PlotFile:: linemod(const char* s)
+{
+ return cmd('f') << s << "\n";
+}
+
+PlotFile& PlotFile:: move(const int xi, const int yi)
+{
+ return cmd('m') << xi << yi;
+}
+
+PlotFile& PlotFile:: point(const int xi, const int yi)
+{
+ return cmd('p') << xi << yi;
+}
+
+PlotFile& PlotFile:: space(const int x0, const int y0,
+ const int x1, const int y1)
+{
+ return cmd('s') << x0 << y0 << x1 << y1;
+}
diff --git a/gnu/dist/libio/PlotFile.h b/gnu/dist/libio/PlotFile.h
new file mode 100644
index 00000000000..82b08bc4681
--- /dev/null
+++ b/gnu/dist/libio/PlotFile.h
@@ -0,0 +1,89 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ a very simple implementation of a class to output unix "plot"
+ format plotter files. See corresponding unix man pages for
+ more details.
+
+ written by Doug Lea (dl@rocky.oswego.edu)
+ converted to use iostream library by Per Bothner (bothner@cygnus.com)
+*/
+
+#ifndef _PlotFile_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _PlotFile_h
+
+#include <fstream.h>
+
+/*
+ Some plot libraries have the `box' command to draw boxes. Some don't.
+ `box' is included here via moves & lines to allow both possiblilties.
+*/
+
+extern "C++" {
+class PlotFile : public ofstream
+{
+protected:
+ PlotFile& cmd(char c);
+ PlotFile& operator << (const int x);
+ PlotFile& operator << (const char *s);
+
+public:
+
+ PlotFile() : ofstream() { }
+ PlotFile(int fd) : ofstream(fd) { }
+ PlotFile(const char *name, int mode=ios::out, int prot=0664)
+ : ofstream(name, mode, prot) { }
+
+// PlotFile& remove() { ofstream::remove(); return *this; }
+
+// int filedesc() { return ofstream::filedesc(); }
+// const char* name() { return File::name(); }
+// void setname(const char* newname) { File::setname(newname); }
+// int iocount() { return File::iocount(); }
+
+ PlotFile& arc(const int xi, const int yi,
+ const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& box(const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& circle(const int x, const int y, const int r);
+ PlotFile& cont(const int xi, const int yi);
+ PlotFile& dot(const int xi, const int yi, const int dx,
+ int n, const int* pat);
+ PlotFile& erase();
+ PlotFile& label(const char* s);
+ PlotFile& line(const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& linemod(const char* s);
+ PlotFile& move(const int xi, const int yi);
+ PlotFile& point(const int xi, const int yi);
+ PlotFile& space(const int x0, const int y0,
+ const int x1, const int y1);
+};
+} // extern "C++"
+#endif
diff --git a/gnu/dist/libio/README b/gnu/dist/libio/README
new file mode 100644
index 00000000000..c2d564965ca
--- /dev/null
+++ b/gnu/dist/libio/README
@@ -0,0 +1,30 @@
+This is libio, the GNU C/C++ input/output library.
+
+By default, the library is configured to build the C++ iostream
+facility (in $libdir/libiostream.a).
+
+The library can be configured to build the C stdio facility
+that is part of a C run-time library.
+
+This library is distributed with libg++; see ../libg++/README
+for installation instructions, and where to send bug reports
+and questions.
+
+* Copyright restrictions
+
+The files in this directory are generally covered by the GNU Public
+License (which is in the file ../COPYING), but modified with the
+following:
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does not cause
+ the resulting executable to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+
+A few source files and subroutines are covered by other (but
+less restrictive) copyright conditions. E.g. some code (such
+as iovfprintf.c) is based on software that was developed by the
+University of California, Berkeley, for the Berkeley Software
+Distribution (BSD-4.4), and bears their copyright; and one
+file (floatconv.c) is derived from ("free") code copyrighted AT&T.
diff --git a/gnu/dist/libio/SFile.cc b/gnu/dist/libio/SFile.cc
new file mode 100644
index 00000000000..e5daa645695
--- /dev/null
+++ b/gnu/dist/libio/SFile.cc
@@ -0,0 +1,82 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This 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. This 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 this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <SFile.h>
+
+SFile::SFile(const char *filename, int size, int mode, int prot)
+: fstream(filename, mode, prot)
+{
+ sz = size;
+}
+
+SFile::SFile(int fd, int size)
+: fstream(fd)
+{
+ sz = size;
+}
+
+void SFile::open(const char *name, int size, int mode, int prot)
+{
+ fstream::open(name, mode, prot);
+ sz = size;
+}
+
+SFile& SFile::get(void* x)
+{
+ read(x, sz);
+ return *this;
+}
+
+SFile& SFile::put(void* x)
+{
+ write(x, sz);
+ return *this;
+}
+
+SFile& SFile::operator[](long i)
+{
+ if (rdbuf()->pubseekoff(i * sz, ios::beg) == EOF)
+ set(ios::badbit);
+ return *this;
+}
diff --git a/gnu/dist/libio/SFile.h b/gnu/dist/libio/SFile.h
new file mode 100644
index 00000000000..f07277cee49
--- /dev/null
+++ b/gnu/dist/libio/SFile.h
@@ -0,0 +1,55 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1988, 1992, 1993 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _SFile_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _SFile_h 1
+
+#include <fstream.h>
+
+extern "C++" {
+class SFile: public fstream
+{
+ protected:
+ int sz; // unit size for structured binary IO
+
+public:
+ SFile() : fstream() { }
+ SFile(int fd, int size);
+ SFile(const char *name, int size, int mode, int prot=0664);
+ void open(const char *name, int size, int mode, int prot=0664);
+
+ int size() { return sz; }
+ int setsize(int s) { int old = sz; sz = s; return old; }
+
+ SFile& get(void* x);
+ SFile& put(void* x);
+ SFile& operator[](long i);
+};
+} // extern "C++"
+
+#endif
diff --git a/gnu/dist/libio/builtinbuf.cc b/gnu/dist/libio/builtinbuf.cc
new file mode 100644
index 00000000000..05e65a5c371
--- /dev/null
+++ b/gnu/dist/libio/builtinbuf.cc
@@ -0,0 +1,78 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+#include "builtinbuf.h"
+#include "iostreamP.h"
+#if !_IO_UNIFIED_JUMPTABLES
+int builtinbuf::overflow(int ch) { return _IO_OVERFLOW (this, ch); }
+
+int builtinbuf::underflow() { return _IO_UNDERFLOW (this); }
+
+streamsize builtinbuf::xsgetn(char* buf, streamsize n)
+{ return _IO_XSGETN (this, buf, n); }
+
+streamsize builtinbuf::xsputn(const char* buf, streamsize n)
+{ return _IO_XSPUTN (this, buf, n); }
+
+int builtinbuf::doallocate() { return _IO_DOALLOCATE (this); }
+
+builtinbuf::~builtinbuf() { _IO_FINISH (this); }
+
+int builtinbuf::sync() { return _IO_SYNC (this); }
+
+streambuf* builtinbuf::setbuf(char *buf, int n)
+{ return (streambuf*)_IO_SETBUF (this, buf, n); }
+
+streampos builtinbuf::seekoff(streamoff off, _seek_dir dir, int mode)
+{
+ return _IO_SEEKOFF (this, off, dir, mode);
+}
+
+streampos builtinbuf::seekpos(streampos pos, int mode)
+{
+ return _IO_SEEKPOS (this, pos, mode);
+}
+
+int builtinbuf::pbackfail(int c)
+{ return _IO_PBACKFAIL (this, c); }
+
+streamsize builtinbuf::sys_read(char* buf, streamsize size)
+{ return _IO_SYSREAD (this, buf, size); }
+
+streampos builtinbuf::sys_seek(streamoff off, _seek_dir dir)
+{ return _IO_SYSSEEK (this, off, dir); }
+
+streamsize builtinbuf::sys_write(const char* buf, streamsize size)
+{ return _IO_SYSWRITE (this, buf, size); }
+
+int builtinbuf::sys_stat(void* buf) // Actually, a (struct stat*)
+{ return _IO_SYSSTAT (this, buf); }
+
+int builtinbuf::sys_close()
+{ return _IO_SYSCLOSE (this); }
+#endif
diff --git a/gnu/dist/libio/builtinbuf.h b/gnu/dist/libio/builtinbuf.h
new file mode 100644
index 00000000000..0e0c6e85a9e
--- /dev/null
+++ b/gnu/dist/libio/builtinbuf.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _BUILTINBUF_H
+#define _BUILTINBUF_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <streambuf.h>
+
+#if !_IO_UNIFIED_JUMPTABLES
+// A builtinbuf a a streambuf where all the virtual operations
+// call the _IO_jump_t table.
+
+extern "C++" {
+class builtinbuf : public streambuf {
+ friend ios;
+ virtual int overflow(int);
+ virtual int underflow();
+ virtual streamsize xsgetn(char *, streamsize);
+ virtual streamsize xsputn(const char *, streamsize);
+ virtual streambuf* setbuf(char*, int);
+ virtual int doallocate();
+ virtual ~builtinbuf();
+ virtual int sync();
+
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual int pbackfail(int c);
+ virtual streamsize sys_read(char* buf, streamsize size);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+ virtual int sys_close();
+#if 0
+ virtual int get_column();
+ virtual int set_column(int);
+#endif
+ private:
+ builtinbuf() { }
+};
+} // extern "C++"
+#endif
+
+#endif /* _BUILTINBUF_H */
diff --git a/gnu/dist/libio/cleanup.c b/gnu/dist/libio/cleanup.c
new file mode 100644
index 00000000000..691fa838b26
--- /dev/null
+++ b/gnu/dist/libio/cleanup.c
@@ -0,0 +1,17 @@
+#include "libioP.h"
+#if _G_HAVE_ATEXIT
+#include <stdlib.h>
+
+typedef void (*voidfunc) __P((void));
+
+static void
+_IO_register_cleanup ()
+{
+ atexit ((voidfunc)_IO_cleanup);
+ _IO_cleanup_registration_needed = 0;
+}
+
+void (*_IO_cleanup_registration_needed)() = _IO_register_cleanup;
+#else
+void (*_IO_cleanup_registration_needed)() = NULL;
+#endif /* _G_HAVE_ATEXIT */
diff --git a/gnu/dist/libio/config.shared b/gnu/dist/libio/config.shared
new file mode 100644
index 00000000000..1b23b353090
--- /dev/null
+++ b/gnu/dist/libio/config.shared
@@ -0,0 +1,486 @@
+# Copyright (C) 1993, 1995, 1997 Free Software Foundation
+#
+# This file is part of the GNU IO Library. This library is free
+# software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU CC; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Significant variables:
+
+# Note that TO_TOPDIR does *not* include multilib.
+test -z "${TO_TOPDIR}" && TO_TOPDIR=${TOLIBGXX}../
+# Native configurations build target libraries in directories at the same
+# level as the rest of the tree. Cross configurations build target libraries
+# one level deeper. TO_REAL_TOPDIR accounts for this.
+# Obviously, TO_REAL_TOPDIR can only be used in the build tree.
+if [ "${with_target_subdir}" != "." ] ; then
+ TO_REAL_TOPDIR="${TO_TOPDIR}../"
+else
+ TO_REAL_TOPDIR="${TO_TOPDIR}"
+fi
+DOING_LIBGXX=${DOING_LIBGXX-false}
+THIS_FILE="${srcdir}/${TOLIBGXX}config.shared"
+
+echo "# Start of package fragment generated by ${THIS_FILE}."
+echo ""
+
+# Multilib support.
+echo 'MULTISRCTOP ='
+echo 'MULTIBUILDTOP ='
+echo 'MULTIDIRS ='
+echo 'MULTISUBDIR ='
+echo 'MULTIDO = true'
+echo 'MULTICLEAN = true'
+echo ''
+
+# TOLIBGXX
+# MOSTLYCLEAN
+# CLEAN
+# DISTCLEAN
+# REALCLEAN
+# SUBDIRS [defaults to (configdirs)]
+# INFO_FILES List of (basenames of) texinfo files
+# INFO_SUBDIRS [default: empty] sub-directories containing documentation
+
+# ??? This doesn't appear to be used by us or any of our callers.
+# Note that all uses in this file are single-quoted.
+rootme=${rootme-`pwd`}
+
+# libg++ uses the convention that $rootme includes a trailing '/'.
+# We use that in the definition of TOPDIR. $rootme is either empty
+# or an absolute pathname to the current directory (with trailing '/').
+TOPDIR=${TOPDIR-'$${rootme}$(MULTIBUILDTOP)'${TO_REAL_TOPDIR}}
+echo '#' TOPDIR="${TOPDIR} invsubdir=${invsubdir} subdir=${subdir}"
+SUBDIRS=${SUBDIRS-${configdirs}}
+CHECK_SUBDIRS=${CHECK_SUBDIRS-${SUBDIRS}}
+
+echo "srcdir = ${srcdir}"
+echo "SUBDIRS = ${SUBDIRS}"
+echo "CHECK_SUBDIRS = ${CHECK_SUBDIRS}"
+
+echo "prefix = ${prefix-/usr/local}"
+echo "exec_prefix = ${exec_prefix-'${prefix}'}"
+
+echo 'bindir = $(exec_prefix)/bin'
+echo 'libdir = $(exec_prefix)/lib'
+
+echo 'datadir = $(prefix)/lib'
+echo 'mandir = $(prefix)/man'
+echo 'man1dir = $(mandir)/man1'
+echo 'man2dir = $(mandir)/man2'
+echo 'man3dir = $(mandir)/man3'
+echo 'man4dir = $(mandir)/man4'
+echo 'man5dir = $(mandir)/man5'
+echo 'man6dir = $(mandir)/man6'
+echo 'man7dir = $(mandir)/man7'
+echo 'man8dir = $(mandir)/man8'
+echo 'man9dir = $(mandir)/man9'
+
+echo 'infodir = $(prefix)/info'
+echo 'includedir = $(prefix)/include'
+echo 'docdir = $(datadir)/doc'
+echo ''
+echo 'SHELL = /bin/sh'
+echo ''
+case "$srcdir" in
+ /*) echo 'INSTALL = $(srcdir)'/"${TO_TOPDIR}install-sh -c" ;;
+ .) echo 'INSTALL = $${rootme}'"${with_multisrctop}${TO_REAL_TOPDIR}install-sh -c" ;;
+ *) echo 'INSTALL = $${rootme}$(srcdir)'/"${TO_TOPDIR}install-sh -c" ;;
+esac
+echo 'INSTALL_PROGRAM = $(INSTALL)'
+echo 'INSTALL_DATA = $(INSTALL)'
+echo ''
+echo 'AR = `if [ -f' ${TOPDIR}'binutils/ar ] ; \'
+echo " then echo ${TOPDIR}binutils/ar ; "'\'
+echo ' else echo ar ; fi`'
+echo 'AR_FLAGS = rc'
+echo 'RANLIB = `if [ -f' ${TOPDIR}'binutils/ranlib ] ; \'
+echo ' then echo '${TOPDIR}'binutils/ranlib ; \'
+echo ' else echo ranlib ; fi`'
+echo 'NM = `if [ -f' ${TOPDIR}'binutils/nm.new ] ; \'
+echo ' then echo '${TOPDIR}'binutils/nm.new ; \'
+echo ' else echo nm ; fi`'
+echo 'NLMCONV = `if [ -f' ${TOPDIR}'binutils/nlmconv ] ; \'
+echo ' then echo '${TOPDIR}'binutils/nlmconv ; \'
+echo ' else echo nlmconv ; fi`'
+echo 'LD = `if [ -f' ${TOPDIR}'ld/ld.new ] ; \'
+echo ' then echo '${TOPDIR}'ld/ld.new ; \'
+echo ' else echo ld ; fi`'
+echo ''
+echo 'MAKEINFO = `if [ -f '${TOPDIR}'texinfo/C/makeinfo ] ; \'
+echo ' then echo '${TOPDIR}'texinfo/C/makeinfo ; \'
+echo ' else echo makeinfo ; fi`'
+case "$srcdir" in
+ .) echo 'TEXIDIR = '"${with_multisrctop}${TO_REAL_TOPDIR}texinfo" ;;
+ *) echo 'TEXIDIR = $(srcdir)'/"${TO_TOPDIR}texinfo" ;;
+esac
+echo 'TEXI2DVI = TEXINPUTS=${TEXIDIR}:$$TEXINPUTS texi2dvi'
+echo ''
+echo 'CC = cc'
+echo 'CXX = gcc'
+echo ''
+# FIXME!!!
+if true ; then
+ echo 'WRAP_C_INCLUDES ='
+else
+ echo 'WRAP_C_INCLUDES = -I$(srcdir)'/${TOLIBGXX}g++-include
+fi
+echo 'CFLAGS = -g'
+echo 'CXXFLAGS = -g -O'
+echo 'LIBCFLAGS = $(CFLAGS)'
+echo 'LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates'
+if [ "${LIBDIR}" = "yes" ]; then
+ echo 'PICDIR = stamp-picdir'
+else
+ echo 'PICDIR = '
+fi
+
+if test "${DOING_LIBGXX}" = "true" ; then
+ echo "TOLIBGXX = ${TOLIBGXX}"
+ echo 'PROTODIR = $(srcdir)'/${TOLIBGXX}src/gen
+ echo "LIBS = -L./${TOLIBGXX} -L./${TOLIBGXX}../libstdc++ -lg++ -lstdc++"
+
+ # You can override iostream (e.g. in a site- or host-Makefile fragment) to:
+ # iostream (Normal iostream library)
+ # old-stream (Old stream library; no longer supported)
+ # no-stream (If you don't want iostream to be part of libg++)
+ echo 'IO_DIR = ../libio'
+ echo '# IO_DIR = no-stream'
+elif test "${DOING_GPERF}" = "true" ; then
+ echo "IO_DIR = libio"
+ echo "TOLIBGXX = ${TOLIBGXX}"
+ echo "LIBS = -L./${TOLIBGXX} -L./${TOLIBGXX}../libstdc++ -lg++ -lstdc++"
+fi
+
+if [ -z "${ALL}" ] ; then
+ if [ -n "${TARGETLIB}" ] ; then
+ ALL='$(TARGETLIB)'
+ echo "TARGETLIB = ${TARGETLIB}"
+ elif [ -n "${TARGETPROG}" ] ; then
+ ALL='${TARGETPROG}'
+ echo "TARGETPROG = ${TARGETPROG}"
+ else
+ echo "config error: neither ALL, TARGETLIB or TARGETPROG is defined" 1>&2
+ fi
+fi
+
+ALL='$(PICDIR)'" ${ALL}"
+
+echo "all: ${ALL} multi-all"
+if [ "${SUBDIRS}" != "" ] ; then
+ echo ' @rootme=`pwd`/; export rootme; \'
+ echo ' $(MAKE) "DODIRS=$(SUBDIRS)" DO=all $(FLAGS_TO_PASS) subdir_do'
+fi
+echo '.PHONY: all'
+echo ''
+
+echo '.PHONY: multi-all'
+echo 'multi-all:'
+echo ' @$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=all'
+echo ''
+
+echo
+if [ "${SUBDIRS}" != "" ] ; then
+ echo '.PHONY: subdir_do'
+ echo 'subdir_do: force'
+ echo ' @rootme=`pwd`/; export rootme; \'
+ echo ' for i in $(DODIRS); do \'
+ echo ' if [ -f ./$$i/Makefile ] ; then \'
+ echo ' echo "cd $$i; make $(DO) ..." ; \'
+ echo ' (cd $$i ; $(MAKE) $(FLAGS_TO_PASS) $(DO)) || exit 1 ; \'
+ echo ' else true ; fi ; \'
+ echo ' done'
+ echo ''
+ echo '# List of variables to pass to sub-makes. This should not be needed'
+ echo '# by GNU make or Sun make (both of which pass command-line variable'
+ echo '# overrides thouh $(MAKE)) but may be needed by older versions.'
+ echo ''
+ echo 'FLAGS_TO_PASS= \'
+ echo ' "INSTALL=$(INSTALL)" \'
+ echo ' "INSTALL_DATA=$(INSTALL_DATA)" \'
+ echo ' "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \'
+ echo ' "prefix=$(prefix)" \'
+ echo ' "exec_prefix=$(exec_prefix)" \'
+ echo ' "tooldir=$(tooldir)" \'
+ echo ' "AR=$(AR)" \'
+ echo ' "AR_FLAGS=$(AR_FLAGS)" \'
+ echo ' "CC=$(CC)" \'
+ echo ' "CXX=$(CXX)" \'
+ echo ' "CFLAGS=$(CFLAGS)" \'
+ echo ' "CXXFLAGS=$(CXXFLAGS)" \'
+ echo ' "NM=$(NM)" \'
+ echo ' "RANLIB=$(RANLIB)" \'
+ echo ' "LIBCFLAGS=$(LIBCFLAGS)" \'
+ echo ' "LIBCXXFLAGS=$(LIBCXXFLAGS)" \'
+ echo ' "LOADLIBES=$(LOADLIBES)" \'
+ echo ' "LDFLAGS=$(LDFLAGS)" \'
+ echo ' "MAKEINFO=$(MAKEINFO)" \'
+ echo ' "SHLIB=$(SHLIB)" \'
+ echo ' "SHCURSES=$(SHCURSES)" \'
+ echo ' "PICFLAG=$(PICFLAG)" \'
+ echo ' "RUNTESTFLAGS=$(RUNTESTFLAGS)"'
+fi
+
+echo 'NOSTDINC = -nostdinc++'
+if test -n "${XCXXINCLUDES}" ; then
+ echo "CXXINCLUDES = ${XCXXINCLUDES} "'$(NOSTDINC)'
+elif test "${DOING_LIBGXX}" = "true" ; then
+ echo 'CXXINCLUDES = $(NOSTDINC) -I. -I'"${TO_TOPDIR}libio"' -I$(srcdir) -I$(srcdir)/'"${TOLIBGXX}"'$(IO_DIR) -I$(srcdir)/'"${TOLIBGXX}"'../libstdc++ -I$(srcdir)/'"${TOLIBGXX}src"' $(WRAP_C_INCLUDES)'
+fi
+if test -n "${XCINCLUDES}" ; then
+ echo "CINCLUDES = ${XCINCLUDES}"
+elif test "${DOING_LIBGXX}" = "true" ; then
+ echo 'CINCLUDES ='
+fi
+
+if [ "${LIBDIR}" = "yes" ]; then
+ echo 'XCFLAGS = $(LIBCFLAGS)'
+ echo 'XCXXFLAGS = $(LIBCXXFLAGS)'
+else
+ echo 'XCFLAGS = $(CFLAGS)'
+ echo 'XCXXFLAGS = $(CXXFLAGS)'
+fi
+
+echo '.SUFFIXES: .o .C .cc .c'
+echo 'COMPILE.c = $(CC) -c $(XCFLAGS) $(CINCLUDES) $(MT_CFLAGS)'
+echo '.c.o:'
+if [ "${LIBDIR}" = "yes" ]; then
+echo ' test -z "$(PICFLAG)" ||\'
+echo ' $(COMPILE.c) $(PICFLAG) $< -o pic/$@'
+fi
+echo ' $(COMPILE.c) $<'
+[ "${TOUCH_ON_COMPILE}" = "yes" ] && echo ' @touch stamp'
+echo 'COMPILE.cc = $(CXX) -c $(XCXXFLAGS) $(CXXINCLUDES) $(MT_CFLAGS)'
+echo '.C.o:'
+if [ "${LIBDIR}" = "yes" ]; then
+echo ' test -z "$(PICFLAG)" ||\'
+echo ' $(COMPILE.cc) $(PICFLAG) $< -o pic/$@'
+fi
+echo ' $(COMPILE.cc) $<'
+[ "${TOUCH_ON_COMPILE}" = "yes" ] && echo ' @touch stamp'
+echo '.cc.o:'
+if [ "${LIBDIR}" = "yes" ]; then
+echo ' test -z "$(PICFLAG)" || \'
+echo ' $(COMPILE.cc) $(PICFLAG) $< -o pic/$@'
+fi
+echo ' $(COMPILE.cc) $<'
+[ "${TOUCH_ON_COMPILE}" = "yes" ] && echo ' @touch stamp'
+echo ''
+
+if [ -n "${TARGETLIB}" ] ; then
+ echo TARGETLIB = ${TARGETLIB}
+fi
+if [ -n "${TARGETPROG}" ] ; then
+ echo TARGETPROG = ${TARGETPROG}
+fi
+
+if [ "${LIBDIR}" = "yes" ]; then
+ echo ''
+ echo 'stamp-picdir:'
+ echo ' if [ -n "$(PICFLAG)" ] && [ ! -d pic ]; then \'
+ echo ' mkdir pic; \'
+ echo ' else true; fi'
+ echo ' touch stamp-picdir'
+fi
+
+echo ''
+echo '.PHONY: install'
+echo 'install:'
+echo '.PHONY: check'
+if [ "${CHECK}" != "check" ] ; then
+ echo "check: ${ALL} ${CHECK}"
+ if [ "${CHECK_SUBDIRS}" != "" ] ; then
+ echo ' rootme=`pwd`/; export rootme; \'
+ echo ' SAVE_LLPATH="$${SAVE_LLPATH-$$LD_LIBRARY_PATH}"; export SAVE_LLPATH; \'
+ echo ' LD_LIBRARY_PATH="$${rootme}${TOLIBGXX}../libstdc++:$${rootme}${TOLIBGXX}../libg++:$$SAVE_LLPATH"; \'
+ echo ' export LD_LIBRARY_PATH; \'
+ echo ' $(MAKE) "DODIRS=$(CHECK_SUBDIRS)" DO=check $(FLAGS_TO_PASS) subdir_do'
+ fi
+fi
+
+# Generate rules for documentation (depending on INFO_FILES and INFO_SUBDIRS).
+
+echo '.PHONY: info dvi install-info clean-info'
+
+# emit the rule for 'info'
+# (Note that the top-level ../Makefile.in greps for '^info:' when making
+# a release (in "make taz"), so don't break that!)
+if [ -z "${INFO_FILES}" ] ; then
+ echo 'info:'
+else
+ echo info: `for file in ${INFO_FILES} ; do echo $file.info ; done`
+fi
+if [ "${INFO_SUBDIRS}" != "" ] ; then
+ echo ' @rootme=`pwd`/; export rootme; \
+ $(MAKE) "DODIRS='${INFO_SUBDIRS}'" DO=info $(FLAGS_TO_PASS) subdir_do'
+fi
+
+# emit the rule for 'dvi'
+if [ -z "${INFO_FILES}" ] ; then
+ echo 'dvi:'
+else
+ echo dvi: `for file in ${INFO_FILES} ; do echo $file.dvi ; done`
+fi
+if [ "${INFO_SUBDIRS}" != "" ] ; then
+ echo ' @rootme=`pwd`/; export rootme; \
+ $(MAKE) "DODIRS='${INFO_SUBDIRS}'" DO=dvi $(FLAGS_TO_PASS) subdir_do'
+fi
+
+# Emit rules for each *.info and *.dvi file
+for file in ${INFO_FILES} ; do
+ echo ${file}.info: '$(srcdir)'/${file}.texi
+ echo ' $(MAKEINFO) -I$(srcdir) -I$(TEXIDIR) $(srcdir)/'${file}.texi -o ${file}.info
+ echo ${file}.dvi: '$(srcdir)'/${file}.texi
+ echo ' $(TEXI2DVI) $(srcdir)'/${file}.texi
+ echo "${file}.ps: ${file}.dvi"
+ echo " dvips ${file} -o"
+done
+
+# emit the rule for install-info
+echo 'install-info:'
+if [ -n "${INFO_FILES}" ] ; then
+ echo ' -parent=`echo $(infodir)|sed -e' "'"'s@/[^/]*$$@@'"'"'`; \'
+ echo ' if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi'
+ echo ' -if [ -d $(infodir) ] ; then true ; else mkdir $(infodir) ; fi'
+ echo ' for i in *.info* ; do \'
+ echo ' $(INSTALL_DATA) $$i $(infodir)/$$i ; \'
+ echo ' done'
+fi
+if [ "${INFO_SUBDIRS}" != "" ] ; then
+ echo ' @rootme=`pwd`/; export rootme; \
+ $(MAKE) "DODIRS='${INFO_SUBDIRS}'" DO=install-info $(FLAGS_TO_PASS) subdir_do'
+fi
+
+# emit clean-info and clean-dvi rules
+echo '.PHONY: do-clean-info clean-info do-clean-dvi clean-dvi'
+echo do-clean-info:
+if [ -n "${INFO_FILES}" ] ; then
+ echo ' rm -f *.info*'
+fi
+echo 'do-clean-dvi:'
+if [ -n "${INFO_FILES}" ] ; then
+ echo ' rm -f *.dvi *.aux *.cp *.cps *.fn* *.ky *.log *.pg *.toc *.tp *.vr'
+fi
+for type in info dvi ; do
+ echo clean-${type}: do-clean-${type}
+ if [ "${INFO_SUBDIRS}" != "" ] ; then
+ echo ' @rootme=`pwd`/; export rootme; \
+ $(MAKE) "DODIRS='${NFO_SUBDIRS}'" DO=clean-'${type} '$(FLAGS_TO_PASS) subdir_do'
+ fi
+done
+
+echo ''
+
+echo '.PHONY: boltcc'
+echo 'boltcc:'
+echo ' rootme=`pwd`/ ; export rootme ; $(MAKE) $(FLAGS_TO_PASS)'
+echo ''
+
+# Emit clean rules
+
+echo ''
+echo '# clean rules'
+
+MOSTLYCLEAN="${MOSTLYCLEAN-*.o pic stamp-picdir core ${EXTRA_MOSTLYCLEAN}} `if test -n "${TOUCH_ON_COMPILE}"; then echo stamp; else true; fi`"
+CLEAN="${CLEAN-${TARGETPROG} ${TARGETLIB}}"
+DISTCLEAN="${DISTCLEAN-config.status Makefile *~ Make.pack target-mkfrag multilib.out ${EXTRA_DISTCLEAN-}}"
+REALCLEAN="${REALCLEAN-depend *.info*}"
+
+
+echo '.PHONY: mostlyclean clean distclean maintainer-clean realclean'
+if test -z "${SUBDIRS}" ; then
+ echo "mostlyclean: clean-dvi"
+ echo " rm -rf ${MOSTLYCLEAN}"
+ echo ' @$(MULTICLEAN) multi-clean DO=mostlyclean'
+ echo "clean: clean-dvi"
+ echo " rm -rf ${MOSTLYCLEAN} ${CLEAN}"
+ echo ' @$(MULTICLEAN) multi-clean DO=clean'
+ echo "distclean: clean"
+ echo ' @$(MULTICLEAN) multi-clean DO=distclean'
+ echo " rm -rf ${DISTCLEAN}"
+ echo "maintainer-clean realclean: clean clean-info"
+ echo ' @$(MULTICLEAN) multi-clean DO=maintainer-clean'
+ echo " rm -rf ${DISTCLEAN} ${REALCLEAN}"
+else
+ echo '.PHONY: do-clean subdir_distclean subdir_maintainer_clean'
+ echo "mostlyclean: do-clean-dvi"
+ echo " rm -rf ${MOSTLYCLEAN}"
+ echo ' @$(MAKE) $(FLAGS_TO_PASS) "DODIRS=$(SUBDIRS)" DO=mostlyclean subdir_do'
+ echo ' @$(MULTICLEAN) multi-clean DO=mostlyclean'
+ echo "do-clean: do-clean-dvi"
+ echo " rm -rf ${MOSTLYCLEAN} ${CLEAN}"
+ echo "clean: do-clean"
+ echo ' @$(MAKE) $(FLAGS_TO_PASS) "DODIRS=$(SUBDIRS)" DO=clean subdir_do'
+ echo ' @$(MULTICLEAN) multi-clean DO=clean'
+ # distclean and maintainer-clean are tricky because they remove the Makefile.
+ echo "subdir_distclean:"
+ echo ' @$(MAKE) $(FLAGS_TO_PASS) "DODIRS=$(SUBDIRS)" DO=distclean subdir_do'
+ echo "distclean: do-clean subdir_distclean"
+ echo ' @$(MULTICLEAN) multi-clean DO=distclean'
+ echo " rm -rf ${DISTCLEAN}"
+ echo "subdir_maintainer_clean:"
+ echo ' @$(MAKE) $(FLAGS_TO_PASS) "DODIRS=$(SUBDIRS)" DO=maintainer-clean subdir_do'
+ echo "maintainer-clean realclean: do-clean subdir_maintainer_clean do-clean-info"
+ echo ' @$(MULTICLEAN) multi-clean DO=maintainer-clean'
+ echo " rm -rf ${DISTCLEAN} ${REALCLEAN}"
+fi
+
+echo ''
+echo '.PHONY: force'
+echo 'force:'
+echo ''
+echo '# with the gnu make, this is done automatically.'
+echo ''
+echo 'Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)'
+echo ' $(SHELL) ./config.status'
+echo ''
+echo '.NOEXPORT:'
+echo 'MAKEOVERRIDES='
+
+cat <<"EOF"
+DEPEND_SOURCES = ${srcdir}/*.cc ${srcdir}/*.c
+depend.new:
+# The sed script below attempts to make the depend output portable.
+# It cleans up the depenency information generated by cpp.
+# It replaces instances of $(srcdir)/ by the string '$(srcdir)/'.
+# It removes remaining absolute files names (such as /usr/include/stdio.h).
+# It removes lines containing only "\\".
+# It inserts '$(MULTISRCTOP)' in '$(srcdir)/..'.
+# In order to support SunOS VPATH, $(srcdir)/[a-z]*.{c,cc} is replaced with
+# [a-z]*.{c,cc} (the directory part is removed).
+# The awk script removes a continuation marker that is followed by
+# a blank line, since that may confuse make.
+ echo "# AUTOMATICALLY GENERATED BY 'make depend' - DO NOT EDIT" \
+ >depend.new
+ $(CXX) -M $(CXXINCLUDES) $(DEPEND_SOURCES) \
+ | sed -e 's|$(srcdir)/|$$(srcdir)/|g' \
+ -e 's| [^ ]_G_config.h| $$(_G_CONFIG_H)|g \
+ -e 's| /[^ ]*||g' \
+ -e '/^[ ]*\\$$/d' -e 's/^[ ]*$$//' \
+ | sed -e 's|$$(srcdir)/[.][.]|$$(srcdir)/$$(MULTISRCTOP)..|g' \
+ -e 's|$$(srcdir)/\([^/]*[.]c\)|\1|' \
+ | awk 'BEGIN { prev = "" } \
+ /^( )*$$/ { if (prev ~ /\\$$/) \
+ { prev = substr(prev,1,length(prev)-1); next } } \
+ { print prev; prev = $$0 } \
+ END { if (prev !~ /^( )*$$/) print prev }' \
+ >> depend.new
+$(srcdir)/depend: depend.new
+ mv depend.new $(srcdir)/depend
+EOF
+
+if [ -f ${srcdir}/${subdir}/depend ] ; then
+ cat ${srcdir}/${subdir}/depend
+fi
+
+echo "# End of package fragment generated by ${THIS_FILE}."
diff --git a/gnu/dist/libio/config/hpux.mt b/gnu/dist/libio/config/hpux.mt
new file mode 100644
index 00000000000..fc95afa64fa
--- /dev/null
+++ b/gnu/dist/libio/config/hpux.mt
@@ -0,0 +1,3 @@
+# Flags to pass to gen-params when building _G_config.h.
+# For example: G_CONFIG_ARGS = size_t="unsigned long"
+G_CONFIG_ARGS = DOLLAR_IN_LABEL=1
diff --git a/gnu/dist/libio/config/isc.mt b/gnu/dist/libio/config/isc.mt
new file mode 100644
index 00000000000..15cbb8c36c2
--- /dev/null
+++ b/gnu/dist/libio/config/isc.mt
@@ -0,0 +1,4 @@
+# Flags to pass to gen-params when building _G_config.h.
+# For example: G_CONFIG_ARGS = size_t="unsigned long"
+G_CONFIG_ARGS = pid_t="unsigned short" \
+ gid_t="unsigned short" uid_t="unsigned short"
diff --git a/gnu/dist/libio/config/linux.mt b/gnu/dist/libio/config/linux.mt
new file mode 100644
index 00000000000..0585d90cd10
--- /dev/null
+++ b/gnu/dist/libio/config/linux.mt
@@ -0,0 +1,28 @@
+# Use the libio which comes with the local libc.
+
+# That is where we keep the g++ header files.
+gxx_include_dir =$(prefix)/include/g++
+
+# Comment this out to avoid including the stdio functions in libiostream.a:
+# LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS)
+# LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list
+# LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list`
+
+# Comment the above and uncomment the below to use the code in the Linux libc:
+# We have _G_config.h in /usr/include.
+_G_CONFIG_H=
+
+# We must not see the libio.h file from this library.
+LIBIO_INCLUDE=
+
+# We have those in libc.a.
+IO_OBJECTS= iogetline.o
+STDIO_WRAP_OBJECTS=
+OSPRIM_OBJECTS=
+STDIO_OBJECTS=
+
+# We have the rest in /usr/include.
+USER_INCLUDES=PlotFile.h SFile.h builtinbuf.h editbuf.h fstream.h \
+ indstream.h iomanip.h iostream.h istream.h ostream.h \
+ parsestream.h pfstream.h procbuf.h stdiostream.h stream.h \
+ streambuf.h strfile.h strstream.h
diff --git a/gnu/dist/libio/config/linuxaxp1-libc-lock.h b/gnu/dist/libio/config/linuxaxp1-libc-lock.h
new file mode 100644
index 00000000000..2523a0d5157
--- /dev/null
+++ b/gnu/dist/libio/config/linuxaxp1-libc-lock.h
@@ -0,0 +1,112 @@
+/* libc-internal interface for mutex locks. LinuxThreads version.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#ifndef _LIBC_LOCK_H
+#define _LIBC_LOCK_H 1
+
+#include <pthread.h>
+#define __libc_lock_t pthread_mutex_t
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS. */
+#define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER;
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+ state. */
+#define __libc_lock_init(NAME) \
+ (__pthread_mutex_init != NULL ? __pthread_mutex_init (&(NAME), NULL) : 0);
+
+/* Same as last but this time we initialize a recursive mutex. */
+#define __libc_lock_init_recursive(NAME) \
+ do { \
+ if (__pthread_mutex_init != NULL) \
+ { \
+ pthread_mutexattr_t __attr; \
+ __pthread_mutexattr_init (&__attr); \
+ __pthread_mutexattr_setkind_np (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \
+ __pthread_mutex_init (&(NAME), &__attr); \
+ __pthread_mutexattr_destroy (&__attr); \
+ } \
+ } while (0);
+
+/* Finalize the named lock variable, which must be locked. It cannot be
+ used again until __libc_lock_init is called again on it. This must be
+ called on a lock variable before the containing storage is reused. */
+#define __libc_lock_fini(NAME) \
+ (__pthread_mutex_destroy != NULL ? __pthread_mutex_destroy (&(NAME)) : 0);
+
+/* Lock the named lock variable. */
+#define __libc_lock_lock(NAME) \
+ (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (&(NAME)) : 0);
+
+/* Try to lock the named lock variable. */
+#define __libc_lock_trylock(NAME) \
+ (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (&(NAME)) : 0);
+
+/* Unlock the named lock variable. */
+#define __libc_lock_unlock(NAME) \
+ (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (&(NAME)) : 0);
+
+/* Start critical region with cleanup. */
+#define __libc_cleanup_region_start(FCT, ARG) \
+ { struct _pthread_cleanup_buffer _buffer; \
+ if (_pthread_cleanup_push_defer != NULL) { \
+ _pthread_cleanup_push_defer (&_buffer, (FCT), (ARG)); \
+ }
+
+/* End critical region with cleanup. */
+#define __libc_cleanup_region_end(DOIT) \
+ if (_pthread_cleanup_push_defer != NULL) { \
+ _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \
+ } \
+ }
+
+/* Make the pthread functions weak so that we can elide them from
+ single-threaded processes. */
+#pragma weak __pthread_mutex_init
+#pragma weak __pthread_mutex_destroy
+#pragma weak __pthread_mutex_lock
+#pragma weak __pthread_mutex_trylock
+#pragma weak __pthread_mutex_unlock
+#pragma weak __pthread_mutexattr_init
+#pragma weak __pthread_mutexattr_destroy
+#pragma weak __pthread_mutexattr_setkind_np
+#pragma weak __pthread_key_create
+#pragma weak __pthread_setspecific
+#pragma weak __pthread_getspecific
+#pragma weak __pthread_initialize
+#pragma weak _pthread_cleanup_push_defer
+#pragma weak _pthread_cleanup_pop_restore
+
+/* We need portable names for some functions. E.g., when they are
+ used as argument to __libc_cleanup_region_start. */
+#define __libc_mutex_unlock __pthread_mutex_unlock
+
+#endif /* libc-lock.h */
+
diff --git a/gnu/dist/libio/config/linuxaxp1-stdio-lock.h b/gnu/dist/libio/config/linuxaxp1-stdio-lock.h
new file mode 100644
index 00000000000..cbee76867d1
--- /dev/null
+++ b/gnu/dist/libio/config/linuxaxp1-stdio-lock.h
@@ -0,0 +1,36 @@
+/* Thread package specific definitions of stream lock type.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include <pthread.h>
+
+typedef pthread_mutex_t _IO_lock_t;
+
+/* We need recursive (counting) mutexes. */
+#define _IO_lock_initializer PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+
+
+#define _IO_cleanup_region_start(_fct, _fp) \
+ __libc_cleanup_region_start (_fct, _fp)
+#define _IO_cleanup_region_end(_doit) \
+ __libc_cleanup_region_end (_doit)
+#define _IO_lock_init(_name) \
+ __libc_lock_init_recursive (_name)
+#define _IO_lock_fini(_name) \
+ __libc_lock_fini_recursive (_name)
+
diff --git a/gnu/dist/libio/config/linuxaxp1.mt b/gnu/dist/libio/config/linuxaxp1.mt
new file mode 100644
index 00000000000..d9b7e8c7e95
--- /dev/null
+++ b/gnu/dist/libio/config/linuxaxp1.mt
@@ -0,0 +1,10 @@
+# We _do_ need a new _G_config.h
+_G_CONFIG_H=_G_config.h
+
+# And the two bits files.
+all:
+install: install-axp-mt-headers
+
+install-axp-mt-headers:
+ $(INSTALL_DATA) libc-lock.h $(gxx_include_dir)/libc-lock.h
+ $(INSTALL_DATA) stdio-lock.h $(gxx_include_dir)/stdio-lock.h
diff --git a/gnu/dist/libio/config/linuxlibc1.mt b/gnu/dist/libio/config/linuxlibc1.mt
new file mode 100644
index 00000000000..90fa427225e
--- /dev/null
+++ b/gnu/dist/libio/config/linuxlibc1.mt
@@ -0,0 +1,26 @@
+# Use the libio which comes with the local libc.
+
+# Comment this out to avoid including the stdio functions in libiostream.a:
+# LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS)
+# LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list
+# LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list`
+
+# We must not see the libio.h file from this library.
+LIBIO_INCLUDE=
+
+# We have those in libc.a.
+IO_OBJECTS=iogetc.o ioputc.o iofeof.o ioferror.o \
+ filedoalloc.o fileops.o genops.o iofclose.o \
+ iovsprintf.o iovsscanf.o strops.o iogetline.o
+STDIO_WRAP_OBJECTS=
+OSPRIM_OBJECTS=
+STDIO_OBJECTS=
+
+# We have the rest in /usr/include.
+USER_INCLUDES=PlotFile.h SFile.h builtinbuf.h editbuf.h fstream.h \
+ indstream.h iomanip.h iostream.h istream.h ostream.h \
+ parsestream.h pfstream.h procbuf.h stdiostream.h stream.h \
+ streambuf.h strfile.h strstream.h libio.h
+
+# A bad kludge
+MT_CFLAGS=-D_G_HAVE_MMAP
diff --git a/gnu/dist/libio/config/mn10200.mt b/gnu/dist/libio/config/mn10200.mt
new file mode 100644
index 00000000000..71e79167658
--- /dev/null
+++ b/gnu/dist/libio/config/mn10200.mt
@@ -0,0 +1,3 @@
+# Flags to pass to gen-params when building _G_config.h.
+# For example: G_CONFIG_ARGS = size_t="unsigned long"
+G_CONFIG_ARGS = NO_USE_DTOA=1 USE_INT32_FLAGS=1
diff --git a/gnu/dist/libio/config/mtsafe.mt b/gnu/dist/libio/config/mtsafe.mt
new file mode 100644
index 00000000000..5848851be8a
--- /dev/null
+++ b/gnu/dist/libio/config/mtsafe.mt
@@ -0,0 +1,2 @@
+# tell we want the mt-safe version
+MT_CFLAGS = -D_IO_MTSAFE_IO
diff --git a/gnu/dist/libio/config/netware.mt b/gnu/dist/libio/config/netware.mt
new file mode 100644
index 00000000000..339a865717c
--- /dev/null
+++ b/gnu/dist/libio/config/netware.mt
@@ -0,0 +1,16 @@
+IMPDIR= $(srcdir)/config/netware
+
+PRELUDE= prelude.o
+
+iostream.def: Makefile
+ -rm -f iostream.def
+ echo "description \"libiostream\"" >> iostream.def
+ echo "screenname \"NONE\"" >> iostream.def
+ echo "version `echo $(VERSION) | sed 's|\.|,|g'`" >> iostream.def
+ echo "export @$(IMPDIR)/iostream.imp" >> iostream.def
+
+iostream.O: $(PRELUDE) $(LIBIOSTREAM_OBJECTS)
+ $(CC) -Xlinker -Ur -o $@ $(PRELUDE) $(LIBIOSTREAM_OBJECTS)
+
+iostream.nlm: iostream.def iostream.O $(IMPDIR)/iostream.imp
+ $(NLMCONV) -l $(LD) -T iostream.def iostream.O iostream.nlm
diff --git a/gnu/dist/libio/config/sco4.mt b/gnu/dist/libio/config/sco4.mt
new file mode 100644
index 00000000000..1d8f6f189c3
--- /dev/null
+++ b/gnu/dist/libio/config/sco4.mt
@@ -0,0 +1,3 @@
+# Flags to pass to gen-params when building _G_config.h.
+# For example: G_CONFIG_ARGS = size_t="unsigned long"
+G_CONFIG_ARGS = MATH_H_INLINES=1
diff --git a/gnu/dist/libio/configure.in b/gnu/dist/libio/configure.in
new file mode 100644
index 00000000000..9efcb3e096a
--- /dev/null
+++ b/gnu/dist/libio/configure.in
@@ -0,0 +1,133 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+if [ "${srcdir}" = "." ] ; then
+ if [ "${with_target_subdir}" != "." ] ; then
+ topsrcdir=${with_multisrctop}../..
+ else
+ topsrcdir=${with_multisrctop}..
+ fi
+else
+ topsrcdir=${srcdir}/..
+fi
+
+if [ -d ${topsrcdir}/gcc ] ; then
+ configdirs="tests dbz stdio testsuite"
+else
+ configdirs="tests dbz stdio"
+fi
+srctrigger=libioP.h
+srcname="input/output library"
+package_makefile_frag=Make.pack
+
+# per-host:
+
+# per-target:
+
+echo "# Warning: this fragment is automatically generated" > temp.mt
+frags=
+
+case "${target}" in
+ *-hpux*) frags=hpux.mt ;;
+ alpha*-*-linux-gnulibc1)
+ frags="linux.mt linuxaxp1.mt mtsafe.mt" ;;
+ powerpc*-*-linux-gnulibc1)
+ frags="linux.mt linuxaxp1.mt mtsafe.mt" ;;
+ *-linux-gnulibc1)
+ frags=linuxlibc1.mt ;;
+ *-linux-gnu) frags="linux.mt mtsafe.mt" ;;
+ *-sco3.2v[45]*) frags=sco4.mt ;;
+ *-isc*) frags=isc.mt ;;
+ *-netware*) frags=netware.mt ;;
+ *) frags=${target_cpu}.mt ;;
+esac
+
+case "${enable_shared}" in
+ yes) shared=yes ;;
+ no) shared=no ;;
+ *libio*) shared=yes ;;
+ *) shared=no ;;
+esac
+
+if [ "${shared}" = "yes" ]; then
+ case "${target}" in
+ hppa*-*) frags="${frags} ../../config/mh-papic" ;;
+ i[3456]86-*) frags="${frags} ../../config/mh-x86pic" ;;
+ alpha*-*-linux*)
+ frags="${frags} ../../config/mh-elfalphapic" ;;
+ *) frags="${frags} ../../config/mh-${target_cpu}pic" ;;
+ esac
+fi
+
+# Take care of header file lossage.
+case "${target}" in
+ alpha*-*-linux-gnulibc1)
+ # For some reason stdio-lock.h is not installed on Red Hat systems.
+ # Further, libc-lock.h needs to define the pthreads stuff weak, and
+ # fails to do this for other than _LIBC. Install our own versions
+ # of these files.
+ cp ${srcdir}/config/linuxaxp1-libc-lock.h libc-lock.h
+ cp ${srcdir}/config/linuxaxp1-stdio-lock.h stdio-lock.h
+ ;;
+ powerpc*-*-linux-gnulibc1)
+ # For some reason stdio-lock.h is not installed on Red Hat systems.
+ # Further, libc-lock.h needs to define the pthreads stuff weak, and
+ # fails to do this for other than _LIBC. Install our own versions
+ # of these files.
+ cp ${srcdir}/config/linuxaxp1-libc-lock.h libc-lock.h
+ cp ${srcdir}/config/linuxaxp1-stdio-lock.h stdio-lock.h
+ ;;
+ *-linux-gnu)
+ # We have a correct libc-lock.h in glibc 2.1 but not all glibc 2.0.
+ # Create a wrapper if necessary.
+ (echo "#include <bits/libc-lock.h>" | ${CC-cc} -E -) >/dev/null 2>&1 ||
+ {
+ echo "#include_next <libc-lock.h>" > libc-lock.h
+ echo 'asm (".weak _pthread_cleanup_pop_restore");' >> libc-lock.h
+ echo 'asm (".weak _pthread_cleanup_push_defer");' >> libc-lock.h
+
+ }
+ ;;
+esac
+
+for frag in ${frags}; do
+ frag=${srcdir}/config/$frag
+ if [ -f ${frag} ]; then
+ echo "Appending ${frag} to target-mkfrag"
+ echo "# Following fragment copied from ${frag}" >> temp.mt
+ cat ${frag} >> temp.mt
+ fi
+done
+
+target_makefile_frag=target-mkfrag
+${moveifchange} temp.mt target-mkfrag
+
+LIBDIR=yes
+TO_TOPDIR=../
+ALL='$(_G_CONFIG_H) libio.a libiostream.a iostream.list'
+XCINCLUDES='-I. -I$(srcdir)'
+XCXXINCLUDES='-I. -I$(srcdir)'
+MOSTLYCLEAN='*.o pic stamp-picdir core iostream.list'
+DISTCLEAN='config.status Makefile *~ Make.pack target-mkfrag multilib.out'
+CLEAN='_G_config.h *.a'
+INFO_FILES=iostream
+if [ -n "${with_cross_host}" ] ; then
+ CHECK_SUBDIRS=testsuite
+fi
+(. ${srcdir}/config.shared) >${package_makefile_frag}
+
+# post-target:
+
+# If cross-compiling, don't build gperf or the utils. They
+# will get built by the target compiler, which is confusing.
+# We cannot test the installation. We install in $(tooldir).
+if [ -n "${with_cross_host}" ] ; then
+ rm -f Makefile.tem
+ sed \
+ -e 's|INSTALLDIR.*=.*$|INSTALLDIR = $(tooldir)/lib|' \
+ Makefile >Makefile.tem
+ mv -f Makefile.tem Makefile
+fi
+
+. ${topsrcdir}/config-ml.in
diff --git a/gnu/dist/libio/dbz/Makefile.in b/gnu/dist/libio/dbz/Makefile.in
new file mode 100644
index 00000000000..6d6dc287485
--- /dev/null
+++ b/gnu/dist/libio/dbz/Makefile.in
@@ -0,0 +1,218 @@
+srcdir = .
+CFLAGS = -g
+C_FLAGS = $(CFLAGS) -I$(srcdir) -I.. -I$(srcdir)/.. -DDBZ_FINISH='_IO_flush_all()'
+CC = `if [ -f ../../../gcc/gcc ] ; \
+ then echo ../../../gcc/gcc -B../../../gcc/ ; \
+ else echo gcc ; fi`
+LIBIO = ../libio.a ../../libiberty/libiberty.a
+LIBS = $(LIBIO)
+# LIBS = ../libcnews.a
+DBM =
+RFC = -DHAVERFCIZE
+CASE = case.o
+DEBUG = -DDBZDEBUG
+LINTFLAGS = -h $(DEBUG) $(RFC) -I$(srcdir)
+LDFLAGS =
+# =()<NEWSBIN = @<NEWSBIN>@>()=
+NEWSBIN = /usr/lib/newsbin
+# workaround for System V make bug
+SHELL = /bin/sh
+
+# database sizes for performance tests, regression, and regression prime-find
+TSIZE=12007
+RSIZE=4019
+RPSIZE=2679
+
+#### host and target dependent Makefile fragments come in here.
+##
+
+# history files for regression and performance tests
+RHIST=hist3.3
+R2HIST=hist10
+THIST=hist13
+
+#all: dbz
+all:
+install:
+install-info:
+info:
+
+check: r
+ $(MAKE) rclean
+
+bininstall: dbz
+ cp dbz $(NEWSBIN)
+
+cmp: dbz
+ cmp dbz $(NEWSBIN)/dbz
+
+newsinstall:
+ : nothing
+
+u: dbz.o
+ ar ruv ../libcnews.a dbz.o
+ cmp dbz.h ../h/dbz.h
+
+t: tdbz fake
+
+lint:
+ lint $(LINTFLAGS) dbzmain.c dbz.c
+
+.c.o:
+ $(CC) $(C_FLAGS) -c $<
+
+rdbz.o: rdbz.c
+ $(CC) $(C_FLAGS) $(DEBUG) -DDEFSIZE=$(RSIZE) -c rdbz.c
+
+rdbzmain.o: rdbzmain.c
+ $(CC) $(C_FLAGS) $(RFC) -c rdbzmain.c
+
+tdbz.o: $(srcdir)/dbz.c
+ cp $(srcdir)/dbz.c tdbz.c
+ $(CC) $(C_FLAGS) -DDEFSIZE=$(TSIZE) -c tdbz.c
+ rm tdbz.c
+
+dbz: dbzmain.o $(CASE)
+ $(CC) $(LDFLAGS) dbzmain.o $(CASE) $(PRE) $(DBM) $(LIBS) $(POST) -o $@
+
+tdbz: dbzmain.o tdbz.o $(CASE)
+ $(CC) $(LDFLAGS) dbzmain.o tdbz.o $(CASE) $(PRE) $(LIBS) $(POST) -o $@
+
+rdbz: rdbzmain.o rdbz.o $(CASE)
+ $(CC) $(LDFLAGS) rdbzmain.o rdbz.o $(CASE) $(PRE) $(LIBS) $(POST) -o $@
+
+fake: fake.o random.o
+ $(CC) $(LDFLAGS) fake.o random.o $(PRE) $(LIBS) $(POST) -o $@
+
+byteflip: byteflip.o
+ $(CC) $(LDFLAGS) byteflip.o $(PRE) $(LIBS) $(POST) -o $@
+
+hist10: fake
+ ./fake -t -e 75 10000 >$@
+
+hist3.3: fake
+ ./fake -t -e 75 3300 >$@
+
+hist13: fake
+ ./fake -t -e 75 13000 >$@
+
+r: $(srcdir)/getmap $(srcdir)/revbytes $(srcdir)/altbytes stamp-r8
+ : success!
+
+stamp-r0:
+ : 'WARNING: creates about 2MB of debris; do "make rclean" afterward'
+ rm -f dbase dbase[23] dbase.* dbase[23].*
+ test ! -d xx || rmdir xx
+ @touch stamp-r0
+
+stamp-r1: $(RHIST) $(R2HIST) stamp-r0
+ : crude check of synthetic history file
+ ( sed 25q $(RHIST) ; tail -25 $(RHIST) ) >histjunk
+ cmp histjunk $(srcdir)/firstlast25
+ rm histjunk
+ @touch stamp-r1
+
+r2a: rdbz stamp-r1
+ : basic tests, exercising as many options as possible
+ cp $(RHIST) dbase
+ mkdir xx
+ chmod -w xx
+ ./rdbz -E 1000 -0 -M -i -S -u -U -C xx dbase
+ rmdir xx
+ sed '/> 0/d' $(RHIST) >dbase.used
+ test "`cat dbase.used | wc -l`" -eq "`sed -n '2s/ .*//p' dbase.dir`" ;
+
+stamp-r2: r2a
+ cp $(RHIST) dbase2
+ ./rdbz -E 1000 -0 -p $(RPSIZE) -t ' ' dbase2
+ cmp $(RHIST) dbase
+ cmp dbase dbase2
+ cmp dbase.dir dbase2.dir
+ cmp dbase.pag dbase2.pag
+ ./rdbz -E 1000 -0 -c dbase
+ ./rdbz -E 1000 -0 -c -i -q -M -U dbase
+ @touch stamp-r2
+
+stamp-r3: stamp-r2
+ : build a database and then add to it
+ sed 1000q $(RHIST) >dbase2
+ sed 1,1000d $(RHIST) >dbase2.add
+ ./rdbz -E 1000 -0 dbase2
+ ./rdbz -E 1000 -0 -a dbase2 dbase2.add
+ cmp dbase dbase2
+ cmp dbase.dir dbase2.dir
+ cmp dbase.pag dbase2.pag
+ @touch stamp-r3
+
+stamp-r4: stamp-r3
+ : build based on existing one, test extraction and readonly files
+ ./rdbz -E 1000 -0 -f dbase dbase2
+ test "`cat dbase.used | wc -l`" -eq "`awk 'NR==2{print $$1}' dbase2.dir`" ;
+ test "`cat dbase.used | wc -l`" -eq "`awk 'NR==2{print $$2}' dbase2.dir`" ;
+ chmod -w dbase2.dir dbase2.pag
+ ./rdbz -E 1000 -x dbase2 dbase >dbase.temp
+ cmp dbase.used dbase.temp
+ @touch stamp-r4
+
+stamp-r5: stamp-r4
+ : try some small case perversions
+ sed 's/\(@[^ ]*\)A/\1a/' dbase >dbase.ick
+ ./rdbz -E 1000 -x dbase2 dbase.ick >dbase.temp
+ cmp dbase.used dbase.temp
+ sed -n 's/A\([^ ]*@\)/a\1/p' dbase >dbase.ick
+ ./rdbz -x dbase2 dbase.ick >dbase.temp
+ test ! -s dbase.temp ;
+ rm -f dbase2.dir dbase2.pag
+ @touch stamp-r5
+
+stamp-r6: stamp-r5
+ : try it without tags, case-insensitive, with case perversions
+ ./rdbz -E 1000 -0 -p '0 b 1' dbase2
+ tr '[A-M][n-z]' '[a-m][N-Z]' <dbase2 >dbase.ick
+ ./rdbz -E 1000 -x dbase2 dbase.ick >dbase.temp
+ cmp dbase.used dbase.temp
+ rm -f dbase.temp dbase.ick
+ @touch stamp-r6
+
+stamp-r7: byteflip stamp-r6
+ : test various perversions of byte ordering
+ awk -f $(srcdir)/revbytes dbase.dir >dbase2.dir
+ ./byteflip `$(srcdir)/getmap dbase.dir` `$(srcdir)/getmap dbase2.dir` <dbase.pag >dbase2.pag
+ cp dbase dbase2
+ ./rdbz -E 1000 -0 -c dbase2
+ awk -f $(srcdir)/altbytes dbase.dir >dbase2.dir
+ dd conv=swab <dbase.pag >dbase2.pag
+ ./rdbz -E 1000 -0 -c dbase2
+ cp dbase2 dbase3
+ ./rdbz -E 1000 -0 -f dbase2 dbase3
+ ./rdbz -E 1000 -0 -c dbase3
+ test " `$(srcdir)/getmap dbase2.dir`" = " `$(srcdir)/getmap dbase3.dir`" ;
+ @touch stamp-r7
+
+stamp-r8: stamp-r7
+ : test massive overflow, throw in case sensitivity and tag mask
+ cp $(R2HIST) dbase
+ ./rdbz -E 1000 -0 -p '0 0 7ffc0000' dbase
+ ./rdbz -E 1000 -0 -cq dbase
+ sed 100q dbase | egrep '[aA].* ' | tr aA Aa >dbase.ick
+ ./rdbz -x dbase dbase.ick >dbase.temp
+ test ! -s dbase.temp ;
+ @touch stamp-r8
+
+rclean:
+ rm -f dbase dbase[23] dbase.* dbase[23].* fake fake.o random.o
+ rm -f rdbz rdbz.o rdbzmain.o $(RHIST) $(R2HIST) byteflip byteflip.o
+ rm -f histjunk core stamp-r? *~
+ test ! -d xx || rmdir xx
+
+mostlyclean: rclean
+ rm -f *.o [a-z]dbz [a-z][a-z]dbz junk* PostScript.out
+ rm -f hist* dbase* *.bak mon.out gmon.out core dbm.h
+
+clean: mostlyclean
+ rm -f dbz
+
+distclean: clean
+ rm -rf Makefile config.status rdbz.c rdbzmain.c
+
+maintainer-clean realclean: distclean
diff --git a/gnu/dist/libio/dbz/README b/gnu/dist/libio/dbz/README
new file mode 100644
index 00000000000..e7fa8765ad5
--- /dev/null
+++ b/gnu/dist/libio/dbz/README
@@ -0,0 +1,25 @@
+The dbz package was "liberated" from C News.
+It is included with the GNU libio because it provides
+a fairly good work-out for a stdio implementation.
+The Makefile.in, configure.in, and stdio.h have been
+set up to test libio.
+
+------
+
+This is the new, improved, lemon-freshened :-) dbz.
+
+Just "make" will get you dbz.o and the dbz program. "make r" runs an
+extensive set of regression tests; most of the mysterious oddments lying
+around here are to do with that. "make rclean" cleans up after "make r".
+
+You probably want to inspect the #ifdef list early in dbz.c before
+compiling, although the defaults should work all right on most systems.
+
+If you are not building this as part of C News, you will need to change
+the -I option in FLAGS in the Makefile to "-I.", and delete the DBMLIBS
+and RFC lines entirely. That will break some of the regression tests;
+at some point I'll fix this.
+
+If you are using this independently from C News, you probably still want
+to look through ../notebook/problems, as some of the portability problems
+described in there can affect dbz.
diff --git a/gnu/dist/libio/dbz/altbytes b/gnu/dist/libio/dbz/altbytes
new file mode 100644
index 00000000000..26cc9fb9e02
--- /dev/null
+++ b/gnu/dist/libio/dbz/altbytes
@@ -0,0 +1,7 @@
+NR == 1 {
+ printf "%s %s %s %s %s %s %s %s %s", $1, $2, $3, $4, $5, $6, $7, $8, $9
+ for (i = 10; i <= NF; i += 2)
+ printf " %s %s", $(i+1), $i
+ printf "\n"
+}
+NR > 1 { print }
diff --git a/gnu/dist/libio/dbz/byteflip.c b/gnu/dist/libio/dbz/byteflip.c
new file mode 100644
index 00000000000..d54c6591fa1
--- /dev/null
+++ b/gnu/dist/libio/dbz/byteflip.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+#define MAXWORD 32
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ register int len;
+ int inmap[MAXWORD];
+ int outmap[MAXWORD];
+ char in[MAXWORD];
+ char out[MAXWORD];
+ register int i;
+ register int a;
+
+ a = 1;
+ len = atoi(argv[a++]);
+ if (len > MAXWORD)
+ abort(); /* kind of drastic... */
+ for (i = 0; i < len; i++)
+ inmap[i] = atoi(argv[a++]);
+ if (atoi(argv[a++]) != len)
+ abort();
+ for (i = 0; i < len; i++)
+ outmap[i] = atoi(argv[a++]);
+
+ while (fread(in, 1, len, stdin) == len) {
+ for (i = 0; i < len; i++)
+ out[outmap[i]] = in[inmap[i]];
+ fwrite(out, 1, len, stdout);
+ }
+#ifdef DBZ_FINISH
+ DBZ_FINISH;
+#endif
+ exit(0);
+}
diff --git a/gnu/dist/libio/dbz/case.c b/gnu/dist/libio/dbz/case.c
new file mode 100644
index 00000000000..87b741ff54a
--- /dev/null
+++ b/gnu/dist/libio/dbz/case.c
@@ -0,0 +1,129 @@
+/*
+ * case-mapping stuff
+ *
+ * We exploit the fact that we are dealing only with headers here, and
+ * headers are limited to the ASCII characters by RFC822. It is barely
+ * possible that we might be dealing with a translation into another
+ * character set, but in particular it's very unlikely for a header
+ * character to be outside -128..255.
+ *
+ * Life would be a whole lot simpler if tolower() could safely and portably
+ * be applied to any char.
+ */
+#include <stdio.h>
+#include "string.h"
+#include "case.h"
+
+/* note that case.h knows the value of OFFSET */
+#define OFFSET 128 /* avoid trouble with negative chars */
+#define MAPSIZE (256+OFFSET)
+char casemap[MAPSIZE]; /* relies on init to '\0' */
+static int primed = 0; /* has casemap been set up? */
+
+/*
+ - prime - set up case-mapping stuff
+ */
+static void
+prime()
+{
+ register char *lp;
+ register char *up;
+ register int c;
+ register int i;
+ static char lower[] = "abcdefghijklmnopqrstuvwxyz";
+ static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ for (lp = lower, up = upper; *lp != '\0'; lp++, up++) {
+ c = *lp;
+ casemap[c+OFFSET] = c;
+ casemap[*up+OFFSET] = c;
+ }
+ for (i = 0; i < MAPSIZE; i++)
+ if (casemap[i] == '\0')
+ casemap[i] = (char)(i-OFFSET);
+ primed = 1;
+}
+
+/*
+ - cistrncmp - case-independent strncmp
+ */
+int /* < == > 0 */
+cistrncmp(s1, s2, len)
+char *s1;
+char *s2;
+int len;
+{
+ register char *p1;
+ register char *p2;
+ register int n;
+
+ if (!primed)
+ prime();
+
+ p1 = s1;
+ p2 = s2;
+ n = len;
+ while (--n >= 0 && *p1 != '\0' && TOLOW(*p1) == TOLOW(*p2)) {
+ p1++;
+ p2++;
+ }
+ if (n < 0)
+ return(0);
+
+ /*
+ * The following case analysis is necessary so that characters
+ * which look negative collate low against normal characters but
+ * high against the end-of-string NUL.
+ */
+ if (*p1 == '\0' && *p2 == '\0')
+ return(0);
+ else if (*p1 == '\0')
+ return(-1);
+ else if (*p2 == '\0')
+ return(1);
+ else
+ return(TOLOW(*p1) - TOLOW(*p2));
+}
+
+/*
+ - rfc822ize - do the bizarre case conversion needed for rfc822 message-ids
+ *
+ * Actually, this is not quite complete. Absolute, total, full RFC822
+ * compliance requires a horrible parsing job, because of the arcane
+ * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi,
+ * for example. There are three or four things that might occur in the
+ * domain part of a message-id that are case-sensitive. They don't seem
+ * to ever occur in real news, thank Cthulhu. (What? You were expecting
+ * a merciful and forgiving deity to be invoked in connection with RFC822?
+ * Forget it; none of them would come near it.)
+ */
+char * /* returns the argument */
+rfc822ize(s)
+char *s;
+{
+ register char *p;
+ static char post[] = "postmaster";
+ static int postlen = sizeof(post)-1;
+
+ if (!primed)
+ prime();
+
+ p = strrchr(s, '@');
+ if (p == NULL) /* no local/domain split */
+ p = ""; /* assume all local */
+ else if (p - (s+1) == postlen && CISTREQN(s+1, post, postlen)) {
+ /* crazy special case -- "postmaster" is case-insensitive */
+ p = s;
+ }
+#ifdef NONSTANDARD
+#ifdef RFCVIOLATION
+#ifdef B_2_11_MISTAKE
+ p = s; /* all case-insensitive */
+#endif
+#endif
+#endif
+ for (; *p != '\0'; p++)
+ *p = TOLOW(*p);
+
+ return(s);
+}
diff --git a/gnu/dist/libio/dbz/case.h b/gnu/dist/libio/dbz/case.h
new file mode 100644
index 00000000000..d5ef6961550
--- /dev/null
+++ b/gnu/dist/libio/dbz/case.h
@@ -0,0 +1,12 @@
+extern int cistrncmp();
+extern char *rfc822ize();
+
+extern char casemap[];
+
+/* must call cistrncmp before invoking TOLOW... */
+#define TOLOW(c) (casemap[(c)+128]) /* see case.c for why 128 */
+
+/* ...but the use of it in CISTREQN is safe without the preliminary call (!) */
+/* CISTREQN is an optimised case-insensitive strncmp(a,b,n)==0; n > 0 */
+#define CISTREQN(a, b, n) \
+ (TOLOW((a)[0]) == TOLOW((b)[0]) && cistrncmp(a, b, n) == 0)
diff --git a/gnu/dist/libio/dbz/configure.in b/gnu/dist/libio/dbz/configure.in
new file mode 100644
index 00000000000..4cb9b57ce0f
--- /dev/null
+++ b/gnu/dist/libio/dbz/configure.in
@@ -0,0 +1,17 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=
+srctrigger=dbzmain.c
+srcname="libio dbz test"
+
+# per-host:
+
+# per-target:
+
+files="dbz.c dbzmain.c"
+links="rdbz.c rdbzmain.c"
+
+# post-target:
+
diff --git a/gnu/dist/libio/dbz/dbz.1 b/gnu/dist/libio/dbz/dbz.1
new file mode 100644
index 00000000000..d2fff17af98
--- /dev/null
+++ b/gnu/dist/libio/dbz/dbz.1
@@ -0,0 +1,221 @@
+.TH DBZ 1 "11 Feb 1992"
+.BY "C News"
+.SH NAME
+dbz \- operate on dbz databases of text
+.SH SYNOPSIS
+.B dbz
+[
+.BR \- { axmc }
+] [
+.B \-t
+c
+] [
+.B \-l
+length
+] [
+.BR \- { qiue }
+] [
+.B \-f
+old
+] [
+.B \-p
+parms
+] database file ...
+.SH DESCRIPTION
+.I Dbz
+is a shell-level interface to the
+.IR dbz (3z)
+database routines for indexed access to a text file.
+.PP
+The
+.I database
+file must be a text file,
+one line per database record,
+with the key the first field on the line.
+The
+.B \-t
+option sets the field-separator character; the default is tab.
+Setting the separator character to NUL (with
+.BR "\-t\ ''" )
+makes the whole line the key.
+Lines must not exceed 1023 bytes in length including the newline;
+this limit can be increased with the
+.B \-l
+option.
+The limitations and restrictions of
+.IR dbz (3z)
+must also be observed;
+in particular, it remains the user's responsibility to ensure that
+no attempt is made to store two entries (whether identical or not)
+with the same key.
+.PP
+In the absence of options,
+.I dbz
+creates a
+.IR dbz (3z)
+index for the database;
+the index comprises files
+.IB database .pag
+and
+.IB database .dir
+in the same directory.
+Any previous index is silently overwritten.
+The
+.BR \-a ,
+.BR \-x ,
+.BR \-m ,
+and
+.B \-c
+options specify other operations.
+.PP
+With
+.BR \-a ,
+.I dbz
+appends lines from the
+.IR file (s)
+(standard input if none)
+to the database, updating both the
+text file and the indexes.
+.PP
+With
+.BR \-x ,
+.I dbz
+reads keys from the
+.IR file (s)
+(standard input if none)
+and prints (on standard output) the corresponding lines, if any,
+from the database.
+The input is in the form of database lines, although only the keys are
+significant.
+The
+.B \-q
+option makes
+.B \-x
+print the input lines whose keys are found instead of the database
+lines; this is somewhat faster.
+.PP
+With
+.BR \-m ,
+operation is the same as for
+.B \-x
+except that the keys which are \fInot\fR present in the database are printed.
+.PP
+With
+.BR \-c ,
+.I dbz
+checks the database for internal consistency.
+The
+.B \-q
+option causes this check to be done more quickly but less thoroughly
+(each key is looked up in the index, but no check is made to be sure
+that the index entry points to the right place).
+.PP
+The
+.B \-i
+option suppresses the use of
+.IR dbz (3z)'s
+.I incore
+facility.
+This makes accesses slower, but keeps the files current
+during updating
+and reduces
+startup/shutdown overhead.
+.PP
+Normally,
+.I dbz
+checks whether a key is already in the database before adding it.
+The
+.B \-u
+option suppresses this check, speeding things up at the expense of safety.
+.PP
+A new index is normally created with default size,
+case mapping, and tagging.
+The default size is right for 90-100,000 records.
+The default case mapping is right for RFC822 message-ids.
+See
+.IR dbz (3z)
+for what tagging is about.
+(Note, these defaults can be changed when
+.IR dbz (3z)
+is installed.)
+.PP
+If the
+.B \-f
+option is given,
+size, case mapping, and tagging
+are instead initialized based on the
+database
+.IR old .
+This is mostly useful when
+creating a new generation of an existing database.
+(See the description of
+.I dbzagain
+in
+.IR dbz (3z)
+for details.)
+.PP
+If the
+.B \-p
+option is given, the
+.I parms
+string specifies the size, case mapping, and tagging.
+If
+.I parms
+is a single decimal number,
+that is taken as the expected number of records
+in the index, with case mapping and tagging defaulted.
+Alternatively,
+.I parms
+can be three fields\(ema decimal number, a case-mapping code character, and a
+hexadecimal tag mask\(emseparated by white space.
+The decimal number is, again, the expected number of records;
+0 means ``use the default''.
+See
+.IR dbz (3z)
+for possible choices of case-mapping code,
+but in particular,
+.B 0
+means ``no case mapping''.
+See
+.IR dbz (3z)
+for details on tag masks;
+0 means ``use the default''.
+.PP
+If the
+.B \-e
+option is given, the decimal number in
+.B \-p
+is taken to be the exact table size, not the expected number of records,
+and invocation of
+.I dbzsize
+(see
+.IR dbz (3z))
+to predict a good size for that number of records is suppressed.
+.PP
+The
+.B \&.pag
+file is normally about 6 bytes per record (based on the estimate given to
+.B \-p
+or the previous history of the
+.B \-f
+database).
+The
+.B \&.dir
+file is tiny.
+.SH SEE ALSO
+dbz(3z)
+.SH HISTORY
+Written at U of Toronto by Henry Spencer, for the C News project.
+See
+.IR dbz (3z)
+for the history of the underlying database routines.
+.SH BUGS
+There are a number of undocumented options with obscure effects,
+meant for debugging and regression testing of
+.IR dbz (3z).
+.PP
+Permissions for the index files probably ought to be taken from those
+of the base file.
+.PP
+The line-length limit is a blemish, alleviated only slightly by
+.BR \-l .
diff --git a/gnu/dist/libio/dbz/dbz.3z b/gnu/dist/libio/dbz/dbz.3z
new file mode 100644
index 00000000000..6df25311c70
--- /dev/null
+++ b/gnu/dist/libio/dbz/dbz.3z
@@ -0,0 +1,547 @@
+.TH DBZ 3Z "3 Feb 1991"
+.BY "C News"
+.SH NAME
+dbminit, fetch, store, dbmclose \- somewhat dbm-compatible database routines
+.br
+dbzfresh, dbzagain, dbzfetch, dbzstore \- database routines
+.br
+dbzsync, dbzsize, dbzincore, dbzcancel, dbzdebug \- database routines
+.SH SYNOPSIS
+.nf
+.B #include <dbz.h>
+.PP
+.B dbminit(base)
+.B char *base;
+.PP
+.B datum
+.B fetch(key)
+.B datum key;
+.PP
+.B store(key, value)
+.B datum key;
+.B datum value;
+.PP
+.B dbmclose()
+.PP
+.B dbzfresh(base, size, fieldsep, cmap, tagmask)
+.B char *base;
+.B long size;
+.B int fieldsep;
+.B int cmap;
+.B long tagmask;
+.PP
+.B dbzagain(base, oldbase)
+.B char *base;
+.B char *oldbase;
+.PP
+.B datum
+.B dbzfetch(key)
+.B datum key;
+.PP
+.B dbzstore(key, value)
+.B datum key;
+.B datum value;
+.PP
+.B dbzsync()
+.PP
+.B long
+.B dbzsize(nentries)
+.B long nentries;
+.PP
+.B dbzincore(newvalue)
+.PP
+.B dbzcancel()
+.PP
+.B dbzdebug(newvalue)
+.SH DESCRIPTION
+These functions provide an indexing system for rapid random access to a
+text file (the
+.I base
+.IR file ).
+Subject to certain constraints, they are call-compatible with
+.IR dbm (3),
+although they also provide some extensions.
+(Note that they are
+.I not
+file-compatible with
+.I dbm
+or any variant thereof.)
+.PP
+In principle,
+.I dbz
+stores key-value pairs, where both key and value are arbitrary sequences
+of bytes, specified to the functions by
+values of type
+.IR datum ,
+typedefed in the header file to be a structure with members
+.I dptr
+(a value of type
+.I char *
+pointing to the bytes)
+and
+.I dsize
+(a value of type
+.I int
+indicating how long the byte sequence is).
+.PP
+In practice,
+.I dbz
+is more restricted than
+.IR dbm .
+A
+.I dbz
+database
+must be an index into a base file,
+with the database
+.IR value s
+being
+.IR fseek (3)
+offsets into the base file.
+Each such
+.I value
+must ``point to'' a place in the base file where the corresponding
+.I key
+sequence is found.
+A key can be no longer than
+.SM DBZMAXKEY
+(a constant defined in the header file) bytes.
+No key can be an initial subsequence of another,
+which in most applications requires that keys be
+either bracketed or terminated in some way (see the
+discussion of the
+.I fieldsep
+parameter of
+.IR dbzfresh ,
+below,
+for a fine point on terminators).
+.PP
+.I Dbminit
+opens a database,
+an index into the base file
+.IR base ,
+consisting of files
+.IB base .dir
+and
+.IB base .pag
+which must already exist.
+(If the database is new, they should be zero-length files.)
+Subsequent accesses go to that database until
+.I dbmclose
+is called to close the database.
+The base file need not exist at the time of the
+.IR dbminit ,
+but it must exist before accesses are attempted.
+.PP
+.I Fetch
+searches the database for the specified
+.IR key ,
+returning the corresponding
+.IR value
+if any.
+.I Store
+stores the
+.IR key - value
+pair in the database.
+.I Store
+will fail unless the database files are writeable.
+See below for a complication arising from case mapping.
+.PP
+.I Dbzfresh
+is a variant of
+.I dbminit
+for creating a new database with more control over details.
+Unlike for
+.IR dbminit ,
+the database files need not exist:
+they will be created if necessary,
+and truncated in any case.
+.PP
+.IR Dbzfresh 's
+.I size
+parameter specifies the size of the first hash table within the database,
+in key-value pairs.
+Performance will be best if
+.I size
+is a prime number and
+the number of key-value pairs stored in the database does not exceed
+about 2/3 of
+.IR size .
+(The
+.I dbzsize
+function, given the expected number of key-value pairs,
+will suggest a database size that meets these criteria.)
+Assuming that an
+.I fseek
+offset is 4 bytes,
+the
+.B .pag
+file will be
+.RI 4* size
+bytes
+(the
+.B .dir
+file is tiny and roughly constant in size)
+until
+the number of key-value pairs exceeds about 80% of
+.IR size .
+(Nothing awful will happen if the database grows beyond 100% of
+.IR size ,
+but accesses will slow down somewhat and the
+.B .pag
+file will grow somewhat.)
+.PP
+.IR Dbzfresh 's
+.I fieldsep
+parameter specifies the field separator in the base file.
+If this is not
+NUL (0), and the last character of a
+.I key
+argument is NUL, that NUL compares equal to either a NUL or a
+.I fieldsep
+in the base file.
+This permits use of NUL to terminate key strings without requiring that
+NULs appear in the base file.
+The
+.I fieldsep
+of a database created with
+.I dbminit
+is the horizontal-tab character.
+.PP
+For use in news systems, various forms of case mapping (e.g. uppercase to
+lowercase) in keys are available.
+The
+.I cmap
+parameter to
+.I dbzfresh
+is a single character specifying which of several mapping algorithms to use.
+Available algorithms are:
+.RS
+.TP
+.B 0
+case-sensitive: no case mapping
+.TP
+.B B
+same as
+.B 0
+.TP
+.B NUL
+same as
+.B 0
+.TP
+.B =
+case-insensitive: uppercase and lowercase equivalent
+.TP
+.B b
+same as
+.B =
+.TP
+.B C
+RFC822 message-ID rules, case-sensitive before `@' (with certain exceptions)
+and case-insensitive after
+.TP
+.B ?
+whatever the local default is, normally
+.B C
+.RE
+.PP
+Mapping algorithm
+.B 0
+(no mapping) is faster than the others and is overwhelmingly the correct
+choice for most applications.
+Unless compatibility constraints interfere, it is more efficient to pre-map
+the keys, storing mapped keys in the base file, than to have
+.I dbz
+do the mapping on every search.
+.PP
+For historical reasons,
+.I fetch
+and
+.I store
+expect their
+.I key
+arguments to be pre-mapped, but expect unmapped keys in the base file.
+.I Dbzfetch
+and
+.I dbzstore
+do the same jobs but handle all case mapping internally,
+so the customer need not worry about it.
+.PP
+.I Dbz
+stores only the database
+.IR value s
+in its files, relying on reference to the base file to confirm a hit on a key.
+References to the base file can be minimized, greatly speeding up searches,
+if a little bit of information about the keys can be stored in the
+.I dbz
+files.
+This is ``free'' if there are some unused bits in an
+.I fseek
+offset,
+so that the offset can be
+.I tagged
+with some information about the key.
+The
+.I tagmask
+parameter of
+.I dbzfresh
+allows specifying the location of unused bits.
+.I Tagmask
+should be a mask with
+one group of
+contiguous
+.B 1
+bits.
+The bits in the mask should
+be unused (0) in
+.I most
+offsets.
+The bit immediately above the mask (the
+.I flag
+bit) should be unused (0) in
+.I all
+offsets;
+.I (dbz)store
+will reject attempts to store a key-value pair in which the
+.I value
+has the flag bit on.
+Apart from this restriction, tagging is invisible to the user.
+As a special case, a
+.I tagmask
+of 1 means ``no tagging'', for use with enormous base files or
+on systems with unusual offset representations.
+.PP
+A
+.I size
+of 0
+given to
+.I dbzfresh
+is synonymous with the local default;
+the normal default is suitable for tables of 90-100,000
+key-value pairs.
+A
+.I cmap
+of 0 (NUL) is synonymous with the character
+.BR 0 ,
+signifying no case mapping
+(note that the character
+.B ?
+specifies the local default mapping,
+normally
+.BR C ).
+A
+.I tagmask
+of 0 is synonymous with the local default tag mask,
+normally 0x7f000000 (specifying the top bit in a 32-bit offset
+as the flag bit, and the next 7 bits as the mask,
+which is suitable for base files up to circa 24MB).
+Calling
+.I dbminit(name)
+with the database files empty is equivalent to calling
+.IR dbzfresh(name,0,'\et','?',0) .
+.PP
+When databases are regenerated periodically, as in news,
+it is simplest to pick the parameters for a new database based on the old one.
+This also permits some memory of past sizes of the old database, so that
+a new database size can be chosen to cover expected fluctuations.
+.I Dbzagain
+is a variant of
+.I dbminit
+for creating a new database as a new generation of an old database.
+The database files for
+.I oldbase
+must exist.
+.I Dbzagain
+is equivalent to calling
+.I dbzfresh
+with the same field separator, case mapping, and tag mask as the old database,
+and a
+.I size
+equal to the result of applying
+.I dbzsize
+to the largest number of entries in the
+.I oldbase
+database and its previous 10 generations.
+.PP
+When many accesses are being done by the same program,
+.I dbz
+is massively faster if its first hash table is in memory.
+If an internal flag is 1,
+an attempt is made to read the table in when
+the database is opened, and
+.I dbmclose
+writes it out to disk again (if it was read successfully and
+has been modified).
+.I Dbzincore
+sets the flag to
+.I newvalue
+(which should be 0 or 1)
+and returns the previous value;
+this does not affect the status of a database that has already been opened.
+The default is 0.
+The attempt to read the table in may fail due to memory shortage;
+in this case
+.I dbz
+quietly falls back on its default behavior.
+.IR Store s
+to an in-memory database are not (in general) written out to the file
+until
+.IR dbmclose
+or
+.IR dbzsync ,
+so if robustness in the presence of crashes
+or concurrent accesses
+is crucial, in-memory databases
+should probably be avoided.
+.PP
+.I Dbzsync
+causes all buffers etc. to be flushed out to the files.
+It is typically used as a precaution against crashes or concurrent accesses
+when a
+.IR dbz -using
+process will be running for a long time.
+It is a somewhat expensive operation,
+especially
+for an in-memory database.
+.PP
+.I Dbzcancel
+cancels any pending writes from buffers.
+This is typically useful only for in-core databases, since writes are
+otherwise done immediately.
+Its main purpose is to let a child process, in the wake of a
+.IR fork ,
+do a
+.I dbmclose
+without writing its parent's data to disk.
+.PP
+If
+.I dbz
+has been compiled with debugging facilities available (which makes it
+bigger and a bit slower),
+.I dbzdebug
+alters the value (and returns the previous value) of an internal flag
+which (when 1; default is 0) causes
+verbose and cryptic debugging output on standard output.
+.PP
+Concurrent reading of databases is fairly safe,
+but there is no (inter)locking,
+so concurrent updating is not.
+.PP
+The database files include a record of the byte order of the processor
+creating the database, and accesses by processors with different byte
+order will work, although they will be slightly slower.
+Byte order is preserved by
+.IR dbzagain .
+However,
+agreement on the size and internal structure of an
+.I fseek
+offset is necessary, as is consensus on
+the character set.
+.PP
+An open database occupies three
+.I stdio
+streams and their corresponding file descriptors;
+a fourth is needed for an in-memory database.
+Memory consumption is negligible (except for
+.I stdio
+buffers) except for in-memory databases.
+.SH SEE ALSO
+dbz(1), dbm(3)
+.SH DIAGNOSTICS
+Functions returning
+.I int
+values return 0 for success, \-1 for failure.
+Functions returning
+.I datum
+values return a value with
+.I dptr
+set to NULL for failure.
+.I Dbminit
+attempts to have
+.I errno
+set plausibly on return, but otherwise this is not guaranteed.
+An
+.I errno
+of
+.B EDOM
+from
+.I dbminit
+indicates that the database did not appear to be in
+.I dbz
+format.
+.SH HISTORY
+The original
+.I dbz
+was written by
+Jon Zeeff (zeeff@b-tech.ann-arbor.mi.us).
+Later contributions by David Butler and Mark Moraes.
+Extensive reworking,
+including this documentation,
+by Henry Spencer (henry@zoo.toronto.edu) as
+part of the C News project.
+Hashing function by Peter Honeyman.
+.SH BUGS
+The
+.I dptr
+members of returned
+.I datum
+values point to static storage which is overwritten by later calls.
+.PP
+Unlike
+.IR dbm ,
+.I dbz
+will misbehave if an existing key-value pair is `overwritten' by
+a new
+.I (dbz)store
+with the same key.
+The user is responsible for avoiding this by using
+.I (dbz)fetch
+first to check for duplicates;
+an internal optimization remembers the result of the
+first search so there is minimal overhead in this.
+.PP
+Waiting until after
+.I dbminit
+to bring the base file into existence
+will fail if
+.IR chdir (2)
+has been used meanwhile.
+.PP
+The RFC822 case mapper implements only a first approximation to the
+hideously-complex RFC822 case rules.
+.PP
+The prime finder in
+.I dbzsize
+is not particularly quick.
+.PP
+Should implement the
+.I dbm
+functions
+.IR delete ,
+.IR firstkey ,
+and
+.IR nextkey .
+.PP
+On C implementations which trap integer overflow,
+.I dbz
+will refuse to
+.I (dbz)store
+an
+.I fseek
+offset equal to the greatest
+representable
+positive number,
+as this would cause overflow in the biased representation used.
+.PP
+.I Dbzagain
+perhaps ought to notice when many offsets
+in the old database were
+too big for
+tagging, and shrink the tag mask to match.
+.PP
+Marking
+.IR dbz 's
+file descriptors
+.RI close-on- exec
+would be a better approach to the problem
+.I dbzcancel
+tries to address, but that's harder to do portably.
diff --git a/gnu/dist/libio/dbz/dbz.c b/gnu/dist/libio/dbz/dbz.c
new file mode 100644
index 00000000000..7489a09d15a
--- /dev/null
+++ b/gnu/dist/libio/dbz/dbz.c
@@ -0,0 +1,1768 @@
+/*
+
+dbz.c V3.2
+
+Copyright 1988 Jon Zeeff (zeeff@b-tech.ann-arbor.mi.us)
+You can use this code in any manner, as long as you leave my name on it
+and don't hold me responsible for any problems with it.
+
+Hacked on by gdb@ninja.UUCP (David Butler); Sun Jun 5 00:27:08 CDT 1988
+
+Various improvments + INCORE by moraes@ai.toronto.edu (Mark Moraes)
+
+Major reworking by Henry Spencer as part of the C News project.
+
+These routines replace dbm as used by the usenet news software
+(it's not a full dbm replacement by any means). It's fast and
+simple. It contains no AT&T code.
+
+In general, dbz's files are 1/20 the size of dbm's. Lookup performance
+is somewhat better, while file creation is spectacularly faster, especially
+if the incore facility is used.
+
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#ifndef __STDC__
+extern int errno;
+#endif
+#include <dbz.h>
+
+/*
+ * #ifdef index. "LIA" = "leave it alone unless you know what you're doing".
+ *
+ * FUNNYSEEKS SEEK_SET is not 0, get it from <unistd.h>
+ * INDEX_SIZE backward compatibility with old dbz; avoid using this
+ * NMEMORY number of days of memory for use in sizing new table (LIA)
+ * INCORE backward compatibility with old dbz; use dbzincore() instead
+ * DBZDEBUG enable debugging
+ * DEFSIZE default table size (not as critical as in old dbz)
+ * OLDBNEWS default case mapping as in old B News; set NOBUFFER
+ * BNEWS default case mapping as in current B News; set NOBUFFER
+ * DEFCASE default case-map algorithm selector
+ * NOTAGS fseek offsets are strange, do not do tagging (see below)
+ * NPAGBUF size of .pag buffer, in longs (LIA)
+ * SHISTBUF size of ASCII-file buffer, in bytes (LIA)
+ * MAXRUN length of run which shifts to next table (see below) (LIA)
+ * OVERFLOW long-int arithmetic overflow must be avoided, will trap
+ * NOBUFFER do not buffer hash-table i/o, B News locking is defective
+ */
+
+#ifdef FUNNYSEEKS
+#include <unistd.h>
+#else
+#define SEEK_SET 0
+#endif
+#ifdef OVERFLOW
+#include <limits.h>
+#endif
+
+static int dbzversion = 3; /* for validating .dir file format */
+
+/*
+ * The dbz database exploits the fact that when news stores a <key,value>
+ * tuple, the `value' part is a seek offset into a text file, pointing to
+ * a copy of the `key' part. This avoids the need to store a copy of
+ * the key in the dbz files. However, the text file *must* exist and be
+ * consistent with the dbz files, or things will fail.
+ *
+ * The basic format of the database is a simple hash table containing the
+ * values. A value is stored by indexing into the table using a hash value
+ * computed from the key; collisions are resolved by linear probing (just
+ * search forward for an empty slot, wrapping around to the beginning of
+ * the table if necessary). Linear probing is a performance disaster when
+ * the table starts to get full, so a complication is introduced. The
+ * database is actually one *or more* tables, stored sequentially in the
+ * .pag file, and the length of linear-probe sequences is limited. The
+ * search (for an existing item or an empty slot) always starts in the
+ * first table, and whenever MAXRUN probes have been done in table N,
+ * probing continues in table N+1. This behaves reasonably well even in
+ * cases of massive overflow. There are some other small complications
+ * added, see comments below.
+ *
+ * The table size is fixed for any particular database, but is determined
+ * dynamically when a database is rebuilt. The strategy is to try to pick
+ * the size so the first table will be no more than 2/3 full, that being
+ * slightly before the point where performance starts to degrade. (It is
+ * desirable to be a bit conservative because the overflow strategy tends
+ * to produce files with holes in them, which is a nuisance.)
+ */
+
+/*
+ * The following is for backward compatibility.
+ */
+#ifdef INDEX_SIZE
+#define DEFSIZE INDEX_SIZE
+#endif
+
+/*
+ * ANSI C says the offset argument to fseek is a long, not an off_t, for some
+ * reason. Let's use off_t anyway.
+ */
+#define SOF (sizeof(off_t))
+
+/*
+ * We assume that unused areas of a binary file are zeros, and that the
+ * bit pattern of `(off_t)0' is all zeros. The alternative is rather
+ * painful file initialization. Note that okayvalue(), if OVERFLOW is
+ * defined, knows what value of an offset would cause overflow.
+ */
+#define VACANT ((off_t)0)
+#define BIAS(o) ((o)+1) /* make any valid off_t non-VACANT */
+#define UNBIAS(o) ((o)-1) /* reverse BIAS() effect */
+
+/*
+ * In a Unix implementation, or indeed any in which an off_t is a byte
+ * count, there are a bunch of high bits free in an off_t. There is a
+ * use for them. Checking a possible hit by looking it up in the base
+ * file is relatively expensive, and the cost can be dramatically reduced
+ * by using some of those high bits to tag the value with a few more bits
+ * of the key's hash. This detects most false hits without the overhead of
+ * seek+read+strcmp. We use the top bit to indicate whether the value is
+ * tagged or not, and don't tag a value which is using the tag bits itself.
+ * We're in trouble if the off_t representation wants to use the top bit.
+ * The actual bitmasks and offset come from the configuration stuff,
+ * which permits fiddling with them as necessary, and also suppressing
+ * them completely (by defining the masks to 0). We build pre-shifted
+ * versions of the masks for efficiency.
+ */
+static off_t tagbits; /* pre-shifted tag mask */
+static off_t taghere; /* pre-shifted tag-enable bit */
+static off_t tagboth; /* tagbits|taghere */
+#define HASTAG(o) ((o)&taghere)
+#define TAG(o) ((o)&tagbits)
+#define NOTAG(o) ((o)&~tagboth)
+#define CANTAG(o) (((o)&tagboth) == 0)
+#define MKTAG(v) (((v)<<conf.tagshift)&tagbits)
+
+/*
+ * A new, from-scratch database, not built as a rebuild of an old one,
+ * needs to know table size, casemap algorithm, and tagging. Normally
+ * the user supplies this info, but there have to be defaults.
+ */
+#ifndef DEFSIZE
+#define DEFSIZE 120011 /* 300007 might be better */
+#endif
+#ifdef OLDBNEWS
+#define DEFCASE '0' /* B2.10 -- no mapping */
+#define NOBUFFER /* B News locking is defective */
+#endif
+#ifdef BNEWS
+#define DEFCASE '=' /* B2.11 -- all mapped */
+#define NOBUFFER /* B News locking is defective */
+#endif
+#ifndef DEFCASE /* C News compatibility is the default */
+#define DEFCASE 'C' /* C News -- RFC822 mapping */
+#endif
+#ifndef NOTAGS
+#define TAGENB 0x80 /* tag enable is top bit, tag is next 7 */
+#define TAGMASK 0x7f
+#define TAGSHIFT 24
+#else
+#define TAGENB 0 /* no tags */
+#define TAGMASK 0
+#define TAGSHIFT 0
+#endif
+
+/*
+ * We read configuration info from the .dir file into this structure,
+ * so we can avoid wired-in assumptions for an existing database.
+ *
+ * Among the info is a record of recent peak usages, so that a new table
+ * size can be chosen intelligently when rebuilding. 10 is a good
+ * number of usages to keep, since news displays marked fluctuations
+ * in volume on a 7-day cycle.
+ */
+struct dbzconfig {
+ int olddbz; /* .dir file empty but .pag not? */
+ off_t tsize; /* table size */
+# ifndef NMEMORY
+# define NMEMORY 10 /* # days of use info to remember */
+# endif
+# define NUSEDS (1+NMEMORY)
+ off_t used[NUSEDS]; /* entries used today, yesterday, ... */
+ int valuesize; /* size of table values, == SOF */
+ int bytemap[SOF]; /* byte-order map */
+ char casemap; /* case-mapping algorithm (see cipoint()) */
+ char fieldsep; /* field separator in base file, if any */
+ off_t tagenb; /* unshifted tag-enable bit */
+ off_t tagmask; /* unshifted tag mask */
+ int tagshift; /* shift count for tagmask and tagenb */
+};
+static struct dbzconfig conf;
+static int getconf();
+static long getno();
+static int putconf();
+static void mybytemap();
+static off_t bytemap();
+
+/*
+ * For a program that makes many, many references to the database, it
+ * is a large performance win to keep the table in core, if it will fit.
+ * Note that this does hurt robustness in the event of crashes, and
+ * dbmclose() *must* be called to flush the in-core database to disk.
+ * The code is prepared to deal with the possibility that there isn't
+ * enough memory. There *is* an assumption that a size_t is big enough
+ * to hold the size (in bytes) of one table, so dbminit() tries to figure
+ * out whether this is possible first.
+ *
+ * The preferred way to ask for an in-core table is to do dbzincore(1)
+ * before dbminit(). The default is not to do it, although -DINCORE
+ * overrides this for backward compatibility with old dbz.
+ *
+ * We keep only the first table in core. This greatly simplifies the
+ * code, and bounds memory demand. Furthermore, doing this is a large
+ * performance win even in the event of massive overflow.
+ */
+#ifdef INCORE
+static int incore = 1;
+#else
+static int incore = 0;
+#endif
+
+/*
+ * Stdio buffer for .pag reads. Buffering more than about 16 does not help
+ * significantly at the densities we try to maintain, and the much larger
+ * buffers that most stdios default to are much more expensive to fill.
+ * With small buffers, stdio is performance-competitive with raw read(),
+ * and it's much more portable.
+ */
+#ifndef NPAGBUF
+#define NPAGBUF 16
+#endif
+#ifndef NOBUFFER
+#ifdef _IOFBF
+static off_t pagbuf[NPAGBUF]; /* only needed if !NOBUFFER && _IOFBF */
+#endif
+#endif
+
+/*
+ * Stdio buffer for base-file reads. Message-IDs (all news ever needs to
+ * read) are essentially never longer than 64 bytes, and the typical stdio
+ * buffer is so much larger that it is much more expensive to fill.
+ */
+#ifndef SHISTBUF
+#define SHISTBUF 64
+#endif
+#ifdef _IOFBF
+static char basebuf[SHISTBUF]; /* only needed if _IOFBF exists */
+#endif
+
+/*
+ * Data structure for recording info about searches.
+ */
+struct searcher {
+ off_t place; /* current location in file */
+ int tabno; /* which table we're in */
+ int run; /* how long we'll stay in this table */
+# ifndef MAXRUN
+# define MAXRUN 100
+# endif
+ long hash; /* the key's hash code (for optimization) */
+ off_t tag; /* tag we are looking for */
+ int seen; /* have we examined current location? */
+ int aborted; /* has i/o error aborted search? */
+};
+static void start();
+#define FRESH ((struct searcher *)NULL)
+static off_t search();
+#define NOTFOUND ((off_t)-1)
+static int okayvalue();
+static int set();
+
+/*
+ * Arguably the searcher struct for a given routine ought to be local to
+ * it, but a fetch() is very often immediately followed by a store(), and
+ * in some circumstances it is a useful performance win to remember where
+ * the fetch() completed. So we use a global struct and remember whether
+ * it is current.
+ */
+static struct searcher srch;
+static struct searcher *prevp; /* &srch or FRESH */
+
+/* byte-ordering stuff */
+static int mybmap[SOF]; /* my byte order (see mybytemap()) */
+static int bytesame; /* is database order same as mine? */
+#define MAPIN(o) ((bytesame) ? (o) : bytemap((o), conf.bytemap, mybmap))
+#define MAPOUT(o) ((bytesame) ? (o) : bytemap((o), mybmap, conf.bytemap))
+
+/*
+ * The double parentheses needed to make this work are ugly, but the
+ * alternative (under most compilers) is to pack around 2K of unused
+ * strings -- there's just no way to get rid of them.
+ */
+static int debug; /* controlled by dbzdebug() */
+#ifdef DBZDEBUG
+#define DEBUG(args) if (debug) { (void) printf args ; }
+#else
+#define DEBUG(args) ;
+#endif
+
+/* externals used */
+extern char *malloc();
+extern char *calloc();
+extern void free(); /* ANSI C; some old implementations say int */
+extern int atoi();
+extern long atol();
+
+/* misc. forwards */
+static long hash();
+static void crcinit();
+static char *cipoint();
+static char *mapcase();
+static int isprime();
+static FILE *latebase();
+
+/* file-naming stuff */
+static char dir[] = ".dir";
+static char pag[] = ".pag";
+static char *enstring();
+
+/* central data structures */
+static FILE *basef; /* descriptor for base file */
+static char *basefname; /* name for not-yet-opened base file */
+static FILE *dirf; /* descriptor for .dir file */
+static int dirronly; /* dirf open read-only? */
+static FILE *pagf = NULL; /* descriptor for .pag file */
+static off_t pagpos; /* posn in pagf; only search may set != -1 */
+static int pagronly; /* pagf open read-only? */
+static off_t *corepag; /* incore version of .pag file, if any */
+static FILE *bufpagf; /* well-buffered pagf, for incore rewrite */
+static off_t *getcore();
+static int putcore();
+static int written; /* has a store() been done? */
+
+/*
+ - dbzfresh - set up a new database, no historical info
+ */
+int /* 0 success, -1 failure */
+dbzfresh(name, size, fs, cmap, tagmask)
+char *name; /* base name; .dir and .pag must exist */
+long size; /* table size (0 means default) */
+int fs; /* field-separator character in base file */
+int cmap; /* case-map algorithm (0 means default) */
+off_t tagmask; /* 0 default, 1 no tags */
+{
+ register char *fn;
+ struct dbzconfig c;
+ register off_t m;
+ register FILE *f;
+
+ if (pagf != NULL) {
+ DEBUG(("dbzfresh: database already open\n"));
+ return(-1);
+ }
+ if (size != 0 && size < 2) {
+ DEBUG(("dbzfresh: preposterous size (%ld)\n", size));
+ return(-1);
+ }
+
+ /* get default configuration */
+ if (getconf((FILE *)NULL, (FILE *)NULL, &c) < 0)
+ return(-1); /* "can't happen" */
+
+ /* and mess with it as specified */
+ if (size != 0)
+ c.tsize = size;
+ c.fieldsep = fs;
+ switch (cmap) {
+ case 0:
+ case '0':
+ case 'B': /* 2.10 compat */
+ c.casemap = '0'; /* '\0' nicer, but '0' printable! */
+ break;
+ case '=':
+ case 'b': /* 2.11 compat */
+ c.casemap = '=';
+ break;
+ case 'C':
+ c.casemap = 'C';
+ break;
+ case '?':
+ c.casemap = DEFCASE;
+ break;
+ default:
+ DEBUG(("dbzfresh case map `%c' unknown\n", cmap));
+ return(-1);
+ break;
+ }
+ switch (tagmask) {
+ case 0: /* default */
+ break;
+ case 1: /* no tags */
+ c.tagshift = 0;
+ c.tagmask = 0;
+ c.tagenb = 0;
+ break;
+ default:
+ m = tagmask;
+ c.tagshift = 0;
+ while (!(m&01)) {
+ m >>= 1;
+ c.tagshift++;
+ }
+ c.tagmask = m;
+ c.tagenb = (m << 1) & ~m;
+ break;
+ }
+
+ /* write it out */
+ fn = enstring(name, dir);
+ if (fn == NULL)
+ return(-1);
+ f = fopen(fn, "w");
+ free(fn);
+ if (f == NULL) {
+ DEBUG(("dbzfresh: unable to write config\n"));
+ return(-1);
+ }
+ if (putconf(f, &c) < 0) {
+ (void) fclose(f);
+ return(-1);
+ }
+ if (fclose(f) == EOF) {
+ DEBUG(("dbzfresh: fclose failure\n"));
+ return(-1);
+ }
+
+ /* create/truncate .pag */
+ fn = enstring(name, pag);
+ if (fn == NULL)
+ return(-1);
+ f = fopen(fn, "w");
+ free(fn);
+ if (f == NULL) {
+ DEBUG(("dbzfresh: unable to create/truncate .pag file\n"));
+ return(-1);
+ } else
+ (void) fclose(f);
+
+ /* and punt to dbminit for the hard work */
+ return(dbminit(name));
+}
+
+/*
+ - dbzsize - what's a good table size to hold this many entries?
+ */
+long
+dbzsize(contents)
+long contents; /* 0 means what's the default */
+{
+ register long n;
+
+ if (contents <= 0) { /* foulup or default inquiry */
+ DEBUG(("dbzsize: preposterous input (%ld)\n", contents));
+ return(DEFSIZE);
+ }
+ n = (contents/2)*3; /* try to keep table at most 2/3 full */
+ if (!(n&01)) /* make it odd */
+ n++;
+ DEBUG(("dbzsize: tentative size %ld\n", n));
+ while (!isprime(n)) /* and look for a prime */
+ n += 2;
+ DEBUG(("dbzsize: final size %ld\n", n));
+
+ return(n);
+}
+
+/*
+ - isprime - is a number prime?
+ *
+ * This is not a terribly efficient approach.
+ */
+static int /* predicate */
+isprime(x)
+register long x;
+{
+ static int quick[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 0 };
+ register int *ip;
+ register long div;
+ register long stop;
+
+ /* hit the first few primes quickly to eliminate easy ones */
+ /* this incidentally prevents ridiculously small tables */
+ for (ip = quick; (div = *ip) != 0; ip++)
+ if (x%div == 0) {
+ DEBUG(("isprime: quick result on %ld\n", (long)x));
+ return(0);
+ }
+
+ /* approximate square root of x */
+ for (stop = x; x/stop < stop; stop >>= 1)
+ continue;
+ stop <<= 1;
+
+ /* try odd numbers up to stop */
+ for (div = *--ip; div < stop; div += 2)
+ if (x%div == 0)
+ return(0);
+
+ return(1);
+}
+
+/*
+ - dbzagain - set up a new database to be a rebuild of an old one
+ */
+int /* 0 success, -1 failure */
+dbzagain(name, oldname)
+char *name; /* base name; .dir and .pag must exist */
+char *oldname; /* base name; all must exist */
+{
+ register char *fn;
+ struct dbzconfig c;
+ register int i;
+ register long top;
+ register FILE *f;
+ register int newtable;
+ register off_t newsize;
+
+ if (pagf != NULL) {
+ DEBUG(("dbzagain: database already open\n"));
+ return(-1);
+ }
+
+ /* pick up the old configuration */
+ fn = enstring(oldname, dir);
+ if (fn == NULL)
+ return(-1);
+ f = fopen(fn, "r");
+ free(fn);
+ if (f == NULL) {
+ DEBUG(("dbzagain: cannot open old .dir file\n"));
+ return(-1);
+ }
+ i = getconf(f, (FILE *)NULL, &c);
+ (void) fclose(f);
+ if (i < 0) {
+ DEBUG(("dbzagain: getconf failed\n"));
+ return(-1);
+ }
+
+ /* tinker with it */
+ top = 0;
+ newtable = 0;
+ for (i = 0; i < NUSEDS; i++) {
+ if (top < c.used[i])
+ top = c.used[i];
+ if (c.used[i] == 0)
+ newtable = 1; /* hasn't got full usage history yet */
+ }
+ if (top == 0) {
+ DEBUG(("dbzagain: old table has no contents!\n"));
+ newtable = 1;
+ }
+ for (i = NUSEDS-1; i > 0; i--)
+ c.used[i] = c.used[i-1];
+ c.used[0] = 0;
+ newsize = dbzsize(top);
+ if (!newtable || newsize > c.tsize) /* don't shrink new table */
+ c.tsize = newsize;
+
+ /* write it out */
+ fn = enstring(name, dir);
+ if (fn == NULL)
+ return(-1);
+ f = fopen(fn, "w");
+ free(fn);
+ if (f == NULL) {
+ DEBUG(("dbzagain: unable to write new .dir\n"));
+ return(-1);
+ }
+ i = putconf(f, &c);
+ (void) fclose(f);
+ if (i < 0) {
+ DEBUG(("dbzagain: putconf failed\n"));
+ return(-1);
+ }
+
+ /* create/truncate .pag */
+ fn = enstring(name, pag);
+ if (fn == NULL)
+ return(-1);
+ f = fopen(fn, "w");
+ free(fn);
+ if (f == NULL) {
+ DEBUG(("dbzagain: unable to create/truncate .pag file\n"));
+ return(-1);
+ } else
+ (void) fclose(f);
+
+ /* and let dbminit do the work */
+ return(dbminit(name));
+}
+
+/*
+ - dbminit - open a database, creating it (using defaults) if necessary
+ *
+ * We try to leave errno set plausibly, to the extent that underlying
+ * functions permit this, since many people consult it if dbminit() fails.
+ */
+int /* 0 success, -1 failure */
+dbminit(name)
+char *name;
+{
+ register int i;
+ register size_t s;
+ register char *dirfname;
+ register char *pagfname;
+
+ if (pagf != NULL) {
+ DEBUG(("dbminit: dbminit already called once\n"));
+ errno = 0;
+ return(-1);
+ }
+
+ /* open the .dir file */
+ dirfname = enstring(name, dir);
+ if (dirfname == NULL)
+ return(-1);
+ dirf = fopen(dirfname, "r+");
+ if (dirf == NULL) {
+ dirf = fopen(dirfname, "r");
+ dirronly = 1;
+ } else
+ dirronly = 0;
+ free(dirfname);
+ if (dirf == NULL) {
+ DEBUG(("dbminit: can't open .dir file\n"));
+ return(-1);
+ }
+
+ /* open the .pag file */
+ pagfname = enstring(name, pag);
+ if (pagfname == NULL) {
+ (void) fclose(dirf);
+ return(-1);
+ }
+ pagf = fopen(pagfname, "r+b");
+ if (pagf == NULL) {
+ pagf = fopen(pagfname, "rb");
+ if (pagf == NULL) {
+ DEBUG(("dbminit: .pag open failed\n"));
+ (void) fclose(dirf);
+ free(pagfname);
+ return(-1);
+ }
+ pagronly = 1;
+ } else if (dirronly)
+ pagronly = 1;
+ else
+ pagronly = 0;
+#ifdef NOBUFFER
+ /*
+ * B News does not do adequate locking on its database accesses.
+ * Why it doesn't get into trouble using dbm is a mystery. In any
+ * case, doing unbuffered i/o does not cure the problem, but does
+ * enormously reduce its incidence.
+ */
+ (void) setbuf(pagf, (char *)NULL);
+#else
+#ifdef _IOFBF
+ (void) setvbuf(pagf, (char *)pagbuf, _IOFBF, sizeof(pagbuf));
+#endif
+#endif
+ pagpos = -1;
+ /* don't free pagfname, need it below */
+
+ /* open the base file */
+ basef = fopen(name, "r");
+ if (basef == NULL) {
+ DEBUG(("dbminit: basefile open failed\n"));
+ basefname = enstring(name, "");
+ if (basefname == NULL) {
+ (void) fclose(pagf);
+ (void) fclose(dirf);
+ free(pagfname);
+ pagf = NULL;
+ return(-1);
+ }
+ } else
+ basefname = NULL;
+#ifdef _IOFBF
+ if (basef != NULL)
+ (void) setvbuf(basef, basebuf, _IOFBF, sizeof(basebuf));
+#endif
+
+ /* pick up configuration */
+ if (getconf(dirf, pagf, &conf) < 0) {
+ DEBUG(("dbminit: getconf failure\n"));
+ (void) fclose(basef);
+ (void) fclose(pagf);
+ (void) fclose(dirf);
+ free(pagfname);
+ pagf = NULL;
+ errno = EDOM; /* kind of a kludge, but very portable */
+ return(-1);
+ }
+ tagbits = conf.tagmask << conf.tagshift;
+ taghere = conf.tagenb << conf.tagshift;
+ tagboth = tagbits | taghere;
+ mybytemap(mybmap);
+ bytesame = 1;
+ for (i = 0; i < SOF; i++)
+ if (mybmap[i] != conf.bytemap[i])
+ bytesame = 0;
+
+ /* get first table into core, if it looks desirable and feasible */
+ s = (size_t)conf.tsize * SOF;
+ if (incore && (off_t)(s/SOF) == conf.tsize) {
+ bufpagf = fopen(pagfname, (pagronly) ? "rb" : "r+b");
+ if (bufpagf != NULL)
+ corepag = getcore(bufpagf);
+ } else {
+ bufpagf = NULL;
+ corepag = NULL;
+ }
+ free(pagfname);
+
+ /* misc. setup */
+ crcinit();
+ written = 0;
+ prevp = FRESH;
+ DEBUG(("dbminit: succeeded\n"));
+ return(0);
+}
+
+/*
+ - enstring - concatenate two strings into a malloced area
+ */
+static char * /* NULL if malloc fails */
+enstring(s1, s2)
+char *s1;
+char *s2;
+{
+ register char *p;
+
+ p = malloc((size_t)strlen(s1) + (size_t)strlen(s2) + 1);
+ if (p != NULL) {
+ (void) strcpy(p, s1);
+ (void) strcat(p, s2);
+ } else {
+ DEBUG(("enstring(%s, %s) out of memory\n", s1, s2));
+ }
+ return(p);
+}
+
+/*
+ - dbmclose - close a database
+ */
+int
+dbmclose()
+{
+ register int ret = 0;
+
+ if (pagf == NULL) {
+ DEBUG(("dbmclose: not opened!\n"));
+ return(-1);
+ }
+
+ if (fclose(pagf) == EOF) {
+ DEBUG(("dbmclose: fclose(pagf) failed\n"));
+ ret = -1;
+ }
+ pagf = basef; /* ensure valid pointer; dbzsync checks it */
+ if (dbzsync() < 0)
+ ret = -1;
+ if (bufpagf != NULL && fclose(bufpagf) == EOF) {
+ DEBUG(("dbmclose: fclose(bufpagf) failed\n"));
+ ret = -1;
+ }
+ if (corepag != NULL)
+ free((char *)corepag);
+ corepag = NULL;
+ if (fclose(basef) == EOF) {
+ DEBUG(("dbmclose: fclose(basef) failed\n"));
+ ret = -1;
+ }
+ if (basefname != NULL)
+ free(basefname);
+ basef = NULL;
+ pagf = NULL;
+ if (fclose(dirf) == EOF) {
+ DEBUG(("dbmclose: fclose(dirf) failed\n"));
+ ret = -1;
+ }
+
+ DEBUG(("dbmclose: %s\n", (ret == 0) ? "succeeded" : "failed"));
+ return(ret);
+}
+
+/*
+ - dbzsync - push all in-core data out to disk
+ */
+int
+dbzsync()
+{
+ register int ret = 0;
+
+ if (pagf == NULL) {
+ DEBUG(("dbzsync: not opened!\n"));
+ return(-1);
+ }
+ if (!written)
+ return(0);
+
+ if (corepag != NULL) {
+ if (putcore(corepag, bufpagf) < 0) {
+ DEBUG(("dbzsync: putcore failed\n"));
+ ret = -1;
+ }
+ }
+ if (!conf.olddbz)
+ if (putconf(dirf, &conf) < 0)
+ ret = -1;
+
+ DEBUG(("dbzsync: %s\n", (ret == 0) ? "succeeded" : "failed"));
+ return(ret);
+}
+
+/*
+ - dbzcancel - cancel writing of in-core data
+ * Mostly for use from child processes.
+ * Note that we don't need to futz around with stdio buffers, because we
+ * always fflush them immediately anyway and so they never have stale data.
+ */
+int
+dbzcancel()
+{
+ if (pagf == NULL) {
+ DEBUG(("dbzcancel: not opened!\n"));
+ return(-1);
+ }
+
+ written = 0;
+ return(0);
+}
+
+/*
+ - dbzfetch - fetch() with case mapping built in
+ */
+datum
+dbzfetch(key)
+datum key;
+{
+ char buffer[DBZMAXKEY + 1];
+ datum mappedkey;
+ register size_t keysize;
+
+ DEBUG(("dbzfetch: (%s)\n", key.dptr));
+
+ /* Key is supposed to be less than DBZMAXKEY */
+ keysize = key.dsize;
+ if (keysize >= DBZMAXKEY) {
+ keysize = DBZMAXKEY;
+ DEBUG(("keysize is %d - truncated to %d\n", key.dsize, DBZMAXKEY));
+ }
+
+ mappedkey.dptr = mapcase(buffer, key.dptr, keysize);
+ buffer[keysize] = '\0'; /* just a debug aid */
+ mappedkey.dsize = keysize;
+
+ return(fetch(mappedkey));
+}
+
+/*
+ - fetch - get an entry from the database
+ *
+ * Disgusting fine point, in the name of backward compatibility: if the
+ * last character of "key" is a NUL, that character is (effectively) not
+ * part of the comparison against the stored keys.
+ */
+datum /* dptr NULL, dsize 0 means failure */
+fetch(key)
+datum key;
+{
+ char buffer[DBZMAXKEY + 1];
+ static off_t key_ptr; /* return value points here */
+ datum output;
+ register size_t keysize;
+ register size_t cmplen;
+ register char *sepp;
+
+ DEBUG(("fetch: (%s)\n", key.dptr));
+ output.dptr = NULL;
+ output.dsize = 0;
+ prevp = FRESH;
+
+ /* Key is supposed to be less than DBZMAXKEY */
+ keysize = key.dsize;
+ if (keysize >= DBZMAXKEY) {
+ keysize = DBZMAXKEY;
+ DEBUG(("keysize is %d - truncated to %d\n", key.dsize, DBZMAXKEY));
+ }
+
+ if (pagf == NULL) {
+ DEBUG(("fetch: database not open!\n"));
+ return(output);
+ } else if (basef == NULL) { /* basef didn't exist yet */
+ basef = latebase();
+ if (basef == NULL)
+ return(output);
+ }
+
+ cmplen = keysize;
+ sepp = &conf.fieldsep;
+ if (key.dptr[keysize-1] == '\0') {
+ cmplen--;
+ sepp = &buffer[keysize-1];
+ }
+ start(&srch, &key, FRESH);
+ while ((key_ptr = search(&srch)) != NOTFOUND) {
+ DEBUG(("got 0x%lx\n", key_ptr));
+
+ /* fetch the key */
+ if (fseek(basef, key_ptr, SEEK_SET) != 0) {
+ DEBUG(("fetch: seek failed\n"));
+ return(output);
+ }
+ if (fread(buffer, 1, keysize, basef) != keysize) {
+ DEBUG(("fetch: read failed\n"));
+ return(output);
+ }
+
+ /* try it */
+ buffer[keysize] = '\0'; /* terminated for DEBUG */
+ (void) mapcase(buffer, buffer, keysize);
+ DEBUG(("fetch: buffer (%s) looking for (%s) size = %d\n",
+ buffer, key.dptr, keysize));
+ if (memcmp(key.dptr, buffer, cmplen) == 0 &&
+ (*sepp == conf.fieldsep || *sepp == '\0')) {
+ /* we found it */
+ output.dptr = (char *)&key_ptr;
+ output.dsize = SOF;
+ DEBUG(("fetch: successful\n"));
+ return(output);
+ }
+ }
+
+ /* we didn't find it */
+ DEBUG(("fetch: failed\n"));
+ prevp = &srch; /* remember where we stopped */
+ return(output);
+}
+
+/*
+ - latebase - try to open a base file that wasn't there at the start
+ */
+static FILE *
+latebase()
+{
+ register FILE *it;
+
+ if (basefname == NULL) {
+ DEBUG(("latebase: name foulup\n"));
+ return(NULL);
+ }
+ it = fopen(basefname, "r");
+ if (it == NULL) {
+ DEBUG(("latebase: still can't open base\n"));
+ } else {
+ DEBUG(("latebase: late open succeeded\n"));
+ free(basefname);
+ basefname = NULL;
+#ifdef _IOFBF
+ (void) setvbuf(it, basebuf, _IOFBF, sizeof(basebuf));
+#endif
+ }
+ return(it);
+}
+
+/*
+ - dbzstore - store() with case mapping built in
+ */
+int
+dbzstore(key, data)
+datum key;
+datum data;
+{
+ char buffer[DBZMAXKEY + 1];
+ datum mappedkey;
+ register size_t keysize;
+
+ DEBUG(("dbzstore: (%s)\n", key.dptr));
+
+ /* Key is supposed to be less than DBZMAXKEY */
+ keysize = key.dsize;
+ if (keysize >= DBZMAXKEY) {
+ DEBUG(("dbzstore: key size too big (%d)\n", key.dsize));
+ return(-1);
+ }
+
+ mappedkey.dptr = mapcase(buffer, key.dptr, keysize);
+ buffer[keysize] = '\0'; /* just a debug aid */
+ mappedkey.dsize = keysize;
+
+ return(store(mappedkey, data));
+}
+
+/*
+ - store - add an entry to the database
+ */
+int /* 0 success, -1 failure */
+store(key, data)
+datum key;
+datum data;
+{
+ off_t value;
+
+ if (pagf == NULL) {
+ DEBUG(("store: database not open!\n"));
+ return(-1);
+ } else if (basef == NULL) { /* basef didn't exist yet */
+ basef = latebase();
+ if (basef == NULL)
+ return(-1);
+ }
+ if (pagronly) {
+ DEBUG(("store: database open read-only\n"));
+ return(-1);
+ }
+ if (data.dsize != SOF) {
+ DEBUG(("store: value size wrong (%d)\n", data.dsize));
+ return(-1);
+ }
+ if (key.dsize >= DBZMAXKEY) {
+ DEBUG(("store: key size too big (%d)\n", key.dsize));
+ return(-1);
+ }
+
+ /* copy the value in to ensure alignment */
+ (void) memcpy((char *)&value, data.dptr, SOF);
+ DEBUG(("store: (%s, %ld)\n", key.dptr, (long)value));
+ if (!okayvalue(value)) {
+ DEBUG(("store: reserved bit or overflow in 0x%lx\n", value));
+ return(-1);
+ }
+
+ /* find the place, exploiting previous search if possible */
+ start(&srch, &key, prevp);
+ while (search(&srch) != NOTFOUND)
+ continue;
+
+ prevp = FRESH;
+ conf.used[0]++;
+ DEBUG(("store: used count %ld\n", conf.used[0]));
+ written = 1;
+ return(set(&srch, value));
+}
+
+/*
+ - dbzincore - control attempts to keep .pag file in core
+ */
+int /* old setting */
+dbzincore(value)
+int value;
+{
+ register int old = incore;
+
+ incore = value;
+ return(old);
+}
+
+/*
+ - getconf - get configuration from .dir file
+ */
+static int /* 0 success, -1 failure */
+getconf(df, pf, cp)
+register FILE *df; /* NULL means just give me the default */
+register FILE *pf; /* NULL means don't care about .pag */
+register struct dbzconfig *cp;
+{
+ register int c;
+ register int i;
+ int err = 0;
+
+ c = (df != NULL) ? getc(df) : EOF;
+ if (c == EOF) { /* empty file, no configuration known */
+ cp->olddbz = 0;
+ if (df != NULL && pf != NULL && getc(pf) != EOF)
+ cp->olddbz = 1;
+ cp->tsize = DEFSIZE;
+ cp->fieldsep = '\t';
+ for (i = 0; i < NUSEDS; i++)
+ cp->used[i] = 0;
+ cp->valuesize = SOF;
+ mybytemap(cp->bytemap);
+ cp->casemap = DEFCASE;
+ cp->tagenb = TAGENB;
+ cp->tagmask = TAGMASK;
+ cp->tagshift = TAGSHIFT;
+ DEBUG(("getconf: defaults (%ld, %c, (0x%lx/0x%lx<<%d))\n",
+ cp->tsize, cp->casemap, cp->tagenb,
+ cp->tagmask, cp->tagshift));
+ return(0);
+ }
+ (void) ungetc(c, df);
+
+ /* first line, the vital stuff */
+ if (getc(df) != 'd' || getc(df) != 'b' || getc(df) != 'z')
+ err = -1;
+ if (getno(df, &err) != dbzversion)
+ err = -1;
+ cp->tsize = getno(df, &err);
+ cp->fieldsep = getno(df, &err);
+ while ((c = getc(df)) == ' ')
+ continue;
+ cp->casemap = c;
+ cp->tagenb = getno(df, &err);
+ cp->tagmask = getno(df, &err);
+ cp->tagshift = getno(df, &err);
+ cp->valuesize = getno(df, &err);
+ if (cp->valuesize != SOF) {
+ DEBUG(("getconf: wrong off_t size (%d)\n", cp->valuesize));
+ err = -1;
+ cp->valuesize = SOF; /* to protect the loops below */
+ }
+ for (i = 0; i < cp->valuesize; i++)
+ cp->bytemap[i] = getno(df, &err);
+ if (getc(df) != '\n')
+ err = -1;
+ DEBUG(("size %ld, sep %d, cmap %c, tags 0x%lx/0x%lx<<%d, ", cp->tsize,
+ cp->fieldsep, cp->casemap, cp->tagenb, cp->tagmask,
+ cp->tagshift));
+ DEBUG(("bytemap (%d)", cp->valuesize));
+ for (i = 0; i < cp->valuesize; i++) {
+ DEBUG((" %d", cp->bytemap[i]));
+ }
+ DEBUG(("\n"));
+
+ /* second line, the usages */
+ for (i = 0; i < NUSEDS; i++)
+ cp->used[i] = getno(df, &err);
+ if (getc(df) != '\n')
+ err = -1;
+ DEBUG(("used %ld %ld %ld...\n", cp->used[0], cp->used[1], cp->used[2]));
+
+ if (err < 0) {
+ DEBUG(("getconf error\n"));
+ return(-1);
+ }
+ return(0);
+}
+
+/*
+ - getno - get a long
+ */
+static long
+getno(f, ep)
+FILE *f;
+int *ep;
+{
+ register char *p;
+# define MAXN 50
+ char getbuf[MAXN];
+ register int c;
+
+ while ((c = getc(f)) == ' ')
+ continue;
+ if (c == EOF || c == '\n') {
+ DEBUG(("getno: missing number\n"));
+ *ep = -1;
+ return(0);
+ }
+ p = getbuf;
+ *p++ = c;
+ while ((c = getc(f)) != EOF && c != '\n' && c != ' ')
+ if (p < &getbuf[MAXN-1])
+ *p++ = c;
+ if (c == EOF) {
+ DEBUG(("getno: EOF\n"));
+ *ep = -1;
+ } else
+ (void) ungetc(c, f);
+ *p = '\0';
+
+ if (strspn(getbuf, "-1234567890") != strlen(getbuf)) {
+ DEBUG(("getno: `%s' non-numeric\n", getbuf));
+ *ep = -1;
+ }
+ return(atol(getbuf));
+}
+
+/*
+ - putconf - write configuration to .dir file
+ */
+static int /* 0 success, -1 failure */
+putconf(f, cp)
+register FILE *f;
+register struct dbzconfig *cp;
+{
+ register int i;
+ register int ret = 0;
+
+ if (fseek(f, 0, SEEK_SET) != 0) {
+ DEBUG(("fseek failure in putconf\n"));
+ ret = -1;
+ }
+ fprintf(f, "dbz %d %ld %d %c %ld %ld %d %d", dbzversion,
+ (long)cp->tsize,
+ cp->fieldsep, cp->casemap, (long)cp->tagenb,
+ (long)cp->tagmask, cp->tagshift,
+ cp->valuesize);
+
+ for (i = 0; i < cp->valuesize; i++)
+ fprintf(f, " %d", cp->bytemap[i]);
+ fprintf(f, "\n");
+ for (i = 0; i < NUSEDS; i++)
+ fprintf(f, "%ld%c",
+ (long)cp->used[i], (i < NUSEDS-1) ? ' ' : '\n');
+
+
+ (void) fflush(f);
+ if (ferror(f))
+ ret = -1;
+
+ DEBUG(("putconf status %d\n", ret));
+ return(ret);
+}
+
+/*
+ - getcore - try to set up an in-core copy of .pag file
+ */
+static off_t * /* pointer to copy, or NULL */
+getcore(f)
+FILE *f;
+{
+ register off_t *p;
+ register size_t i;
+ register size_t nread;
+ register char *it;
+
+ it = malloc((size_t)conf.tsize * SOF);
+ if (it == NULL) {
+ DEBUG(("getcore: malloc failed\n"));
+ return(NULL);
+ }
+
+ nread = fread(it, SOF, (size_t)conf.tsize, f);
+ if (ferror(f)) {
+ DEBUG(("getcore: read failed\n"));
+ free(it);
+ return(NULL);
+ }
+
+ p = (off_t *)it + nread;
+ i = (size_t)conf.tsize - nread;
+ while (i-- > 0)
+ *p++ = VACANT;
+ return((off_t *)it);
+}
+
+/*
+ - putcore - try to rewrite an in-core table
+ */
+static int /* 0 okay, -1 fail */
+putcore(tab, f)
+off_t *tab;
+FILE *f;
+{
+ if (fseek(f, 0, SEEK_SET) != 0) {
+ DEBUG(("fseek failure in putcore\n"));
+ return(-1);
+ }
+ (void) fwrite((char *)tab, SOF, (size_t)conf.tsize, f);
+ (void) fflush(f);
+ return((ferror(f)) ? -1 : 0);
+}
+
+/*
+ - start - set up to start or restart a search
+ */
+static void
+start(sp, kp, osp)
+register struct searcher *sp;
+register datum *kp;
+register struct searcher *osp; /* may be FRESH, i.e. NULL */
+{
+ register long h;
+
+ h = hash(kp->dptr, kp->dsize);
+ if (osp != FRESH && osp->hash == h) {
+ if (sp != osp)
+ *sp = *osp;
+ DEBUG(("search restarted\n"));
+ } else {
+ sp->hash = h;
+ sp->tag = MKTAG(h / conf.tsize);
+ DEBUG(("tag 0x%lx\n", sp->tag));
+ sp->place = h % conf.tsize;
+ sp->tabno = 0;
+ sp->run = (conf.olddbz) ? conf.tsize : MAXRUN;
+ sp->aborted = 0;
+ }
+ sp->seen = 0;
+}
+
+/*
+ - search - conduct part of a search
+ */
+static off_t /* NOTFOUND if we hit VACANT or error */
+search(sp)
+register struct searcher *sp;
+{
+ register off_t dest;
+ register off_t value;
+ off_t val; /* buffer for value (can't fread register) */
+ register off_t place;
+
+ if (sp->aborted)
+ return(NOTFOUND);
+
+ for (;;) {
+ /* determine location to be examined */
+ place = sp->place;
+ if (sp->seen) {
+ /* go to next location */
+ if (--sp->run <= 0) {
+ sp->tabno++;
+ sp->run = MAXRUN;
+ }
+ place = (place+1)%conf.tsize + sp->tabno*conf.tsize;
+ sp->place = place;
+ } else
+ sp->seen = 1; /* now looking at current location */
+ DEBUG(("search @ %ld\n", place));
+
+ /* get the tagged value */
+ if (corepag != NULL && place < conf.tsize) {
+ DEBUG(("search: in core\n"));
+ value = MAPIN(corepag[place]);
+ } else {
+ /* seek, if necessary */
+ dest = place * SOF;
+ if (pagpos != dest) {
+ if (fseek(pagf, dest, SEEK_SET) != 0) {
+ DEBUG(("search: seek failed\n"));
+ pagpos = -1;
+ sp->aborted = 1;
+ return(NOTFOUND);
+ }
+ pagpos = dest;
+ }
+
+ /* read it */
+ if (fread((char *)&val, sizeof(val), 1, pagf) == 1)
+ value = MAPIN(val);
+ else if (ferror(pagf)) {
+ DEBUG(("search: read failed\n"));
+ pagpos = -1;
+ sp->aborted = 1;
+ return(NOTFOUND);
+ } else
+ value = VACANT;
+
+ /* and finish up */
+ pagpos += sizeof(val);
+ }
+
+ /* vacant slot is always cause to return */
+ if (value == VACANT) {
+ DEBUG(("search: empty slot\n"));
+ return(NOTFOUND);
+ };
+
+ /* check the tag */
+ value = UNBIAS(value);
+ DEBUG(("got 0x%lx\n", value));
+ if (!HASTAG(value)) {
+ DEBUG(("tagless\n"));
+ return(value);
+ } else if (TAG(value) == sp->tag) {
+ DEBUG(("match\n"));
+ return(NOTAG(value));
+ } else {
+ DEBUG(("mismatch 0x%lx\n", TAG(value)));
+ }
+ }
+ /* NOTREACHED */
+}
+
+/*
+ - okayvalue - check that a value can be stored
+ */
+static int /* predicate */
+okayvalue(value)
+off_t value;
+{
+ if (HASTAG(value))
+ return(0);
+#ifdef OVERFLOW
+ if (value == LONG_MAX) /* BIAS() and UNBIAS() will overflow */
+ return(0);
+#endif
+ return(1);
+}
+
+/*
+ - set - store a value into a location previously found by search
+ */
+static int /* 0 success, -1 failure */
+set(sp, value)
+register struct searcher *sp;
+off_t value;
+{
+ register off_t place = sp->place;
+ register off_t v = value;
+
+ if (sp->aborted)
+ return(-1);
+
+ if (CANTAG(v) && !conf.olddbz) {
+ v |= sp->tag | taghere;
+ if (v != UNBIAS(VACANT)) /* BIAS(v) won't look VACANT */
+#ifdef OVERFLOW
+ if (v != LONG_MAX) /* and it won't overflow */
+#endif
+ value = v;
+ }
+ DEBUG(("tagged value is 0x%lx\n", value));
+ value = BIAS(value);
+ value = MAPOUT(value);
+
+ /* If we have the index file in memory, use it */
+ if (corepag != NULL && place < conf.tsize) {
+ corepag[place] = value;
+ DEBUG(("set: incore\n"));
+ return(0);
+ }
+
+ /* seek to spot */
+ pagpos = -1; /* invalidate position memory */
+ if (fseek(pagf, place * SOF, SEEK_SET) != 0) {
+ DEBUG(("set: seek failed\n"));
+ sp->aborted = 1;
+ return(-1);
+ }
+
+ /* write in data */
+ if (fwrite((char *)&value, SOF, 1, pagf) != 1) {
+ DEBUG(("set: write failed\n"));
+ sp->aborted = 1;
+ return(-1);
+ }
+ /* fflush improves robustness, and buffer re-use is rare anyway */
+ if (fflush(pagf) == EOF) {
+ DEBUG(("set: fflush failed\n"));
+ sp->aborted = 1;
+ return(-1);
+ }
+
+ DEBUG(("set: succeeded\n"));
+ return(0);
+}
+
+/*
+ - mybytemap - determine this machine's byte map
+ *
+ * A byte map is an array of ints, sizeof(off_t) of them. The 0th int
+ * is the byte number of the high-order byte in my off_t, and so forth.
+ */
+static void
+mybytemap(map)
+int map[]; /* -> int[SOF] */
+{
+ union {
+ off_t o;
+ char c[SOF];
+ } u;
+ register int *mp = &map[SOF];
+ register int ntodo;
+ register int i;
+
+ u.o = 1;
+ for (ntodo = (int)SOF; ntodo > 0; ntodo--) {
+ for (i = 0; i < SOF; i++)
+ if (u.c[i] != 0)
+ break;
+ if (i == SOF) {
+ /* trouble -- set it to *something* consistent */
+ DEBUG(("mybytemap: nonexistent byte %d!!!\n", ntodo));
+ for (i = 0; i < SOF; i++)
+ map[i] = i;
+ return;
+ }
+ DEBUG(("mybytemap: byte %d\n", i));
+ *--mp = i;
+ while (u.c[i] != 0)
+ u.o <<= 1;
+ }
+}
+
+/*
+ - bytemap - transform an off_t from byte ordering map1 to map2
+ */
+static off_t /* transformed result */
+bytemap(ino, map1, map2)
+off_t ino;
+int *map1;
+int *map2;
+{
+ union oc {
+ off_t o;
+ char c[SOF];
+ };
+ union oc in;
+ union oc out;
+ register int i;
+
+ in.o = ino;
+ for (i = 0; i < SOF; i++)
+ out.c[map2[i]] = in.c[map1[i]];
+ return(out.o);
+}
+
+/*
+ * This is a simplified version of the pathalias hashing function.
+ * Thanks to Steve Belovin and Peter Honeyman
+ *
+ * hash a string into a long int. 31 bit crc (from andrew appel).
+ * the crc table is computed at run time by crcinit() -- we could
+ * precompute, but it takes 1 clock tick on a 750.
+ *
+ * This fast table calculation works only if POLY is a prime polynomial
+ * in the field of integers modulo 2. Since the coefficients of a
+ * 32-bit polynomial won't fit in a 32-bit word, the high-order bit is
+ * implicit. IT MUST ALSO BE THE CASE that the coefficients of orders
+ * 31 down to 25 are zero. Happily, we have candidates, from
+ * E. J. Watson, "Primitive Polynomials (Mod 2)", Math. Comp. 16 (1962):
+ * x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + x^0
+ * x^31 + x^3 + x^0
+ *
+ * We reverse the bits to get:
+ * 111101010000000000000000000000001 but drop the last 1
+ * f 5 0 0 0 0 0 0
+ * 010010000000000000000000000000001 ditto, for 31-bit crc
+ * 4 8 0 0 0 0 0 0
+ */
+
+#define POLY 0x48000000L /* 31-bit polynomial (avoids sign problems) */
+
+static long CrcTable[128];
+
+/*
+ - crcinit - initialize tables for hash function
+ */
+static void
+crcinit()
+{
+ register int i, j;
+ register long sum;
+
+ for (i = 0; i < 128; ++i) {
+ sum = 0L;
+ for (j = 7 - 1; j >= 0; --j)
+ if (i & (1 << j))
+ sum ^= POLY >> j;
+ CrcTable[i] = sum;
+ }
+ DEBUG(("crcinit: done\n"));
+}
+
+/*
+ - hash - Honeyman's nice hashing function
+ */
+static long
+hash(name, size)
+register char *name;
+register int size;
+{
+ register long sum = 0L;
+
+ while (size--) {
+ sum = (sum >> 7) ^ CrcTable[(sum ^ (*name++)) & 0x7f];
+ }
+ DEBUG(("hash: returns (%ld)\n", sum));
+ return(sum);
+}
+
+/*
+ * case-mapping stuff
+ *
+ * Borrowed from C News, by permission of the authors. Somewhat modified.
+ *
+ * We exploit the fact that we are dealing only with headers here, and
+ * headers are limited to the ASCII characters by RFC822. It is barely
+ * possible that we might be dealing with a translation into another
+ * character set, but in particular it's very unlikely for a header
+ * character to be outside -128..255.
+ *
+ * Life would be a whole lot simpler if tolower() could safely and portably
+ * be applied to any char.
+ */
+
+#define OFFSET 128 /* avoid trouble with negative chars */
+
+/* must call casencmp before invoking TOLOW... */
+#define TOLOW(c) (cmap[(c)+OFFSET])
+
+/* ...but the use of it in CISTREQN is safe without the preliminary call (!) */
+/* CISTREQN is an optimised case-insensitive strncmp(a,b,n)==0; n > 0 */
+#define CISTREQN(a, b, n) \
+ (TOLOW((a)[0]) == TOLOW((b)[0]) && casencmp(a, b, n) == 0)
+
+#define MAPSIZE (256+OFFSET)
+static char cmap[MAPSIZE]; /* relies on init to '\0' */
+static int mprimed = 0; /* has cmap been set up? */
+
+/*
+ - mapprime - set up case-mapping stuff
+ */
+static void
+mapprime()
+{
+ register char *lp;
+ register char *up;
+ register int c;
+ register int i;
+ static char lower[] = "abcdefghijklmnopqrstuvwxyz";
+ static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ for (lp = lower, up = upper; *lp != '\0'; lp++, up++) {
+ c = *lp;
+ cmap[c+OFFSET] = c;
+ cmap[*up+OFFSET] = c;
+ }
+ for (i = 0; i < MAPSIZE; i++)
+ if (cmap[i] == '\0')
+ cmap[i] = (char)(i-OFFSET);
+ mprimed = 1;
+}
+
+/*
+ - casencmp - case-independent strncmp
+ */
+static int /* < == > 0 */
+casencmp(s1, s2, len)
+char *s1;
+char *s2;
+int len;
+{
+ register char *p1;
+ register char *p2;
+ register int n;
+
+ if (!mprimed)
+ mapprime();
+
+ p1 = s1;
+ p2 = s2;
+ n = len;
+ while (--n >= 0 && *p1 != '\0' && TOLOW(*p1) == TOLOW(*p2)) {
+ p1++;
+ p2++;
+ }
+ if (n < 0)
+ return(0);
+
+ /*
+ * The following case analysis is necessary so that characters
+ * which look negative collate low against normal characters but
+ * high against the end-of-string NUL.
+ */
+ if (*p1 == '\0' && *p2 == '\0')
+ return(0);
+ else if (*p1 == '\0')
+ return(-1);
+ else if (*p2 == '\0')
+ return(1);
+ else
+ return(TOLOW(*p1) - TOLOW(*p2));
+}
+
+/*
+ - mapcase - do case-mapped copy
+ */
+static char * /* returns src or dst */
+mapcase(dst, src, siz)
+char *dst; /* destination, used only if mapping needed */
+char *src; /* source; src == dst is legal */
+size_t siz;
+{
+ register char *s;
+ register char *d;
+ register char *c; /* case break */
+ register char *e; /* end of source */
+
+
+ c = cipoint(src, siz);
+ if (c == NULL)
+ return(src);
+
+ if (!mprimed)
+ mapprime();
+ s = src;
+ e = s + siz;
+ d = dst;
+
+ while (s < c)
+ *d++ = *s++;
+ while (s < e)
+ *d++ = TOLOW(*s++);
+
+ return(dst);
+}
+
+/*
+ - cipoint - where in this message-ID does it become case-insensitive?
+ *
+ * The RFC822 code is not quite complete. Absolute, total, full RFC822
+ * compliance requires a horrible parsing job, because of the arcane
+ * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi,
+ * for example. There are three or four things that might occur in the
+ * domain part of a message-id that are case-sensitive. They don't seem
+ * to ever occur in real news, thank Cthulhu. (What? You were expecting
+ * a merciful and forgiving deity to be invoked in connection with RFC822?
+ * Forget it; none of them would come near it.)
+ */
+static char * /* pointer into s, or NULL for "nowhere" */
+cipoint(s, siz)
+char *s;
+size_t siz;
+{
+ register char *p;
+ static char post[] = "postmaster";
+ static int plen = sizeof(post)-1;
+
+ switch (conf.casemap) {
+ case '0': /* unmapped, sensible */
+ return(NULL);
+ break;
+ case 'C': /* C News, RFC 822 conformant (approx.) */
+ p = memchr(s, '@', siz);
+ if (p == NULL) /* no local/domain split */
+ return(NULL); /* assume all local */
+ else if (p - (s+1) == plen && CISTREQN(s+1, post, plen)) {
+ /* crazy -- "postmaster" is case-insensitive */
+ return(s);
+ } else
+ return(p);
+ break;
+ case '=': /* 2.11, neither sensible nor conformant */
+ return(s); /* all case-insensitive */
+ break;
+ }
+
+ DEBUG(("cipoint: unknown case mapping `%c'\n", conf.casemap));
+ return(NULL); /* just leave it alone */
+}
+
+/*
+ - dbzdebug - control dbz debugging at run time
+ */
+int /* old value */
+dbzdebug(value)
+int value;
+{
+#ifdef DBZDEBUG
+ register int old = debug;
+
+ debug = value;
+ return(old);
+#else
+ return(-1);
+#endif
+}
diff --git a/gnu/dist/libio/dbz/dbz.h b/gnu/dist/libio/dbz/dbz.h
new file mode 100644
index 00000000000..3d7e8ed702c
--- /dev/null
+++ b/gnu/dist/libio/dbz/dbz.h
@@ -0,0 +1,32 @@
+/* for dbm and dbz */
+typedef struct {
+ char *dptr;
+ int dsize;
+} datum;
+
+/* standard dbm functions */
+extern int dbminit();
+extern datum fetch();
+extern int store();
+extern int delete(); /* not in dbz */
+extern datum firstkey(); /* not in dbz */
+extern datum nextkey(); /* not in dbz */
+extern int dbmclose(); /* in dbz, but not in old dbm */
+
+/* new stuff for dbz */
+extern int dbzfresh();
+extern int dbzagain();
+extern datum dbzfetch();
+extern int dbzstore();
+extern int dbzsync();
+extern long dbzsize();
+extern int dbzincore();
+extern int dbzcancel();
+extern int dbzdebug();
+
+/*
+ * In principle we could handle unlimited-length keys by operating a chunk
+ * at a time, but it's not worth it in practice. Setting a nice large
+ * bound on them simplifies the code and doesn't hurt anything.
+ */
+#define DBZMAXKEY 255
diff --git a/gnu/dist/libio/dbz/dbzmain.c b/gnu/dist/libio/dbz/dbzmain.c
new file mode 100644
index 00000000000..7d20c7da4d7
--- /dev/null
+++ b/gnu/dist/libio/dbz/dbzmain.c
@@ -0,0 +1,519 @@
+/*
+ * dbz - use and test dbz in various ways
+ *
+ * -Log-
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <dbz.h>
+
+#ifdef FUNNYSEEKS
+#include <unistd.h>
+#else
+#define SEEK_SET 0
+#endif
+
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+#ifndef lint
+static char RCSid[] = "$Header: /cvsroot/src/gnu/dist/libio/dbz/Attic/dbzmain.c,v 1.1.1.1 1998/03/29 08:32:23 mrg Exp $";
+#endif
+
+char *progname;
+
+char *inname = "(no file)"; /* filename for messages etc. */
+long lineno; /* line number for messages etc. */
+
+char *my_basename;
+char *pagname;
+char *dir_name;
+char *str2dup();
+FILE *base;
+
+int op = 'b'; /* what to do, default build a new table */
+int baseinput = 1; /* is the base file also the input? */
+
+char *from = NULL; /* old table to use for dbzagain() */
+int omitzero = 0; /* omit lines tagged with 0 */
+long every = 0; /* report every n lines */
+int syncs = 0; /* dbzsync() on each report */
+int quick = 0; /* quick checking, not too thorough */
+int sweep = 0; /* sweep file checking all offsets */
+int useincore = 1; /* should we use incore facility? */
+long xxx = 0; /* debugging variable */
+int printx = 0; /* print xxx after all is done */
+int unique = 1; /* before store(), check with fetch() */
+int usefresh = 0; /* use dbzfresh? */
+long siz = 0; /* -p size */
+char map = 'C'; /* -p map */
+long tag = 0; /* -p tag mask */
+int exact = 0; /* do not run dbzsize(siz) */
+int dbzint = 1; /* use new interface? */
+char fs = '\t'; /* field separator, default tab */
+int unopen = 0; /* make base unopenable during dbminit? */
+char *change = NULL; /* chdir here before dbmclose */
+
+#define DEFBUF 1024 /* default line-buffer size */
+int buflen = DEFBUF; /* line length limit */
+char lbuf[DEFBUF];
+char *line = lbuf;
+char cbuf[DEFBUF];
+char *cmp = cbuf;
+
+void fail();
+void dofile();
+void runs();
+void dosweep();
+void mkfiles();
+void crfile();
+void doline();
+void process();
+
+#ifdef HAVERFCIZE
+extern char *rfc822ize();
+#else
+#define rfc822ize(n) (n)
+#endif
+
+extern char *malloc();
+
+/*
+ - main - parse arguments and handle options
+ */
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int c;
+ int errflg = 0;
+ extern int optind;
+ extern char *optarg;
+ int doruns = 0;
+ extern long atol();
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "axcmt:l:R0E:SqOiX:Yuf:p:eMUC:d")) != EOF)
+ switch (c) {
+ case 'a': /* append to existing table */
+ if (op != 'b')
+ fail("only one of -a -x -c -m can be given", "");
+ op = 'a';
+ baseinput = 0;
+ break;
+ case 'x': /* extract from existing table */
+ if (op != 'b')
+ fail("only one of -a -x -c -m can be given", "");
+ op = 'x';
+ baseinput = 0;
+ break;
+ case 'c': /* check existing table */
+ if (op != 'b')
+ fail("only one of -a -x -c -m can be given", "");
+ op = 'c';
+ break;
+ case 'm': /* extract missing (complement of -x) */
+ if (op != 'b')
+ fail("only one of -a -x -c -m can be given", "");
+ op = 'm';
+ baseinput = 0;
+ break;
+ case 't': /* set field separator */
+ if (strlen(optarg) > 1)
+ fail("only one field separator allowed", "");
+ fs = *optarg;
+ break;
+ case 'l': /* override line-length limit */
+ buflen = atoi(optarg) + 1;
+ if (buflen <= 2)
+ fail("bad -l value `%s'", optarg);
+ line = malloc(buflen);
+ cmp = malloc(buflen);
+ if (line == NULL || cmp == NULL)
+ fail("cannot allocate %s-byte buffers", optarg);
+ break;
+ case 'R': /* print run statistics */
+ doruns = 1;
+ break;
+ case '0': /* omit lines tagged (by fake -t) with 0 */
+ omitzero = 1;
+ break;
+ case 'E': /* report every n items */
+ every = atol(optarg);
+ break;
+ case 'S': /* dbzsync() on each -E report */
+ syncs = 1;
+ break;
+ case 'q': /* quick check or extract */
+ quick = 1;
+ break;
+ case 'O': /* sweep file checking all offsets */
+ sweep = 1;
+ break;
+ case 'i': /* don't use incore */
+ useincore = 0;
+ break;
+ case 'X': /* set xxx */
+ xxx = atoi(optarg);
+ break;
+ case 'Y': /* print xxx afterward */
+ printx = 1;
+ break;
+ case 'u': /* don't check uniqueness */
+ unique = 0;
+ break;
+ case 'f': /* init from existing table's parameters */
+ from = optarg;
+ break;
+ case 'p': /* parameters for dbzfresh */
+ if (sscanf(optarg, "%ld %1s %lx", &siz, &map, &tag) != 3) {
+ map = '?';
+ tag = 0;
+ if (sscanf(optarg, "%ld", &siz) != 1)
+ fail("bad -n value `%s'", optarg);
+ }
+ usefresh = 1;
+ break;
+ case 'e': /* -p size is exact, don't dbzsize() it */
+ exact = 1;
+ break;
+ case 'M': /* use old dbm interface + rfc822ize */
+ dbzint = 0;
+ break;
+ case 'U': /* make base unopenable during init */
+ unopen = 1;
+ break;
+ case 'C': /* change directories before dbmclose */
+ change = optarg;
+ break;
+ case 'd': /* Debugging. */
+ if (dbzdebug(1) < 0)
+ fail("dbz debugging not available", "");
+ break;
+ case '?':
+ default:
+ errflg++;
+ break;
+ }
+ if (errflg || optind >= argc || (optind+1 < argc && baseinput)) {
+ fprintf(stderr, "usage: %s ", progname);
+ fprintf(stderr, "[-a] [-x] [-c] database [file] ...\n");
+ exit(2);
+ }
+
+ (void) dbzincore(useincore);
+ my_basename = argv[optind];
+ pagname = str2dup(my_basename, ".pag");
+ dir_name = str2dup(my_basename, ".dir");
+ mkfiles();
+ optind++;
+
+ if (baseinput) /* implies no further arguments */
+ process(base, my_basename);
+ else if (optind >= argc)
+ process(stdin, "stdin");
+ else
+ for (; optind < argc; optind++)
+ dofile(argv[optind]);
+
+ if (change != NULL)
+ (void) chdir(change);
+ if (dbmclose() < 0)
+ fail("dbmclose failed", "");
+ if (doruns)
+ runs(pagname);
+ if (sweep)
+ dosweep(my_basename, pagname);
+ if (printx)
+ printf("%ld\n", xxx);
+#ifdef DBZ_FINISH
+ DBZ_FINISH;
+#endif
+ exit(0);
+}
+
+/*
+ - dofile - open a file and invoke process()
+ */
+void
+dofile(name)
+char *name;
+{
+ register FILE *in;
+
+ if (STREQ(name, "-"))
+ process(stdin, "-");
+ else {
+ in = fopen(name, "r");
+ if (in == NULL)
+ fail("cannot open `%s'", name);
+ process(in, name);
+ (void) fclose(in);
+ }
+}
+
+/*
+ - mkfiles - create empty files and open them up
+ */
+void
+mkfiles()
+{
+ if (op == 'b' && !dbzint) {
+ crfile(dir_name);
+ crfile(pagname);
+ }
+
+ base = fopen(my_basename, (op == 'a') ? "a" : "r");
+ if (base == NULL)
+ fail("cannot open `%s'", my_basename);
+ if (unopen)
+ (void) chmod(my_basename, 0);
+ if (from != NULL) {
+ if (dbzagain(my_basename, from) < 0)
+ fail("dbzagain(`%s'...) failed", my_basename);
+ } else if (op == 'b' && dbzint) {
+ if (!exact)
+ siz = dbzsize(siz);
+ if (dbzfresh(my_basename, siz, (int)fs, map, (off_t)tag) < 0)
+ fail("dbzfresh(`%s'...) failed", my_basename);
+ } else if (dbminit(my_basename) < 0)
+ fail("dbminit(`%s') failed", my_basename);
+ if (unopen)
+ (void) chmod(my_basename, 0600); /* hard to restore original */
+}
+
+/*
+ - crfile - create a file
+ */
+void
+crfile(name)
+char *name;
+{
+ register int f;
+
+ f = creat(name, 0666);
+ if (f < 0)
+ fail("cannot create `%s'", name);
+ (void) close(f);
+}
+
+/*
+ - process - process input file
+ */
+void
+process(in, name)
+FILE *in;
+char *name;
+{
+ register off_t place;
+
+ inname = name;
+ lineno = 0;
+
+ for (;;) {
+ place = ftell(in);
+ if (fgets(line, buflen, in) == NULL)
+ return;
+ lineno++;
+ if (every > 0 && lineno%every == 0) {
+ fprintf(stderr, "%ld\n", lineno);
+ if (dbzsync() < 0)
+ fail("dbzsync failed", "");
+ }
+ doline(line, place);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ - doline - process input line
+ */
+void
+doline(lp, inoffset)
+char *lp;
+off_t inoffset;
+{
+ register char *p;
+ register char pc;
+ datum key, value;
+ off_t place = inoffset;
+ register int shouldfind;
+ register int llen;
+ char keytext[DBZMAXKEY+1];
+
+ p = NULL;
+ if (fs != '\0')
+ p = strchr(lp, fs);
+ if (p == NULL)
+ p = lp + strlen(lp);
+ if (p > lp && *(p-1) == '\n')
+ p--;
+ if (p - lp > DBZMAXKEY)
+ fail("key of `%.40s...' too long", lp);
+ pc = *p;
+ *p = '\0';
+ (void) strcpy(keytext, lp);
+ *p = pc;
+ key.dptr = (dbzint) ? keytext : rfc822ize(keytext);
+ key.dsize = strlen(keytext)+1;
+
+ switch (op) {
+ case 'a':
+ place = ftell(base);
+ llen = strlen(lp);
+ if (fwrite(lp, 1, llen, base) != llen)
+ fail("write error in `%s'", my_basename);
+ /* FALLTHROUGH */
+ case 'b':
+ if (omitzero && p != NULL && *(p+1) == '0')
+ return;
+ if (unique) {
+ value = (dbzint) ? dbzfetch(key) : fetch(key);
+ if (value.dptr != NULL)
+ fail("`%.40s...' already present", lp);
+ }
+ value.dptr = (char *)&place;
+ value.dsize = (int)sizeof(off_t);
+ if (((dbzint) ? dbzstore(key, value) : store(key, value)) < 0)
+ fail("store failed on `%.40s...'", lp);
+ break;
+ case 'c':
+ value = (dbzint) ? dbzfetch(key) : fetch(key);
+ shouldfind = (omitzero && p != NULL && *(p+1) == '0') ? 0 : 1;
+ if (!shouldfind && (value.dptr != NULL || value.dsize != 0))
+ fail("`%.40s...' found, shouldn't be", lp);
+ if (shouldfind && (value.dptr == NULL ||
+ value.dsize != sizeof(off_t)))
+ fail("can't find `%.40s...'", lp);
+ if (shouldfind && !quick) {
+ (void) memcpy((char *)&place, value.dptr, sizeof(off_t));
+ if (place != inoffset)
+ fail("offset mismatch on `%.40s...'", lp);
+ if (fseek(base, place, SEEK_SET) == -1)
+ fail("fseek failed on `%.40s...'", lp);
+ if (fgets(cmp, buflen, base) == NULL)
+ fail("can't read line for `%.40s...'", lp);
+ if (!STREQ(lp, cmp))
+ fail("compare failed on `%.40s...'", lp);
+ }
+ break;
+ case 'x':
+ value = (dbzint) ? dbzfetch(key) : fetch(key);
+ if (value.dptr != NULL && !quick) {
+ (void) memcpy((char *)&place, value.dptr, sizeof(off_t));
+ if (fseek(base, place, SEEK_SET) == -1)
+ fail("fseek failed on `%.40s...'", lp);
+ if (fgets(cmp, buflen, base) == NULL)
+ fail("can't read line for `%.40s...'", lp);
+ fputs(cmp, stdout);
+ } else if (value.dptr != NULL)
+ fputs(lp, stdout);
+ break;
+ case 'm':
+ value = (dbzint) ? dbzfetch(key) : fetch(key);
+ if (value.dptr == NULL) {
+ fputs(keytext, stdout);
+ putchar('\n');
+ }
+ break;
+ default:
+ fail("unknown operator -- can't happen", "");
+ break;
+ }
+}
+
+/*
+ - runs - print run statistics
+ */
+void
+runs(file)
+char *file;
+{
+ register FILE *fd;
+ off_t it;
+ register long run;
+
+ fd = fopen(file, "r");
+ if (fd == NULL)
+ fail("cannot reopen `%s'", file);
+ run = 0;
+ while (fread((char *)&it, sizeof(off_t), 1, fd) == 1) {
+ if (it != 0)
+ run++;
+ else if (run > 0) {
+ printf("%ld\n", run);
+ run = 0;
+ }
+ }
+ (void) fclose(fd);
+}
+
+/*
+ - dosweep - sweep pag file checking for valid offsets
+ */
+void
+dosweep(fn, pn)
+char *fn;
+char *pn;
+{
+ register FILE *pf;
+ off_t it;
+ char nl;
+ register FILE *hf;
+
+ hf = fopen(fn, "r");
+ if (hf == NULL)
+ fail("cannot reopen `%s'", fn);
+ pf = fopen(pn, "r");
+ if (pf == NULL)
+ fail("cannot reopen `%s'", pn);
+ while (fread((char *)&it, sizeof(off_t), 1, pf) == 1) {
+ it = (it & ((off_t)0x80000000)) ? (it&~((off_t)0xff000000)) : it;
+ if (it != 0 && it != 1) { /* 0 empty, 1 known okay */
+ it--; /* get rid of bias */
+ (void) fseek(hf, it-1, SEEK_SET);
+ nl = getc(hf);
+ if (nl != '\n')
+ fprintf(stderr, "offset 0%lo does not point to line\n",
+ (long)it);
+ }
+ }
+ (void) fclose(hf);
+ (void) fclose(pf);
+}
+
+/*
+ - fail - complain and die
+ */
+void
+fail(s1, s2)
+char *s1;
+char *s2;
+{
+ fprintf(stderr, "%s: (file `%s', line %ld) ", progname, inname, lineno);
+ fprintf(stderr, s1, s2);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/*
+ - str2dup - concatenate strings and malloc result
+ */
+char *
+str2dup(s1, s2)
+char *s1;
+char *s2;
+{
+ register char *p;
+
+ p = malloc((size_t)strlen(s1) + strlen(s2) + 1);
+ if (p == NULL)
+ fail("can't allocate space for strings", "");
+ (void) strcpy(p, s1);
+ (void) strcat(p, s2);
+ return(p);
+}
diff --git a/gnu/dist/libio/dbz/fake.c b/gnu/dist/libio/dbz/fake.c
new file mode 100644
index 00000000000..11946751d76
--- /dev/null
+++ b/gnu/dist/libio/dbz/fake.c
@@ -0,0 +1,144 @@
+/*
+ * fake - make up random lines resembling history-file entries, reproducibly
+ *
+ * -Log-
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define MAXSTR 500 /* For sizing strings -- DON'T use BUFSIZ! */
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+#ifndef lint
+static char RCSid[] = "$Header: /cvsroot/src/gnu/dist/libio/dbz/Attic/fake.c,v 1.1.1.1 1998/03/29 08:32:23 mrg Exp $";
+#endif
+
+int midonly = 0; /* just message ids, rest not realistic */
+int tag = 0; /* tag lines with random digit for later use */
+int expired = -1; /* percentage of lines to be expired */
+
+int debug = 0;
+char *progname;
+
+char *inname; /* filename for messages etc. */
+long lineno; /* line number for messages etc. */
+
+void doline();
+void addchars();
+void seed();
+
+/*
+ - main - parse arguments and handle options
+ */
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int c;
+ int errflg = 0;
+ FILE *in;
+ struct stat statbuf;
+ extern int optind;
+ extern char *optarg;
+ void process();
+ register long no;
+ extern long atol();
+ char line[MAXSTR];
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "ms:te:d")) != EOF)
+ switch (c) {
+ case 'm': /* message-ids only */
+ midonly = 1;
+ break;
+ case 's': /* seed */
+ seed(atol(optarg));
+ break;
+ case 't': /* tag lines with a random digit */
+ tag = 1;
+ break;
+ case 'e': /* percentage to be expired */
+ expired = atoi(optarg);
+ break;
+ case 'd': /* Debugging. */
+ debug++;
+ break;
+ case '?':
+ default:
+ errflg++;
+ break;
+ }
+ if (errflg || optind != argc - 1) {
+ fprintf(stderr, "usage: %s ", progname);
+ fprintf(stderr, "[-m] [-s seed] length\n");
+ exit(2);
+ }
+
+ for (no = atol(argv[optind]); no > 0; no--) {
+ doline(line);
+ puts(line);
+ }
+#ifdef DBZ_FINISH
+ DBZ_FINISH;
+#endif
+ exit(0);
+}
+
+/*
+ - doline - generate random history pseudo-line
+ */
+void
+doline(buf)
+char *buf;
+{
+ char tagch[2];
+
+ (void) strcpy(buf, "<");
+ addchars(buf, range(4, 20));
+ (void) strcat(buf, "@");
+ addchars(buf, range(8, 20));
+ if (midonly)
+ (void) strcat(buf, ">\tx");
+ else {
+ if (tag) {
+ tagch[0] = "1234567890"[range(0,9)];
+ tagch[1] = '\0';
+ (void) strcat(buf, ">\t");
+ (void) strcat(buf, tagch);
+ (void) strcat(buf, "00000000~-");
+ } else
+ (void) strcat(buf, ">\t1234567890~-");
+ }
+ if (range(1, 100) > expired) {
+ if (midonly)
+ (void) strcat(buf, "\tx");
+ else {
+ (void) strcat(buf, "\t");
+ addchars(buf, range(10, 30));
+ }
+ }
+}
+
+/*
+ - addchars - generate n random characters suitable for history file
+ */
+void
+addchars(buf, len)
+char *buf;
+int len;
+{
+ register int i;
+ register char *p = buf + strlen(buf);
+ static char vocab[] = "1234567890.abcde.fghij.klmno.pqrst.uvwxyz.\
+1234567890.ABCDE.FGHIJ.KLMNO.PQRST.UVWXYZ.1234567890.\
+1234567890.abcde.fghij.klmno.pqrst.uvwxyz.1234567890";
+
+ for (i = len; i > 0; i--)
+ *p++ = vocab[range(0, sizeof(vocab)-2)];
+ *p++ = '\0';
+}
diff --git a/gnu/dist/libio/dbz/firstlast25 b/gnu/dist/libio/dbz/firstlast25
new file mode 100644
index 00000000000..4850468c0c2
--- /dev/null
+++ b/gnu/dist/libio/dbz/firstlast25
@@ -0,0 +1,50 @@
+<m....VO1.9q.@s95e1zKsIj7LrIwa1> 600000000~- 90fz0706yo.1Env21x8b
+<H5.i.R6ZQ2@Vg6.5mqj8..z> 200000000~-
+<1Hy.ufmjqe371x5.o@HEEl0tAp4> 700000000~-
+<T6.c9.xM4i@943..7z.c..3h> 600000000~-
+<Exus7LsME4fPL9v8@2.ouu97O25z9cdft> 700000000~-
+<6kUzkf.v74@iC1iGj882RQ0zli> 400000000~-
+<J.7YT7dV.Kkul8Bh0fc@Rar.EnMx2lm0.6Yeob> 600000000~-
+<.wVJi1DX42@5.4i6.jaZ6qw9Ln1.> 500000000~-
+<uUd9e18vxzevae7uY@33a480208l0.4p2q> 300000000~-
+<43hQ.5shbE7@912400.ajES6x0sXl.M> 400000000~-
+<g25r..2r.0WOZ6k3@tb3.U9xrR.uw61a2y0> 600000000~-
+<923s5e67d5Oq085Y.1@6Pik68584> 900000000~-
+<.5.n5cx5aD62i9q8@Ai60Sc.4x> 200000000~-
+<9N9n@3.1ql87.yj2xFs.zLqI> 700000000~- Q2.kni8kZps7kF5uiEv32B38y4z.p
+<.X.fw.6LtoT.0@pp6bp.5s6yh74.> 400000000~-
+<54c1w@7..u1.99m9T4j.BNGBiK> 600000000~- .F3hb.OFh06V..p
+<j12Mtn6q9@m2.m1X1s> 500000000~-
+<o1WJV9G4H.zf0BX44w@W7.76xn33> 000000000~-
+<0C605s6plaAgfM.ap40@e6d66n.uv01W.j.8ph.> 100000000~- m.x7TY8.8DQ5
+<.2.14xdn.@D0g.W.uZ.75gyyg.q1G> 100000000~-
+<.A..03.@5v..64.5v3.3tbjUo.> 500000000~-
+<72..c19ms65.WCf0G3.@83seEG9nnhM.O.j22> 900000000~-
+<D..xX.kti9@u739li.xvy2> 000000000~- NPLL42XVfM
+<6HO.nFal1ufl3.8b@3.n0k7a.IDgNy> 700000000~- Wv4j3Itccnh0Zp3
+<x5RjUnIpd03xBBnuN@z0puc82Q26Ou.0T6> 400000000~- k67.hvXwv6X745R4rh2ybuFN3n.
+<62dIeg.fW92.ov375@x76mf5c6.37.v> 000000000~-
+<chdpqs.0mgZOp.@Dxl9v..94e7ar2> 900000000~-
+<.9Xr.7V91..oe5CG.hX@p5x3jos3s27R6O3yj1> 400000000~-
+<Mm6dr.231dH35ua@SE1u0za3V1M43lRn9> 100000000~-
+<JIhw2@.Qdf.8v28Tnf1M> 200000000~-
+<z4FCa.q4MF..EE0.2@W9U63e33h9w3lcFFl> 400000000~-
+<87.W3r6is4.@svVqQCBiNqz400A.qwj> 200000000~-
+<0liI7Lu0Mx435m7M99@87Xw.8j63.9.> 500000000~-
+<tRtht5M.6d0@06gj.qm3.s9> 200000000~- e27S.BKVD70P.o
+<Jpga8@m68yvw.b4b> 200000000~-
+<.2.69hy3JT1@Aq3.r83o.9> 700000000~-
+<.W7EurYppo4fhzs.I@8651m2W7v> 700000000~-
+<3m02.@22074.a5ct2j3> 900000000~-
+<.fy9Epa@.1.kNGCNokFwB8ezo1WM> 800000000~-
+<c758d64.FS4yY7L5@43sw.kI6> 900000000~-
+<vLd0.t@.kq70oHl96ixdnXd.GVv> 100000000~- 9A6Ejq5t55I4VJ6.q1
+<d3.4@n17p4N.77N7W..7.8> 300000000~-
+<f2lv064.8@4jokk3e07> 400000000~-
+<rr7hoxA.U7.JXxnpvd@1rbMO437vHnakx> 000000000~-
+<.0p3G7novlrYz9kjI@Sx.2w.yqzerZl12781.k> 700000000~-
+<51ny.pQ7ay4@nfU2l1f0ixG09584.m> 000000000~- 38K5bhK7cr6.bg.5MlC2Fxq06Ziuw.
+<2.cau.9s@.n4Pk0Jd9g> 300000000~-
+<bEH1Bwa.662i@zm.3g.gx4.lp3> 300000000~- c8.t4Q0.8t0.m50
+<.t13789u5AqM4m3.z0T@P17e.ypf> 200000000~- q17z.fZ3.FyD533WthqZs8q7
+<M4r1I@Ovaev.dp> 100000000~-
diff --git a/gnu/dist/libio/dbz/getmap b/gnu/dist/libio/dbz/getmap
new file mode 100644
index 00000000000..fd746cad7d9
--- /dev/null
+++ b/gnu/dist/libio/dbz/getmap
@@ -0,0 +1,6 @@
+#!/bin/sh
+awk 'NR == 1 {
+ for (i = 9; i <= NF; i++)
+ printf "%s ", $i
+ printf "\n"
+}' $*
diff --git a/gnu/dist/libio/dbz/random.c b/gnu/dist/libio/dbz/random.c
new file mode 100644
index 00000000000..1d8de3a2b44
--- /dev/null
+++ b/gnu/dist/libio/dbz/random.c
@@ -0,0 +1,31 @@
+/*
+ * random-number generator for testing
+ */
+static unsigned long next = 1;
+
+/*
+ - range - generate a random number within an inclusive range
+ *
+ * Algorithm from ANSI C standard. Limitation: max-min <= 32767.
+ */
+int
+range(min, max)
+int min;
+int max;
+{
+ register int temp;
+
+ next = next * 1103515245 + 12345;
+ temp = (int)((next/65536)%32768);
+ return(temp%(max - min + 1) + min);
+}
+
+/*
+ - seed - seed random number generator
+ */
+void
+seed(n)
+long n;
+{
+ next = (unsigned long)n;
+}
diff --git a/gnu/dist/libio/dbz/revbytes b/gnu/dist/libio/dbz/revbytes
new file mode 100644
index 00000000000..b3d80c2685f
--- /dev/null
+++ b/gnu/dist/libio/dbz/revbytes
@@ -0,0 +1,7 @@
+NR == 1 {
+ printf "%s %s %s %s %s %s %s %s %s", $1, $2, $3, $4, $5, $6, $7, $8, $9
+ for (i = NF; i > 9; i--)
+ printf " %s", $i
+ printf "\n"
+}
+NR > 1 { print }
diff --git a/gnu/dist/libio/dbz/stdio.h b/gnu/dist/libio/dbz/stdio.h
new file mode 100644
index 00000000000..80faee30ad9
--- /dev/null
+++ b/gnu/dist/libio/dbz/stdio.h
@@ -0,0 +1 @@
+#include "../iostdio.h"
diff --git a/gnu/dist/libio/depend b/gnu/dist/libio/depend
new file mode 100644
index 00000000000..b7335fdb1ab
--- /dev/null
+++ b/gnu/dist/libio/depend
@@ -0,0 +1,352 @@
+# AUTOMATICALLY GENERATED BY 'make depend' - DO NOT EDIT
+
+PlotFile.o: PlotFile.cc \
+ $(srcdir)/PlotFile.h \
+ $(srcdir)/fstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+SFile.o: SFile.cc \
+ $(srcdir)/SFile.h \
+ $(srcdir)/fstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+builtinbuf.o: builtinbuf.cc \
+ $(srcdir)/builtinbuf.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/iostreamP.h \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h
+editbuf.o: editbuf.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/editbuf.h \
+ $(srcdir)/fstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h
+filebuf.o: filebuf.cc \
+ $(srcdir)/iostreamP.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/builtinbuf.h
+fstream.o: fstream.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/fstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h
+indstream.o: indstream.cc \
+ $(srcdir)/indstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioassign.o: ioassign.cc \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h
+ioextend.o: ioextend.cc \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iomanip.o: iomanip.cc \
+ $(srcdir)/iomanip.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iostream.o: iostream.cc \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/floatio.h
+isgetline.o: isgetline.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h
+isgetsb.o: isgetsb.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h
+isscan.o: isscan.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h
+osform.o: osform.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h
+parsestream.o: parsestream.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/parsestream.h \
+ $(srcdir)/streambuf.h
+pfstream.o: pfstream.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/pfstream.h \
+ $(srcdir)/fstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/procbuf.h
+procbuf.o: procbuf.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/procbuf.h \
+ $(srcdir)/streambuf.h
+sbform.o: sbform.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/streambuf.h
+sbgetline.o: sbgetline.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/streambuf.h
+sbscan.o: sbscan.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/streambuf.h
+stdiostream.o: stdiostream.cc \
+ $(srcdir)/stdiostream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h
+stdstrbufs.o: stdstrbufs.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+stdstreams.o: stdstreams.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/iostream.h
+stream.o: stream.cc \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/stream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/strstream.h \
+ $(srcdir)/strfile.h
+streambuf.o: streambuf.cc \
+ $(srcdir)/iostreamP.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h
+strstream.o: strstream.cc \
+ $(srcdir)/iostreamP.h \
+ $(srcdir)/streambuf.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/strstream.h \
+ $(srcdir)/iostream.h \
+ $(srcdir)/strfile.h
+cleanup.o: cleanup.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+filedoalloc.o: filedoalloc.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+fileops.o: fileops.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+floatconv.o: floatconv.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+genops.o: genops.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofclose.o: iofclose.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofdopen.o: iofdopen.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofflush.o: iofflush.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofgetpos.o: iofgetpos.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofgets.o: iofgets.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofopen.o: iofopen.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofprintf.o: iofprintf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofputs.o: iofputs.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofread.o: iofread.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofscanf.o: iofscanf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofsetpos.o: iofsetpos.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioftell.o: ioftell.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iofwrite.o: iofwrite.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iogetdelim.o: iogetdelim.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iogetline.o: iogetline.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iogets.o: iogets.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioignore.o: ioignore.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iopadn.o: iopadn.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioperror.o: ioperror.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iopopen.o: iopopen.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioprims.o: ioprims.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioprintf.o: ioprintf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioputs.o: ioputs.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioscanf.o: ioscanf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioseekoff.o: ioseekoff.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioseekpos.o: ioseekpos.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iosetbuffer.o: iosetbuffer.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iosetvbuf.o: iosetvbuf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iosprintf.o: iosprintf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iosscanf.o: iosscanf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iostrerror.o: iostrerror.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+ioungetc.o: ioungetc.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+iovfprintf.o: iovfprintf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/floatio.h
+iovfscanf.o: iovfscanf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/floatio.h
+iovsprintf.o: iovsprintf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/strfile.h
+iovsscanf.o: iovsscanf.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/strfile.h
+outfloat.o: outfloat.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+stdfiles.o: stdfiles.c \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H)
+strops.o: strops.c \
+ $(srcdir)/strfile.h \
+ $(srcdir)/libio.h $(_G_CONFIG_H) \
+ $(srcdir)/libioP.h \
+ $(srcdir)/iolibio.h
diff --git a/gnu/dist/libio/editbuf.cc b/gnu/dist/libio/editbuf.cc
new file mode 100644
index 00000000000..22304820f8f
--- /dev/null
+++ b/gnu/dist/libio/editbuf.cc
@@ -0,0 +1,717 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "libioP.h"
+#include "editbuf.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+/* NOTE: Some of the code here is taken from GNU emacs */
+/* Hence this file falls under the GNU License! */
+
+// Invariants for edit_streambuf:
+// An edit_streambuf is associated with a specific edit_string,
+// which again is a sub-string of a specific edit_buffer.
+// An edit_streambuf is always in either get mode or put mode, never both.
+// In get mode, gptr() is the current position,
+// and pbase(), pptr(), and epptr() are all NULL.
+// In put mode, pptr() is the current position,
+// and eback(), gptr(), and egptr() are all NULL.
+// Any edit_streambuf that is actively doing insertion (as opposed to
+// replacing) // must have its pptr() pointing to the start of the gap.
+// Only one edit_streambuf can be actively inserting into a specific
+// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf.
+// That edit_streambuf "owns" the gap, and the actual start of the
+// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer
+// will only be updated on an edit_streambuf::overflow().
+
+int edit_streambuf::truncate()
+{
+ str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()),
+ str->buffer->tell(str->end));
+ return 0;
+}
+
+#ifdef OLD_STDIO
+inline void disconnect_gap_from_file(edit_buffer* buffer, FILE* fp)
+{
+ if (buffer->gap_start_ptr != &fp->__bufp)
+ return;
+ buffer->gap_start_normal = fp->__bufp;
+ buffer->gap_start_ptr = &buffer->gap_start_normal;
+}
+#endif
+
+void edit_streambuf::flush_to_buffer(edit_buffer* buffer)
+{
+ if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end())
+ buffer->_gap_start = pptr();
+}
+
+void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer)
+{
+ if (buffer->_writer != this) return;
+ flush_to_buffer(buffer);
+ setp(pptr(),pptr());
+ buffer->_writer = NULL;
+}
+
+buf_index edit_buffer::tell(buf_char *ptr)
+{
+ if (ptr <= gap_start())
+ return ptr - data;
+ else
+ return ptr - gap_end() + size1();
+}
+
+#if 0
+buf_index buf_cookie::tell()
+{
+ return str->buffer->tell(file->__bufp);
+}
+#endif
+
+buf_index edit_buffer::tell(edit_mark*mark)
+{
+ return tell(data + mark->index_in_buffer(this));
+}
+
+// adjust the position of the gap
+
+void edit_buffer::move_gap(buf_offset pos)
+{
+ if (pos < size1())
+ gap_left (pos);
+ else if (pos > size1())
+ gap_right (pos);
+}
+
+void edit_buffer::gap_left (int pos)
+{
+ register buf_char *to, *from;
+ register int i;
+ int new_s1;
+
+ i = size1();
+ from = gap_start();
+ to = from + gap_size();
+ new_s1 = size1();
+
+ /* Now copy the characters. To move the gap down,
+ copy characters up. */
+
+ for (;;)
+ {
+ /* I gets number of characters left to copy. */
+ i = new_s1 - pos;
+ if (i == 0)
+ break;
+#if 0
+ /* If a quit is requested, stop copying now.
+ Change POS to be where we have actually moved the gap to. */
+ if (QUITP)
+ {
+ pos = new_s1;
+ break;
+ }
+#endif
+ /* Move at most 32000 chars before checking again for a quit. */
+ if (i > 32000)
+ i = 32000;
+ new_s1 -= i;
+ while (--i >= 0)
+ *--to = *--from;
+ }
+
+ /* Adjust markers, and buffer data structure, to put the gap at POS.
+ POS is where the loop above stopped, which may be what was specified
+ or may be where a quit was detected. */
+ adjust_markers (pos << 1, size1() << 1, gap_size(), data);
+#ifndef OLD_STDIO
+ _gap_start = data + pos;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + pos;
+#endif
+ __gap_end_pos = to - data;
+/* QUIT;*/
+}
+
+void edit_buffer::gap_right (int pos)
+{
+ register buf_char *to, *from;
+ register int i;
+ int new_s1;
+
+ i = size1();
+ to = gap_start();
+ from = i + gap_end();
+ new_s1 = i;
+
+ /* Now copy the characters. To move the gap up,
+ copy characters down. */
+
+ while (1)
+ {
+ /* I gets number of characters left to copy. */
+ i = pos - new_s1;
+ if (i == 0)
+ break;
+#if 0
+ /* If a quit is requested, stop copying now.
+ Change POS to be where we have actually moved the gap to. */
+ if (QUITP)
+ {
+ pos = new_s1;
+ break;
+ }
+#endif
+ /* Move at most 32000 chars before checking again for a quit. */
+ if (i > 32000)
+ i = 32000;
+ new_s1 += i;
+ while (--i >= 0)
+ *to++ = *from++;
+ }
+
+ adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1,
+ - gap_size(), data);
+#ifndef OLD_STDIO
+ _gap_start = data+pos;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + pos;
+#endif
+ __gap_end_pos = from - data;
+/* QUIT;*/
+}
+
+/* make sure that the gap in the current buffer is at least k
+ characters wide */
+
+void edit_buffer::make_gap(buf_offset k)
+{
+ register buf_char *p1, *p2, *lim;
+ buf_char *old_data = data;
+ int s1 = size1();
+
+ if (gap_size() >= k)
+ return;
+
+ /* Get more than just enough */
+ if (buf_size > 1000) k += 2000;
+ else k += /*200;*/ 20; // for testing!
+
+ p1 = (buf_char *) realloc (data, s1 + size2() + k);
+ if (p1 == 0)
+ abort(); /*memory_full ();*/
+
+ k -= gap_size(); /* Amount of increase. */
+
+ /* Record new location of text */
+ data = p1;
+
+ /* Transfer the new free space from the end to the gap
+ by shifting the second segment upward */
+ p2 = data + buf_size;
+ p1 = p2 + k;
+ lim = p2 - size2();
+ while (lim < p2)
+ *--p1 = *--p2;
+
+ /* Finish updating text location data */
+ __gap_end_pos += k;
+
+#ifndef OLD_STDIO
+ _gap_start = data + s1;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + s1;
+#endif
+
+ /* adjust markers */
+ adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data);
+ buf_size += k;
+}
+
+/* Add `amount' to the position of every marker in the current buffer
+ whose current position is between `from' (exclusive) and `to' (inclusive).
+ Also, any markers past the outside of that interval, in the direction
+ of adjustment, are first moved back to the near end of the interval
+ and then adjusted by `amount'. */
+
+void edit_buffer::adjust_markers(register mark_pointer low,
+ register mark_pointer high,
+ int amount, buf_char *old_data)
+{
+ register struct edit_mark *m;
+ register mark_pointer mpos;
+ /* convert to mark_pointer */
+ amount <<= 1;
+
+ if (_writer)
+ _writer->disconnect_gap_from_file(this);
+
+ for (m = mark_list(); m != NULL; m = m->chain)
+ {
+ mpos = m->_pos;
+ if (amount > 0)
+ {
+ if (mpos > high && mpos < high + amount)
+ mpos = high + amount;
+ }
+ else
+ {
+ if (mpos > low + amount && mpos <= low)
+ mpos = low + amount;
+ }
+ if (mpos > low && mpos <= high)
+ mpos += amount;
+ m->_pos = mpos;
+ }
+
+ // Now adjust files
+ edit_streambuf *file;
+
+ for (file = files; file != NULL; file = file->next) {
+ mpos = file->current() - old_data;
+ if (amount > 0)
+ {
+ if (mpos > high && mpos < high + amount)
+ mpos = high + amount;
+ }
+ else
+ {
+ if (mpos > low + amount && mpos <= low)
+ mpos = low + amount;
+ }
+ if (mpos > low && mpos <= high)
+ mpos += amount;
+ char* new_pos = data + mpos;
+ file->set_current(new_pos, file->is_reading());
+ }
+}
+
+#if 0
+stdio_
+ __off == index at start of buffer (need only be valid after seek ? )
+ __buf ==
+
+if read/read_delete/overwrite mode:
+ __endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer))
+
+if inserting:
+ must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp
+ file->edit_string->end->ptr(buffer) == *gap_start_ptr+end
+if write_mode:
+ if before gap
+#endif
+
+int edit_streambuf::underflow()
+{
+ if (!(_mode & ios::in))
+ return EOF;
+ struct edit_buffer *buffer = str->buffer;
+ if (!is_reading()) { // Must switch from put to get mode.
+ disconnect_gap_from_file(buffer);
+ set_current(pptr(), 1);
+ }
+ buf_char *str_end = str->end->ptr(buffer);
+ retry:
+ if (gptr() < egptr()) {
+ return *gptr();
+ }
+ if ((buf_char*)gptr() == str_end)
+ return EOF;
+ if (str_end <= buffer->gap_start()) {
+ setg(eback(), gptr(), str_end);
+ goto retry;
+ }
+ if (gptr() < buffer->gap_start()) {
+ setg(eback(), gptr(), buffer->gap_start());
+ goto retry;
+ }
+ if (gptr() == buffer->gap_start()) {
+ disconnect_gap_from_file(buffer);
+// fp->__offset += fp->__bufp - fp->__buffer;
+ setg(buffer->gap_end(), buffer->gap_end(), str_end);
+ }
+ else
+ setg(eback(), gptr(), str_end);
+ goto retry;
+}
+
+int edit_streambuf::overflow(int ch)
+{
+ if (_mode == ios::in)
+ return EOF;
+ struct edit_buffer *buffer = str->buffer;
+ flush_to_buffer(buffer);
+ if (ch == EOF)
+ return 0;
+ if (is_reading()) { // Must switch from get to put mode.
+ set_current(gptr(), 0);
+ }
+ buf_char *str_end = str->end->ptr(buffer);
+ retry:
+ if (pptr() < epptr()) {
+ *pptr() = ch;
+ pbump(1);
+ return (unsigned char)ch;
+ }
+ if ((buf_char*)pptr() == str_end || inserting()) {
+ /* insert instead */
+ if (buffer->_writer)
+ buffer->_writer->flush_to_buffer(); // Redundant?
+ buffer->_writer = NULL;
+ if (pptr() >= buffer->gap_end())
+ buffer->move_gap(pptr() - buffer->gap_size());
+ else
+ buffer->move_gap(pptr());
+ buffer->make_gap(1);
+ setp(buffer->gap_start(), buffer->gap_end());
+ buffer->_writer = this;
+ *pptr() = ch;
+ pbump(1);
+ return (unsigned char)ch;
+ }
+ if (str_end <= buffer->gap_start()) {
+ // Entire string is left of gap.
+ setp(pptr(), str_end);
+ }
+ else if (pptr() < buffer->gap_start()) {
+ // Current pos is left of gap.
+ setp(pptr(), buffer->gap_start());
+ goto retry;
+ }
+ else if (pptr() == buffer->gap_start()) {
+ // Current pos is at start of gap; move to end of gap.
+// disconnect_gap_from_file(buffer);
+ setp(buffer->gap_end(), str_end);
+// __offset += __bufp - __buffer;
+ }
+ else {
+ // Otherwise, current pos is right of gap.
+ setp(pptr(), str_end);
+ }
+ goto retry;
+}
+
+void edit_streambuf::set_current(char *new_pos, int reading)
+{
+ if (reading) {
+ setg(new_pos, new_pos, new_pos);
+ setp(NULL, NULL);
+ }
+ else {
+ setg(NULL, NULL, NULL);
+ setp(new_pos, new_pos);
+ }
+}
+
+// Called by fseek(fp, pos, whence) if fp is bound to a edit_buffer.
+
+streampos edit_streambuf::seekoff(streamoff offset, _seek_dir dir,
+ int /* =ios::in|ios::out*/)
+{
+ struct edit_buffer *buffer = str->buffer;
+ disconnect_gap_from_file(buffer);
+ buf_index cur_pos = buffer->tell((buf_char*)current());;
+ buf_index start_pos = buffer->tell(str->start);
+ buf_index end_pos = buffer->tell(str->end);
+ switch (dir) {
+ case ios::beg:
+ offset += start_pos;
+ break;
+ case ios::cur:
+ offset += cur_pos;
+ break;
+ case ios::end:
+ offset += end_pos;
+ break;
+ }
+ if (offset < start_pos || offset > end_pos)
+ return EOF;
+ buf_char *new_pos = buffer->data + offset;
+ buf_char* gap_start = buffer->gap_start();
+ if (new_pos > gap_start) {
+ buf_char* gap_end = buffer->gap_end();
+ new_pos += gap_end - gap_start;
+ if (new_pos >= buffer->data + buffer->buf_size) abort(); // Paranoia.
+ }
+ set_current(new_pos, is_reading());
+ return EOF;
+}
+
+#if 0
+int buf_seek(void *arg_cookie, fpos_t * pos, int whence)
+{
+ struct buf_cookie *cookie = arg_cookie;
+ FILE *file = cookie->file;
+ struct edit_buffer *buffer = cookie->str->buffer;
+ buf_char *str_start = cookie->str->start->ptr(buffer);
+ disconnect_gap_from_file(buffer, cookie->file);
+ fpos_t cur_pos, new_pos;
+ if (file->__bufp <= *buffer->gap_start_ptr
+ || str_start >= buffer->__gap_end)
+ cur_pos = str_start - file->__bufp;
+ else
+ cur_pos =
+ (*buffer->gap_start_ptr - str_start) + (file->__bufp - __gap_end);
+ end_pos = ...;
+ switch (whence) {
+ case SEEK_SET:
+ new_pos = *pos;
+ break;
+ case SEEK_CUR:
+ new_pos = cur_pos + *pos;
+ break;
+ case SEEK_END:
+ new_pos = end_pos + *pos;
+ break;
+ }
+ if (new_pos > end_pos) {
+ seek to end_pos;
+ insert_nulls(new_pos - end_pos);
+ return;
+ }
+ if (str_start + new_pos <= *gap_start_ptr &* *gap_start_ptr < end) {
+ __buffer = str_start;
+ __off = 0;
+ __bufp = str_start + new_pos;
+ file->__get_limit =
+ *buffer->gap_start_ptr; /* what if gap_start_ptr == &bufp ??? */
+ } else if () {
+
+ }
+ *pos = new_pos;
+}
+#endif
+
+/* Delete characters from `from' up to (but not incl) `to' */
+
+void edit_buffer::delete_range (buf_index from, buf_index to)
+{
+ register int numdel;
+
+ if ((numdel = to - from) <= 0)
+ return;
+
+ /* Make sure the gap is somewhere in or next to what we are deleting */
+ if (from > size1())
+ gap_right (from);
+ if (to < size1())
+ gap_left (to);
+
+ /* Relocate all markers pointing into the new, larger gap
+ to point at the end of the text before the gap. */
+ adjust_markers ((to + gap_size()) << 1, (to + gap_size()) << 1,
+ - numdel - gap_size(), data);
+
+ __gap_end_pos = to + gap_size();
+ _gap_start = data + from;
+}
+
+void edit_buffer::delete_range(struct edit_mark *start, struct edit_mark *end)
+{
+ delete_range(tell(start), tell(end));
+}
+
+void buf_delete_chars(struct edit_buffer *, struct edit_mark *, size_t)
+{
+ abort();
+}
+
+edit_streambuf::edit_streambuf(edit_string* bstr, int mode)
+{
+ _mode = mode;
+ str = bstr;
+ edit_buffer* buffer = bstr->buffer;
+ next = buffer->files;
+ buffer->files = this;
+ char* buf_ptr = bstr->start->ptr(buffer);
+ _inserting = 0;
+// setb(buf_ptr, buf_ptr, 0);
+ set_current(buf_ptr, !(mode & ios::out+ios::trunc+ios::app));
+ if (_mode & ios::trunc)
+ truncate();
+ if (_mode & ios::ate)
+ seekoff(0, ios::end);
+}
+
+// Called by fclose(fp) if fp is bound to a edit_buffer.
+
+#if 0
+static int buf_close(void *arg)
+{
+ register struct buf_cookie *cookie = arg;
+ struct edit_buffer *buffer = cookie->str->buffer;
+ struct buf_cookie **ptr;
+ for (ptr = &buffer->files; *ptr != cookie; ptr = &(*ptr)->next) ;
+ *ptr = cookie->next;
+ disconnect_gap_from_file(buffer, cookie->file);
+ free (cookie);
+ return 0;
+}
+#endif
+
+edit_streambuf::~edit_streambuf()
+{
+ if (_mode == ios::out)
+ truncate();
+ // Unlink this from list of files associated with bstr->buffer.
+ edit_streambuf **ptr = &str->buffer->files;
+ for (; *ptr != this; ptr = &(*ptr)->next) { }
+ *ptr = next;
+
+ disconnect_gap_from_file(str->buffer);
+}
+
+edit_buffer::edit_buffer()
+{
+ buf_size = /*200;*/ 15; /* for testing! */
+ data = (buf_char*)malloc(buf_size);
+ files = NULL;
+#ifndef OLD_STDIO
+ _gap_start = data;
+ _writer = NULL;
+#else
+ gap_start_normal = data;
+ gap_start_ptr = &gap_start_normal;
+#endif
+ __gap_end_pos = buf_size;
+ start_mark.chain = &end_mark;
+ start_mark._pos = 0;
+ end_mark.chain = NULL;
+ end_mark._pos = 2 * buf_size + 1;
+}
+
+// Allocate a new mark, which is adjusted by 'delta' bytes from 'this'.
+// Restrict new mark to lie within 'str'.
+
+edit_mark::edit_mark(struct edit_string *str, long delta)
+{
+ struct edit_buffer *buf = str->buffer;
+ chain = buf->start_mark.chain;
+ buf->start_mark.chain = this;
+ mark_pointer size1 = buf->size1() << 1;
+ int gap_size = buf->gap_size() << 1;
+ delta <<= 1;
+
+ // check if new and old marks are opposite sides of gap
+ if (_pos <= size1 && _pos + delta > size1)
+ delta += gap_size;
+ else if (_pos >= size1 + gap_size && _pos + delta < size1 + gap_size)
+ delta -= gap_size;
+
+ _pos = _pos + delta;
+ if (_pos < str->start->_pos & ~1)
+ _pos = (str->start->_pos & ~ 1) + (_pos & 1);
+ else if (_pos >= str->end->_pos)
+ _pos = (str->end->_pos & ~ 1) + (_pos & 1);
+}
+
+// A (slow) way to find the buffer a mark belongs to.
+
+edit_buffer * edit_mark::buffer()
+{
+ struct edit_mark *mark;
+ for (mark = this; mark->chain != NULL; mark = mark->chain) ;
+ // Assume that the last mark on the chain is the end_mark.
+ return (edit_buffer *)((char*)mark - offsetof(edit_buffer, end_mark));
+}
+
+edit_mark::~edit_mark()
+{
+ // Must unlink mark from chain of owning buffer
+ struct edit_buffer *buf = buffer();
+ if (this == &buf->start_mark || this == &buf->end_mark) abort();
+ edit_mark **ptr;
+ for (ptr = &buf->start_mark.chain; *ptr != this; ptr = &(*ptr)->chain) ;
+ *ptr = this->chain;
+}
+
+int edit_string::length() const
+{
+ ptrdiff_t delta = end->ptr(buffer) - start->ptr(buffer);
+ if (end->ptr(buffer) <= buffer->gap_start() ||
+ start->ptr(buffer) >= buffer->gap_end())
+ return delta;
+ return delta - buffer->gap_size();
+}
+
+buf_char * edit_string::copy_bytes(int *lenp) const
+{
+ char *new_str;
+ int len1, len2;
+ buf_char *start1, *start2;
+ start1 = start->ptr(buffer);
+ if (end->ptr(buffer) <= buffer->gap_start()
+ || start->ptr(buffer) >= buffer->gap_end()) {
+ len1 = end->ptr(buffer) - start1;
+ len2 = 0;
+ start2 = NULL; // To avoid a warning from g++.
+ }
+ else {
+ len1 = buffer->gap_start() - start1;
+ start2 = buffer->gap_end();
+ len2 = end->ptr(buffer) - start2;
+ }
+ new_str = (char*)malloc(len1 + len2 + 1);
+ memcpy(new_str, start1, len1);
+ if (len2 > 0) memcpy(new_str + len1, start2, len2);
+ new_str[len1+len2] = '\0';
+ *lenp = len1+len2;
+ return new_str;
+}
+
+// Replace the buf_chars in 'this' with ones from 'src'.
+// Equivalent to deleting this, then inserting src, except tries
+// to leave marks in place: Marks whose offset from the start
+// of 'this' is less than 'src->length()' will still have the
+// same offset in 'this' when done.
+
+void edit_string::assign(struct edit_string *src)
+{
+ edit_streambuf dst_file(this, ios::out);
+ if (buffer == src->buffer /*&& ???*/) { /* overly conservative */
+ int src_len;
+ buf_char *new_str;
+ new_str = src->copy_bytes(&src_len);
+ dst_file.sputn(new_str, src_len);
+ free (new_str);
+ } else {
+ edit_streambuf src_file(src, ios::in);
+ for ( ; ; ) {
+ int ch = src_file.sbumpc();
+ if (ch == EOF) break;
+ dst_file.sputc(ch);
+ }
+ }
+}
diff --git a/gnu/dist/libio/editbuf.h b/gnu/dist/libio/editbuf.h
new file mode 100644
index 00000000000..d15758f257e
--- /dev/null
+++ b/gnu/dist/libio/editbuf.h
@@ -0,0 +1,185 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _EDITBUF_H
+#define _EDITBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <stdio.h>
+#include <fstream.h>
+
+extern "C++" {
+typedef unsigned long mark_pointer;
+// At some point, it might be nice to parameterize this code
+// in terms of buf_char.
+typedef /*unsigned*/ char buf_char;
+
+// Logical pos from start of buffer (does not count gap).
+typedef long buf_index;
+
+// Pos from start of buffer, possibly including gap_size.
+typedef long buf_offset;
+
+#if 0
+struct buf_cookie {
+ FILE *file;
+ struct edit_string *str;
+ struct buf_cookie *next;
+ buf_index tell();
+};
+#endif
+
+struct edit_buffer;
+struct edit_mark;
+
+// A edit_string is defined as the region between the 'start' and 'end' marks.
+// Normally (always?) 'start->insert_before()' should be false,
+// and 'end->insert_before()' should be true.
+
+struct edit_string {
+ struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to
+ struct edit_mark *start, *end;
+ int length() const; // count of buf_chars currently in string
+ edit_string(struct edit_buffer *b,
+ struct edit_mark *ms, struct edit_mark *me)
+ { buffer = b; start = ms; end = me; }
+/* Make a fresh, contiguous copy of the data in STR.
+ Assign length of STR to *LENP.
+ (Output has extra NUL at out[*LENP].) */
+ buf_char *copy_bytes(int *lenp) const;
+// FILE *open_file(char *mode);
+ void assign(struct edit_string *src); // copy bytes from src to this
+};
+
+struct edit_streambuf : public streambuf {
+ friend edit_buffer;
+ edit_string *str;
+ edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer.
+ short _mode;
+ edit_streambuf(edit_string* bstr, int mode);
+ ~edit_streambuf();
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ void flush_to_buffer();
+ void flush_to_buffer(edit_buffer* buffer);
+ int _inserting;
+ int inserting() { return _inserting; }
+ void inserting(int i) { _inserting = i; }
+// int delete_chars(int count, char* cut_buf); Not implemented.
+ int truncate();
+ int is_reading() { return gptr() != NULL; }
+ buf_char* current() { return is_reading() ? gptr() : pptr(); }
+ void set_current(char *p, int is_reading);
+ protected:
+ void disconnect_gap_from_file(edit_buffer* buffer);
+};
+
+// A 'edit_mark' indicates a position in a buffer.
+// It is "attached" the text (rather than the offset).
+// There are two kinds of mark, which have different behavior
+// when text is inserted at the mark:
+// If 'insert_before()' is true the mark will be adjusted to be
+// *after* the new text.
+
+struct edit_mark {
+ struct edit_mark *chain;
+ mark_pointer _pos;
+ inline int insert_before() { return _pos & 1; }
+ inline unsigned long index_in_buffer(struct edit_buffer *)
+ { return _pos >> 1; }
+ inline buf_char *ptr(struct edit_buffer *buf);
+ buf_index tell();
+ edit_mark() { }
+ edit_mark(struct edit_string *str, long delta);
+ edit_buffer *buffer();
+ ~edit_mark();
+};
+
+// A 'edit_buffer' consists of a sequence of buf_chars (the data),
+// a list of edit_marks pointing into the data, and a list of FILEs
+// also pointing into the data.
+// A 'edit_buffer' coerced to a edit_string is the string of
+// all the buf_chars in the buffer.
+
+// This implementation uses a conventional buffer gap (as in Emacs).
+// The gap start is defined by de-referencing a (buf_char**).
+// This is because sometimes a FILE is inserting into the buffer,
+// so rather than having each putc adjust the gap, we use indirection
+// to have the gap be defined as the write pointer of the FILE.
+// (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.)
+
+struct edit_buffer {
+ buf_char *data; /* == emacs buffer_text.p1+1 */
+ buf_char *_gap_start;
+ edit_streambuf* _writer; // If non-NULL, currently writing stream
+ inline buf_char *gap_start()
+ { return _writer ? _writer->pptr() : _gap_start; }
+ buf_offset __gap_end_pos; // size of part 1 + size of gap
+ /* int gap; implicit: buf_size - size1 - size2 */
+ int buf_size;
+ struct edit_streambuf *files;
+ struct edit_mark start_mark;
+ struct edit_mark end_mark;
+ edit_buffer();
+ inline buf_offset gap_end_pos() { return __gap_end_pos; }
+ inline struct edit_mark *start_marker() { return &start_mark; }
+ inline struct edit_mark *end_marker() { return &end_mark; }
+/* these should be protected, ultimately */
+ buf_index tell(edit_mark*);
+ buf_index tell(buf_char*);
+ inline buf_char *gap_end() { return data + gap_end_pos(); }
+ inline int gap_size() { return gap_end() - gap_start(); }
+ inline int size1() { return gap_start() - data; }
+ inline int size2() { return buf_size - gap_end_pos(); }
+ inline struct edit_mark * mark_list() { return &start_mark; }
+ void make_gap (buf_offset);
+ void move_gap (buf_offset pos);
+ void move_gap (buf_char *pos) { move_gap(pos - data); }
+ void gap_left (int pos);
+ void gap_right (int pos);
+ void adjust_markers(mark_pointer low, mark_pointer high,
+ int amount, buf_char *old_data);
+ void delete_range(buf_index from, buf_index to);
+ void delete_range(struct edit_mark *start, struct edit_mark *end);
+};
+
+extern buf_char * bstr_copy(struct edit_string *str, int *lenp);
+
+// Convert a edit_mark to a (buf_char*)
+
+inline buf_char *edit_mark::ptr(struct edit_buffer *buf)
+ { return buf->data + index_in_buffer(buf); }
+
+inline void edit_streambuf::flush_to_buffer()
+{
+ edit_buffer* buffer = str->buffer;
+ if (buffer->_writer == this) flush_to_buffer(buffer);
+}
+} // extern "C++"
+#endif /* !_EDITBUF_H*/
+
diff --git a/gnu/dist/libio/filebuf.cc b/gnu/dist/libio/filebuf.cc
new file mode 100644
index 00000000000..422d442736e
--- /dev/null
+++ b/gnu/dist/libio/filebuf.cc
@@ -0,0 +1,215 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#include "iostreamP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "builtinbuf.h"
+
+void filebuf::init()
+{
+ _IO_file_init(this);
+}
+
+filebuf::filebuf()
+{
+ _IO_file_init(this);
+}
+
+#if !_IO_UNIFIED_JUMPTABLES
+/* This is like "new filebuf()", but it uses the _IO_file_jump jumptable,
+ for eficiency. */
+
+filebuf* filebuf::__new()
+{
+ filebuf *fb = new filebuf;
+ _IO_JUMPS(fb) = &_IO_file_jumps;
+ fb->_vtable() = builtinbuf_vtable;
+ return fb;
+}
+#endif
+
+filebuf::filebuf(int fd)
+{
+ _IO_file_init(this);
+ _IO_file_attach(this, fd);
+}
+
+filebuf::filebuf(int fd, char* p, int len)
+{
+ _IO_file_init(this);
+ _IO_file_attach(this, fd);
+ setbuf(p, len);
+}
+
+filebuf::~filebuf()
+{
+ if (_IO_file_is_open(this))
+ {
+ _IO_do_flush (this);
+ if (!(xflags() & _IO_DELETE_DONT_CLOSE))
+ _IO_SYSCLOSE (this);
+ }
+}
+
+filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot)
+{
+ if (_IO_file_is_open (this))
+ return NULL;
+ int posix_mode;
+ int read_write;
+ if (mode & ios::app)
+ mode |= ios::out;
+ if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) {
+ posix_mode = O_RDWR;
+ read_write = 0;
+ }
+ else if (mode & ios::out)
+ posix_mode = O_WRONLY, read_write = _IO_NO_READS;
+ else if (mode & (int)ios::in)
+ posix_mode = O_RDONLY, read_write = _IO_NO_WRITES;
+ else
+ posix_mode = 0, read_write = _IO_NO_READS+_IO_NO_WRITES;
+ if (mode & ios::binary)
+ {
+ mode &= ~ios::binary;
+#ifdef O_BINARY
+ /* This is a (mis-)feature of DOS/Windows C libraries. */
+ posix_mode |= O_BINARY;
+#endif
+ }
+ if ((mode & (int)ios::trunc) || mode == (int)ios::out)
+ posix_mode |= O_TRUNC;
+ if (mode & ios::app)
+ posix_mode |= O_APPEND, read_write |= _IO_IS_APPENDING;
+ if (!(mode & (int)ios::nocreate) && mode != ios::in)
+ posix_mode |= O_CREAT;
+ if (mode & (int)ios::noreplace)
+ posix_mode |= O_EXCL;
+#if _G_HAVE_IO_FILE_OPEN
+ return (filebuf*)_IO_file_open (this, filename, posix_mode, prot,
+ read_write, 0);
+#else
+ int fd = ::open(filename, posix_mode, prot);
+ if (fd < 0)
+ return NULL;
+ _fileno = fd;
+ xsetflags(read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+ if (mode & (ios::ate|ios::app)) {
+ if (pubseekoff(0, ios::end) == EOF)
+ return NULL;
+ }
+ _IO_link_in(this);
+ return this;
+#endif
+}
+
+filebuf* filebuf::open(const char *filename, const char *mode)
+{
+#if _G_IO_IO_FILE_VERSION == 0x20001
+ return (filebuf*)_IO_file_fopen(this, filename, mode, 0);
+#else
+ return (filebuf*)_IO_file_fopen(this, filename, mode);
+#endif
+}
+
+filebuf* filebuf::attach(int fd)
+{
+ return (filebuf*)_IO_file_attach(this, fd);
+}
+
+streambuf* filebuf::setbuf(char* p, int len)
+{
+ return (streambuf*)_IO_file_setbuf (this, p, len);
+}
+
+int filebuf::doallocate() { return _IO_file_doallocate(this); }
+
+int filebuf::overflow(int c)
+{
+ return _IO_file_overflow(this, c);
+}
+
+int filebuf::underflow()
+{
+ return _IO_file_underflow(this);
+}
+
+int filebuf::sync()
+{
+ return _IO_file_sync(this);
+}
+
+streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
+{
+ return _IO_file_seekoff (this, offset, dir, mode);
+}
+
+filebuf* filebuf::close()
+{
+ return (_IO_file_close_it(this) ? (filebuf*)NULL : this);
+}
+
+streamsize filebuf::sys_read(char* buf, streamsize size)
+{
+ return _IO_file_read(this, buf, size);
+}
+
+streampos filebuf::sys_seek(streamoff offset, _seek_dir dir)
+{
+ return _IO_file_seek(this, offset, dir);
+}
+
+streamsize filebuf::sys_write(const char *buf, streamsize n)
+{
+ return _IO_file_write (this, buf, n);
+}
+
+int filebuf::sys_stat(void* st)
+{
+ return _IO_file_stat (this, st);
+}
+
+int filebuf::sys_close()
+{
+ return _IO_file_close (this);
+}
+
+streamsize filebuf::xsputn(const char *s, streamsize n)
+{
+ return _IO_file_xsputn(this, s, n);
+}
+
+streamsize filebuf::xsgetn(char *s, streamsize n)
+{
+ // FIXME: OPTIMIZE THIS (specifically, when unbuffered()).
+ return streambuf::xsgetn(s, n);
+}
+
+// Non-ANSI AT&T-ism: Default open protection.
+const int filebuf::openprot = 0644;
diff --git a/gnu/dist/libio/filedoalloc.c b/gnu/dist/libio/filedoalloc.c
new file mode 100644
index 00000000000..5c62280c14b
--- /dev/null
+++ b/gnu/dist/libio/filedoalloc.c
@@ -0,0 +1,110 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Modified for GNU iostream by Per Bothner 1991, 1992. */
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include "libioP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+#ifdef _LIBC
+# undef isatty
+# define isatty(Fd) __isatty (Fd)
+#endif
+
+/*
+ * Allocate a file buffer, or switch to unbuffered I/O.
+ * Per the ANSI C standard, ALL tty devices default to line buffered.
+ *
+ * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
+ * optimisation) right after the _fstat() that finds the buffer size.
+ */
+
+int
+_IO_file_doallocate (fp)
+ _IO_FILE *fp;
+{
+ _IO_size_t size;
+ int couldbetty;
+ char *p;
+ struct stat st;
+
+#if !defined(_LIBC) && !defined(__linux__)
+ /* If _IO_cleanup_registration_needed is non-zero, we should call the
+ function it points to. This is to make sure _IO_cleanup gets called
+ on exit. We call it from _IO_file_doallocate, since that is likely
+ to get called by any program that does buffered I/O. */
+ if (_IO_cleanup_registration_needed)
+ (*_IO_cleanup_registration_needed) ();
+#endif
+
+ if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0)
+ {
+ couldbetty = 0;
+ size = _IO_BUFSIZ;
+#if 0
+ /* do not try to optimise fseek() */
+ fp->_flags |= __SNPT;
+#endif
+ }
+ else
+ {
+ couldbetty = S_ISCHR (st.st_mode);
+#if _IO_HAVE_ST_BLKSIZE
+ size = st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize;
+#else
+ size = _IO_BUFSIZ;
+#endif
+ }
+ ALLOC_BUF (p, size, EOF);
+ _IO_setb (fp, p, p + size, 1);
+ if (couldbetty && isatty (fp->_fileno))
+ fp->_flags |= _IO_LINE_BUF;
+ return 1;
+}
diff --git a/gnu/dist/libio/fileops.c b/gnu/dist/libio/fileops.c
new file mode 100644
index 00000000000..cfa97313d0d
--- /dev/null
+++ b/gnu/dist/libio/fileops.c
@@ -0,0 +1,814 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+ Written by Per Bothner <bothner@cygnus.com>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include "libioP.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+
+#ifdef _LIBC
+# define open(Name, Flags, Prot) __open (Name, Flags, Prot)
+# define close(FD) __close (FD)
+# define fstat(FD, Statbuf) __fstat (FD, Statbuf)
+# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
+# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
+# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
+#endif
+
+/* An fstream can be in at most one of put mode, get mode, or putback mode.
+ Putback mode is a variant of get mode.
+
+ In a filebuf, there is only one current position, instead of two
+ separate get and put pointers. In get mode, the current position
+ is that of gptr(); in put mode that of pptr().
+
+ The position in the buffer that corresponds to the position
+ in external file system is normally _IO_read_end, except in putback
+ mode, when it is _IO_save_end.
+ If the field _fb._offset is >= 0, it gives the offset in
+ the file as a whole corresponding to eGptr(). (?)
+
+ PUT MODE:
+ If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
+ and _IO_read_base are equal to each other. These are usually equal
+ to _IO_buf_base, though not necessarily if we have switched from
+ get mode to put mode. (The reason is to maintain the invariant
+ that _IO_read_end corresponds to the external file position.)
+ _IO_write_base is non-NULL and usually equal to _IO_base_base.
+ We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
+ The un-flushed character are those between _IO_write_base and _IO_write_ptr.
+
+ GET MODE:
+ If a filebuf is in get or putback mode, eback() != egptr().
+ In get mode, the unread characters are between gptr() and egptr().
+ The OS file position corresponds to that of egptr().
+
+ PUTBACK MODE:
+ Putback mode is used to remember "excess" characters that have
+ been sputbackc'd in a separate putback buffer.
+ In putback mode, the get buffer points to the special putback buffer.
+ The unread characters are the characters between gptr() and egptr()
+ in the putback buffer, as well as the area between save_gptr()
+ and save_egptr(), which point into the original reserve buffer.
+ (The pointers save_gptr() and save_egptr() are the values
+ of gptr() and egptr() at the time putback mode was entered.)
+ The OS position corresponds to that of save_egptr().
+
+ LINE BUFFERED OUTPUT:
+ During line buffered output, _IO_write_base==base() && epptr()==base().
+ However, ptr() may be anywhere between base() and ebuf().
+ This forces a call to filebuf::overflow(int C) on every put.
+ If there is more space in the buffer, and C is not a '\n',
+ then C is inserted, and pptr() incremented.
+
+ UNBUFFERED STREAMS:
+ If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
+*/
+
+#define CLOSED_FILEBUF_FLAGS \
+ (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
+
+
+void
+_IO_file_init (fp)
+ _IO_FILE *fp;
+{
+ /* POSIX.1 allows another file handle to be used to change the position
+ of our file descriptor. Hence we actually don't know the actual
+ position before we do the first fseek (and until a following fflush). */
+ fp->_offset = _IO_pos_BAD;
+ fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
+
+ _IO_link_in(fp);
+ fp->_fileno = -1;
+}
+
+int
+_IO_file_close_it (fp)
+ _IO_FILE *fp;
+{
+ int write_status, close_status;
+ if (!_IO_file_is_open (fp))
+ return EOF;
+
+ write_status = _IO_do_flush (fp);
+
+ _IO_unsave_markers(fp);
+
+ close_status = _IO_SYSCLOSE (fp);
+
+ /* Free buffer. */
+ _IO_setb (fp, NULL, NULL, 0);
+ _IO_setg (fp, NULL, NULL, NULL);
+ _IO_setp (fp, NULL, NULL);
+
+ _IO_un_link (fp);
+ fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
+ fp->_fileno = EOF;
+ fp->_offset = _IO_pos_BAD;
+
+ return close_status ? close_status : write_status;
+}
+
+void
+_IO_file_finish (fp, dummy)
+ _IO_FILE *fp;
+ int dummy;
+{
+ if (_IO_file_is_open (fp))
+ {
+ _IO_do_flush (fp);
+ if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
+ _IO_SYSCLOSE (fp);
+ }
+ _IO_default_finish (fp, 0);
+}
+
+_IO_FILE *
+_IO_file_fopen (fp, filename, mode)
+ _IO_FILE *fp;
+ const char *filename;
+ const char *mode;
+{
+ int oflags = 0, omode;
+ int read_write, fdesc;
+ int oprot = 0666;
+ if (_IO_file_is_open (fp))
+ return 0;
+ switch (*mode++)
+ {
+ case 'r':
+ omode = O_RDONLY;
+ read_write = _IO_NO_WRITES;
+ break;
+ case 'w':
+ omode = O_WRONLY;
+ oflags = O_CREAT|O_TRUNC;
+ read_write = _IO_NO_READS;
+ break;
+ case 'a':
+ omode = O_WRONLY;
+ oflags = O_CREAT|O_APPEND;
+ read_write = _IO_NO_READS|_IO_IS_APPENDING;
+ break;
+ default:
+ __set_errno (EINVAL);
+ return NULL;
+ }
+ if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
+ {
+ omode = O_RDWR;
+ read_write &= _IO_IS_APPENDING;
+ }
+ fdesc = open (filename, omode|oflags, oprot);
+ if (fdesc < 0)
+ return NULL;
+ fp->_fileno = fdesc;
+ _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+ if (read_write & _IO_IS_APPENDING)
+ if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
+ == _IO_pos_BAD && errno != ESPIPE)
+ return NULL;
+ _IO_link_in (fp);
+ return fp;
+}
+
+_IO_FILE *
+_IO_file_attach (fp, fd)
+ _IO_FILE *fp;
+ int fd;
+{
+ if (_IO_file_is_open (fp))
+ return NULL;
+ fp->_fileno = fd;
+ fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
+ fp->_flags |= _IO_DELETE_DONT_CLOSE;
+ /* Get the current position of the file. */
+ /* We have to do that since that may be junk. */
+ fp->_offset = _IO_pos_BAD;
+ if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
+ == _IO_pos_BAD && errno != ESPIPE)
+ return NULL;
+ return fp;
+}
+
+_IO_FILE *
+_IO_file_setbuf (fp, p, len)
+ _IO_FILE *fp;
+ char *p;
+ _IO_ssize_t len;
+{
+ if (_IO_default_setbuf (fp, p, len) == NULL)
+ return NULL;
+
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+ = fp->_IO_buf_base;
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+
+ return fp;
+}
+
+/* Write TO_DO bytes from DATA to FP.
+ Then mark FP as having empty buffers. */
+
+int
+_IO_do_write (fp, data, to_do)
+ _IO_FILE *fp;
+ const char *data;
+ _IO_size_t to_do;
+{
+ _IO_size_t count;
+ if (to_do == 0)
+ return 0;
+ if (fp->_flags & _IO_IS_APPENDING)
+ /* On a system without a proper O_APPEND implementation,
+ you would need to sys_seek(0, SEEK_END) here, but is
+ is not needed nor desirable for Unix- or Posix-like systems.
+ Instead, just indicate that offset (before and after) is
+ unpredictable. */
+ fp->_offset = _IO_pos_BAD;
+ else if (fp->_IO_read_end != fp->_IO_write_base)
+ {
+ _IO_pos_t new_pos
+ = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
+ if (new_pos == _IO_pos_BAD)
+ return EOF;
+ fp->_offset = new_pos;
+ }
+ count = _IO_SYSWRITE (fp, data, to_do);
+ if (fp->_cur_column)
+ fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, to_do) + 1;
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
+ fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+ ? fp->_IO_buf_base : fp->_IO_buf_end);
+ return count != to_do ? EOF : 0;
+}
+
+int
+_IO_file_underflow (fp)
+ _IO_FILE *fp;
+{
+ _IO_ssize_t count;
+#if 0
+ /* SysV does not make this test; take it out for compatibility */
+ if (fp->_flags & _IO_EOF_SEEN)
+ return (EOF);
+#endif
+
+ if (fp->_flags & _IO_NO_READS)
+ {
+ __set_errno (EBADF);
+ return EOF;
+ }
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *(unsigned char *) fp->_IO_read_ptr;
+
+ if (fp->_IO_buf_base == NULL)
+ _IO_doallocbuf (fp);
+
+ /* Flush all line buffered files before reading. */
+ /* FIXME This can/should be moved to genops ?? */
+ if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
+ _IO_flush_all_linebuffered ();
+
+ _IO_switch_to_get_mode (fp);
+
+ /* This is very tricky. We have to adjust those
+ pointers before we call _IO_SYSREAD () since
+ we may longjump () out while waiting for
+ input. Those pointers may be screwed up. H.J. */
+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
+ fp->_IO_read_end = fp->_IO_buf_base;
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+ = fp->_IO_buf_base;
+
+ count = _IO_SYSREAD (fp, fp->_IO_buf_base,
+ fp->_IO_buf_end - fp->_IO_buf_base);
+ if (count <= 0)
+ {
+ if (count == 0)
+ fp->_flags |= _IO_EOF_SEEN;
+ else
+ fp->_flags |= _IO_ERR_SEEN, count = 0;
+ }
+ fp->_IO_read_end += count;
+ if (count == 0)
+ return EOF;
+ if (fp->_offset != _IO_pos_BAD)
+ _IO_pos_adjust (fp->_offset, count);
+ return *(unsigned char *) fp->_IO_read_ptr;
+}
+
+int
+_IO_file_overflow (f, ch)
+ _IO_FILE *f;
+ int ch;
+{
+ if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
+ {
+ f->_flags |= _IO_ERR_SEEN;
+ __set_errno (EBADF);
+ return EOF;
+ }
+ /* If currently reading or no buffer allocated. */
+ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
+ {
+ /* Allocate a buffer if needed. */
+ if (f->_IO_write_base == 0)
+ {
+ _IO_doallocbuf (f);
+ _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
+ }
+ /* Otherwise must be currently reading.
+ If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
+ logically slide the buffer forwards one block (by setting the
+ read pointers to all point at the beginning of the block). This
+ makes room for subsequent output.
+ Otherwise, set the read pointers to _IO_read_end (leaving that
+ alone, so it can continue to correspond to the external position). */
+ if (f->_IO_read_ptr == f->_IO_buf_end)
+ f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
+ f->_IO_write_ptr = f->_IO_read_ptr;
+ f->_IO_write_base = f->_IO_write_ptr;
+ f->_IO_write_end = f->_IO_buf_end;
+ f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
+
+ if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+ f->_IO_write_end = f->_IO_write_ptr;
+ f->_flags |= _IO_CURRENTLY_PUTTING;
+ }
+ if (ch == EOF)
+ return _IO_do_flush (f);
+ if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
+ if (_IO_do_flush (f) == EOF)
+ return EOF;
+ *f->_IO_write_ptr++ = ch;
+ if ((f->_flags & _IO_UNBUFFERED)
+ || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
+ if (_IO_do_flush (f) == EOF)
+ return EOF;
+ return (unsigned char) ch;
+}
+
+int
+_IO_file_sync (fp)
+ _IO_FILE *fp;
+{
+ _IO_size_t delta;
+ int retval = 0;
+
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ /* char* ptr = cur_ptr(); */
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ if (_IO_do_flush(fp)) return EOF;
+ delta = fp->_IO_read_ptr - fp->_IO_read_end;
+ if (delta != 0)
+ {
+#ifdef TODO
+ if (_IO_in_backup (fp))
+ delta -= eGptr () - Gbase ();
+#endif
+ _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1);
+ if (new_pos != (_IO_off_t) EOF)
+ fp->_IO_read_end = fp->_IO_read_ptr;
+#ifdef ESPIPE
+ else if (errno == ESPIPE)
+ ; /* Ignore error from unseekable devices. */
+#endif
+ else
+ retval = EOF;
+ }
+ if (retval != EOF)
+ fp->_offset = _IO_pos_BAD;
+ /* FIXME: Cleanup - can this be shared? */
+ /* setg(base(), ptr, ptr); */
+ _IO_cleanup_region_end (1);
+ return retval;
+}
+
+_IO_pos_t
+_IO_file_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+ int mode;
+{
+ _IO_pos_t result;
+ _IO_off_t delta, new_offset;
+ long count;
+ /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
+ offset of the underlying file must be exact. */
+ int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
+ && fp->_IO_write_base == fp->_IO_write_ptr);
+
+ if (mode == 0)
+ dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+
+ /* Flush unwritten characters.
+ (This may do an unneeded write if we seek within the buffer.
+ But to be able to switch to reading, we would need to set
+ egptr to ptr. That can't be done in the current design,
+ which assumes file_ptr() is eGptr. Anyway, since we probably
+ end up flushing when we close(), it doesn't make much difference.)
+ FIXME: simulate mem-papped files. */
+
+ if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
+ if (_IO_switch_to_get_mode (fp))
+ return EOF;
+
+ if (fp->_IO_buf_base == NULL)
+ {
+ _IO_doallocbuf (fp);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ }
+
+ switch (dir)
+ {
+ case _IO_seek_cur:
+ /* Adjust for read-ahead (bytes is buffer). */
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ if (fp->_offset == _IO_pos_BAD)
+ goto dumb;
+ /* Make offset absolute, assuming current pointer is file_ptr(). */
+ offset += _IO_pos_as_off (fp->_offset);
+
+ dir = _IO_seek_set;
+ break;
+ case _IO_seek_set:
+ break;
+ case _IO_seek_end:
+ {
+ struct stat st;
+ if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
+ {
+ offset += st.st_size;
+ dir = _IO_seek_set;
+ }
+ else
+ goto dumb;
+ }
+ }
+ /* At this point, dir==_IO_seek_set. */
+
+ /* If destination is within current buffer, optimize: */
+ if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
+ && !_IO_in_backup (fp))
+ {
+ /* Offset relative to start of main get area. */
+ _IO_pos_t rel_offset = (offset - fp->_offset
+ + (fp->_IO_read_end - fp->_IO_read_base));
+ if (rel_offset >= 0)
+ {
+#if 0
+ if (_IO_in_backup (fp))
+ _IO_switch_to_main_get_area (fp);
+#endif
+ if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
+ {
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
+ fp->_IO_read_end);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ return offset;
+ }
+#ifdef TODO
+ /* If we have streammarkers, seek forward by reading ahead. */
+ if (_IO_have_markers (fp))
+ {
+ int to_skip = rel_offset
+ - (fp->_IO_read_ptr - fp->_IO_read_base);
+ if (ignore (to_skip) != to_skip)
+ goto dumb;
+ return offset;
+ }
+#endif
+ }
+#ifdef TODO
+ if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
+ {
+ if (!_IO_in_backup (fp))
+ _IO_switch_to_backup_area (fp);
+ gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
+ return offset;
+ }
+#endif
+ }
+
+#ifdef TODO
+ _IO_unsave_markers (fp);
+#endif
+
+ if (fp->_flags & _IO_NO_READS)
+ goto dumb;
+
+ /* Try to seek to a block boundary, to improve kernel page management. */
+ new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
+ delta = offset - new_offset;
+ if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
+ {
+ new_offset = offset;
+ delta = 0;
+ }
+ result = _IO_SYSSEEK (fp, new_offset, 0);
+ if (result < 0)
+ return EOF;
+ if (delta == 0)
+ count = 0;
+ else
+ {
+ count = _IO_SYSREAD (fp, fp->_IO_buf_base,
+ (must_be_exact
+ ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
+ if (count < delta)
+ {
+ /* We weren't allowed to read, but try to seek the remainder. */
+ offset = count == EOF ? delta : delta-count;
+ dir = _IO_seek_cur;
+ goto dumb;
+ }
+ }
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
+ fp->_IO_buf_base + count);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ fp->_offset = result + count;
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ return offset;
+ dumb:
+
+ _IO_unsave_markers (fp);
+ result = _IO_SYSSEEK (fp, offset, dir);
+ if (result != EOF)
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ fp->_offset = result;
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ return result;
+}
+
+_IO_ssize_t
+_IO_file_read (fp, buf, size)
+ _IO_FILE *fp;
+ void *buf;
+ _IO_ssize_t size;
+{
+ return read (fp->_fileno, buf, size);
+}
+
+_IO_pos_t
+_IO_file_seek (fp, offset, dir)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+{
+ return lseek (fp->_fileno, offset, dir);
+}
+
+int
+_IO_file_stat (fp, st)
+ _IO_FILE *fp;
+ void *st;
+{
+ return fstat (fp->_fileno, (struct stat *) st);
+}
+
+int
+_IO_file_close (fp)
+ _IO_FILE *fp;
+{
+ return close (fp->_fileno);
+}
+
+_IO_ssize_t
+_IO_file_write (f, data, n)
+ _IO_FILE *f;
+ const void *data;
+ _IO_ssize_t n;
+{
+ _IO_ssize_t to_do = n;
+ while (to_do > 0)
+ {
+ _IO_ssize_t count = write (f->_fileno, data, to_do);
+ if (count == EOF)
+ {
+ f->_flags |= _IO_ERR_SEEN;
+ break;
+ }
+ to_do -= count;
+ data = (void *) ((char *) data + count);
+ }
+ n -= to_do;
+ if (f->_offset >= 0)
+ f->_offset += n;
+ return n;
+}
+
+_IO_size_t
+_IO_file_xsputn (f, data, n)
+ _IO_FILE *f;
+ const void *data;
+ _IO_size_t n;
+{
+ register const char *s = (char *) data;
+ _IO_size_t to_do = n;
+ int must_flush = 0;
+ _IO_size_t count;
+
+ if (n <= 0)
+ return 0;
+ /* This is an optimized implementation.
+ If the amount to be written straddles a block boundary
+ (or the filebuf is unbuffered), use sys_write directly. */
+
+ /* First figure out how much space is available in the buffer. */
+ count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+ if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ count = f->_IO_buf_end - f->_IO_write_ptr;
+ if (count >= n)
+ {
+ register const char *p;
+ for (p = s + n; p > s; )
+ {
+ if (*--p == '\n')
+ {
+ count = p - s + 1;
+ must_flush = 1;
+ break;
+ }
+ }
+ }
+ }
+ /* Then fill the buffer. */
+ if (count > 0)
+ {
+ if (count > to_do)
+ count = to_do;
+ if (count > 20)
+ {
+ memcpy (f->_IO_write_ptr, s, count);
+ s += count;
+ }
+ else
+ {
+ register char *p = f->_IO_write_ptr;
+ register int i = (int) count;
+ while (--i >= 0)
+ *p++ = *s++;
+ }
+ f->_IO_write_ptr += count;
+ to_do -= count;
+ }
+ if (to_do + must_flush > 0)
+ {
+ _IO_size_t block_size, dont_write;
+ /* Next flush the (full) buffer. */
+ if (__overflow (f, EOF) == EOF)
+ return n - to_do;
+
+ /* Try to maintain alignment: write a whole number of blocks.
+ dont_write is what gets left over. */
+ block_size = f->_IO_buf_end - f->_IO_buf_base;
+ dont_write = block_size >= 128 ? to_do % block_size : 0;
+
+ count = to_do - dont_write;
+ if (_IO_do_write (f, s, count) == EOF)
+ return n - to_do;
+ to_do = dont_write;
+
+ /* Now write out the remainder. Normally, this will fit in the
+ buffer, but it's somewhat messier for line-buffered files,
+ so we let _IO_default_xsputn handle the general case. */
+ if (dont_write)
+ to_do -= _IO_default_xsputn (f, s+count, dont_write);
+ }
+ return n - to_do;
+}
+
+#if 0
+/* Work in progress */
+_IO_size_t
+_IO_file_xsgetn (fp, data, n)
+ _IO_FILE *fp;
+ void *data;
+ _IO_size_t n;
+{
+ register _IO_size_t more = n;
+ register char *s = data;
+ for (;;)
+ {
+ /* Data available. */
+ _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (count > 0)
+ {
+ if (count > more)
+ count = more;
+ if (count > 20)
+ {
+ memcpy (s, fp->_IO_read_ptr, count);
+ s += count;
+ fp->_IO_read_ptr += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else
+ {
+ register char *p = fp->_IO_read_ptr;
+ register int i = (int) count;
+ while (--i >= 0)
+ *s++ = *p++;
+ fp->_IO_read_ptr = p;
+ }
+ more -= count;
+ }
+#if 0
+ if (! _IO_in put_mode (fp)
+ && ! _IO_have_markers (fp) && ! IO_have_backup (fp))
+ {
+ /* This is an optimization of _IO_file_underflow */
+ if (fp->_flags & _IO_NO_READS)
+ break;
+ /* If we're reading a lot of data, don't bother allocating
+ a buffer. But if we're only reading a bit, perhaps we should ??*/
+ if (count <= 512 && fp->_IO_buf_base == NULL)
+ _IO_doallocbuf (fp);
+ if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
+ _IO_flush_all_linebuffered ();
+
+ _IO_switch_to_get_mode (fp); ???;
+ count = _IO_SYSREAD (fp, s, more);
+ if (count <= 0)
+ {
+ if (count == 0)
+ fp->_flags |= _IO_EOF_SEEN;
+ else
+ fp->_flags |= _IO_ERR_SEEN, count = 0;
+ }
+
+ s += count;
+ more -= count;
+ }
+#endif
+ if (more == 0 || __underflow (fp) == EOF)
+ break;
+ }
+ return n - more;
+}
+#endif
+
+struct _IO_jump_t _IO_file_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_file_finish),
+ JUMP_INIT(overflow, _IO_file_overflow),
+ JUMP_INIT(underflow, _IO_file_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_file_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_file_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_file_setbuf),
+ JUMP_INIT(sync, _IO_file_sync),
+ JUMP_INIT(doallocate, _IO_file_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_file_close),
+ JUMP_INIT(stat, _IO_file_stat)
+};
diff --git a/gnu/dist/libio/floatconv.c b/gnu/dist/libio/floatconv.c
new file mode 100644
index 00000000000..9503187b5d5
--- /dev/null
+++ b/gnu/dist/libio/floatconv.c
@@ -0,0 +1,2375 @@
+/*
+Copyright (C) 1993, 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+#ifdef _IO_USE_DTOA
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Some cleaning up by Per Bothner, bothner@cygnus.com, 1992, 1993.
+ Re-written to not need static variables
+ (except result, result_k, HIWORD, LOWORD). */
+
+/* Note that the checking of _DOUBLE_IS_32BITS is for use with the
+ cross targets that employ the newlib ieeefp.h header. -- brendan */
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define KR_headers for old-style C function headers.
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#define CONST const
+#else
+#define CONST
+#define KR_headers
+
+/* In this case, we assume IEEE floats. */
+#define FLT_ROUNDS 1
+#define FLT_RADIX 2
+#define DBL_MANT_DIG 53
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#endif
+
+#include <errno.h>
+#ifndef __MATH_H__
+#include <math.h>
+#endif
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if defined(__i386__) || defined(__i860__) || defined(clipper)
+#define IEEE_8087
+#endif
+#if defined(MIPSEL) || defined(__alpha__)
+#define IEEE_8087
+#endif
+#if defined(__sparc__) || defined(sparc) || defined(MIPSEB)
+#define IEEE_MC68k
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+
+#ifndef _DOUBLE_IS_32BITS
+#if FLT_RADIX==16
+#define IBM
+#else
+#if DBL_MANT_DIG==56
+#define VAX
+#else
+#if DBL_MANT_DIG==53 && DBL_MAX_10_EXP==308
+#define IEEE_Unknown
+#else
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+#endif
+#endif
+#endif /* !_DOUBLE_IS_32BITS */
+#endif
+
+typedef _G_uint32_t unsigned32;
+
+union doubleword {
+ double d;
+ unsigned32 u[2];
+};
+
+#ifdef IEEE_8087
+#define HIWORD 1
+#define LOWORD 0
+#define TEST_ENDIANNESS /* nothing */
+#else
+#if defined(IEEE_MC68k)
+#define HIWORD 0
+#define LOWORD 1
+#define TEST_ENDIANNESS /* nothing */
+#else
+static int HIWORD = -1, LOWORD;
+static void test_endianness()
+{
+ union doubleword dw;
+ dw.d = 10;
+ if (dw.u[0] != 0) /* big-endian */
+ HIWORD=0, LOWORD=1;
+ else
+ HIWORD=1, LOWORD=0;
+}
+#define TEST_ENDIANNESS if (HIWORD<0) test_endianness();
+#endif
+#endif
+
+#if 0
+union doubleword _temp;
+#endif
+#if defined(__GNUC__) && !defined(_DOUBLE_IS_32BITS)
+#define word0(x) ({ union doubleword _du; _du.d = (x); _du.u[HIWORD]; })
+#define word1(x) ({ union doubleword _du; _du.d = (x); _du.u[LOWORD]; })
+#define setword0(D,W) \
+ ({ union doubleword _du; _du.d = (D); _du.u[HIWORD]=(W); (D)=_du.d; })
+#define setword1(D,W) \
+ ({ union doubleword _du; _du.d = (D); _du.u[LOWORD]=(W); (D)=_du.d; })
+#define setwords(D,W0,W1) ({ union doubleword _du; \
+ _du.u[HIWORD]=(W0); _du.u[LOWORD]=(W1); (D)=_du.d; })
+#define addword0(D,W) \
+ ({ union doubleword _du; _du.d = (D); _du.u[HIWORD]+=(W); (D)=_du.d; })
+#else
+#define word0(x) ((unsigned32 *)&x)[HIWORD]
+#ifndef _DOUBLE_IS_32BITS
+#define word1(x) ((unsigned32 *)&x)[LOWORD]
+#else
+#define word1(x) 0
+#endif
+#define setword0(D,W) word0(D) = (W)
+#ifndef _DOUBLE_IS_32BITS
+#define setword1(D,W) word1(D) = (W)
+#define setwords(D,W0,W1) (setword0(D,W0),setword1(D,W1))
+#else
+#define setword1(D,W)
+#define setwords(D,W0,W1) (setword0(D,W0))
+#endif
+#define addword0(D,X) (word0(D) += (X))
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors. */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#if defined(IEEE_MC68k)
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+#endif
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_Unknown)
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#define Kmax 15
+
+/* (1<<BIGINT_MINIMUM_K) is the minimum number of words to allocate
+ in a Bigint. dtoa usually manages with 1<<2, and has not been
+ known to need more than 1<<3. */
+
+#define BIGINT_MINIMUM_K 3
+
+struct Bigint {
+ struct Bigint *next;
+ int k; /* Parameter given to Balloc(k) */
+ int maxwds; /* Allocated space: equals 1<<k. */
+ short on_stack; /* 1 if stack-allocated. */
+ short sign; /* 0 if value is positive or zero; 1 if negative. */
+ int wds; /* Current length. */
+ unsigned32 x[1<<BIGINT_MINIMUM_K]; /* Actually: x[maxwds] */
+};
+
+#define BIGINT_HEADER_SIZE \
+ (sizeof(Bigint) - (1<<BIGINT_MINIMUM_K) * sizeof(unsigned32))
+
+typedef struct Bigint Bigint;
+
+/* Initialize a stack-allocated Bigint. */
+
+static Bigint *
+Binit
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ v->on_stack = 1;
+ v->k = BIGINT_MINIMUM_K;
+ v->maxwds = 1 << BIGINT_MINIMUM_K;
+ v->sign = v->wds = 0;
+ return v;
+}
+
+/* Allocate a Bigint with '1<<k' big digits. */
+
+static Bigint *
+Balloc
+#ifdef KR_headers
+ (k) int k;
+#else
+ (int k)
+#endif
+{
+ int x;
+ Bigint *rv;
+
+ if (k < BIGINT_MINIMUM_K)
+ k = BIGINT_MINIMUM_K;
+
+ x = 1 << k;
+ rv = (Bigint *)
+ malloc(BIGINT_HEADER_SIZE + x * sizeof(unsigned32));
+ rv->k = k;
+ rv->maxwds = x;
+ rv->sign = rv->wds = 0;
+ rv->on_stack = 0;
+ return rv;
+}
+
+static void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v && !v->on_stack)
+ free (v);
+}
+
+static void
+Bcopy
+#ifdef KR_headers
+ (x, y) Bigint *x, *y;
+#else
+ (Bigint *x, Bigint *y)
+#endif
+{
+ register unsigned32 *xp, *yp;
+ register int i = y->wds;
+ x->sign = y->sign;
+ x->wds = i;
+ for (xp = x->x, yp = y->x; --i >= 0; )
+ *xp++ = *yp++;
+}
+
+/* Make sure b has room for at least 1<<k big digits. */
+
+static Bigint *
+Brealloc
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint * b, int k)
+#endif
+{
+ if (b == NULL)
+ return Balloc(k);
+ if (b->k >= k)
+ return b;
+ else
+ {
+ Bigint *rv = Balloc (k);
+ Bcopy(rv, b);
+ Bfree(b);
+ return rv;
+ }
+}
+
+/* Return b*m+a. b is modified.
+ Assumption: 0xFFFF*m+a fits in 32 bits. */
+
+static Bigint *
+multadd
+#ifdef KR_headers
+ (b, m, a) Bigint *b; int m, a;
+#else
+ (Bigint *b, int m, int a)
+#endif
+{
+ int i, wds;
+ unsigned32 *x, y;
+ unsigned32 xi, z;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int)(z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+ }
+ while(++i < wds);
+ if (a) {
+ if (wds >= b->maxwds)
+ b = Brealloc(b, b->k+1);
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+static Bigint *
+s2b
+#ifdef KR_headers
+ (result, s, nd0, nd, y9)
+ Bigint *result; CONST char *s; int nd0, nd; unsigned32 y9;
+#else
+ (Bigint *result, CONST char *s, int nd0, int nd, unsigned32 y9)
+#endif
+{
+ int i, k;
+ _G_int32_t x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+ result = Brealloc(result, k);
+ result->x[0] = y9;
+ result->wds = 1;
+
+ i = 9;
+ if (9 < nd0)
+ {
+ s += 9;
+ do
+ result = multadd(result, 10, *s++ - '0');
+ while (++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ result = multadd(result, 10, *s++ - '0');
+ return result;
+}
+
+static int
+hi0bits
+#ifdef KR_headers
+ (x) register unsigned32 x;
+#else
+ (register unsigned32 x)
+#endif
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+ }
+
+static int
+lo0bits
+#ifdef KR_headers
+ (y) unsigned32 *y;
+#else
+ (unsigned32 *y)
+#endif
+{
+ register int k;
+ register unsigned32 x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+ }
+
+static Bigint *
+i2b
+#ifdef KR_headers
+ (result, i) Bigint *result; int i;
+#else
+ (Bigint* result, int i)
+#endif
+{
+ result = Brealloc(result, 1);
+ result->x[0] = i;
+ result->wds = 1;
+ return result;
+}
+
+/* Do: c = a * b. */
+
+static Bigint *
+mult
+#ifdef KR_headers
+ (c, a, b) Bigint *a, *b, *c;
+#else
+ (Bigint *c, Bigint *a, Bigint *b)
+#endif
+{
+ int k, wa, wb, wc;
+ unsigned32 carry, y, z;
+ unsigned32 *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ unsigned32 z2;
+ if (a->wds < b->wds) {
+ Bigint *tmp = a;
+ a = b;
+ b = tmp;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Brealloc(c, k);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+ for(; xb < xbe; xb++, xc0++) {
+ if ((y = *xb & 0xffff)) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16)) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+/* Returns b*(5**k). b is modified. */
+/* Re-written by Per Bothner to not need a static list. */
+
+static Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ static int p05[6] = { 5, 25, 125, 625, 3125, 15625 };
+
+ for (; k > 6; k -= 6)
+ b = multadd(b, 15625, 0); /* b *= 5**6 */
+ if (k == 0)
+ return b;
+ else
+ return multadd(b, p05[k-1], 0);
+}
+
+/* Re-written by Per Bothner so shift can be in place. */
+
+static Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i;
+ unsigned32 *x, *x1, *xe;
+ int old_wds = b->wds;
+ int n = k >> 5;
+ int k1 = b->k;
+ int n1 = n + old_wds + 1;
+
+ if (k == 0)
+ return b;
+
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b = Brealloc(b, k1);
+
+ xe = b->x; /* Source limit */
+ x = xe + old_wds; /* Source pointer */
+ x1 = x + n; /* Destination pointer */
+ if (k &= 0x1f) {
+ int k1 = 32 - k;
+ unsigned32 z = *--x;
+ if ((*x1 = (z >> k1)) != 0) {
+ ++n1;
+ }
+ while (x > xe) {
+ unsigned32 w = *--x;
+ *--x1 = (z << k) | (w >> k1);
+ z = w;
+ }
+ *--x1 = z << k;
+ }
+ else
+ do {
+ *--x1 = *--x;
+ } while(x > xe);
+ while (x1 > xe)
+ *--x1 = 0;
+ b->wds = n1 - 1;
+ return b;
+}
+
+static int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ unsigned32 *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+ }
+
+/* Do: c = a-b. */
+
+static Bigint *
+diff
+#ifdef KR_headers
+ (c, a, b) Bigint *c, *a, *b;
+#else
+ (Bigint *c, Bigint *a, Bigint *b)
+#endif
+{
+ int i, wa, wb;
+ _G_int32_t borrow, y; /* We need signed shifts here. */
+ unsigned32 *xa, *xae, *xb, *xbe, *xc;
+ _G_int32_t z;
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Brealloc(c, 0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ Bigint *tmp = a;
+ a = b;
+ b = tmp;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Brealloc(c, a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+static double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ register _G_int32_t L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ setwords(a, L, 0);
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift)
+ setwords(a, 0x80000 >> L, 0);
+ else {
+ L -= Exp_shift;
+ setwords(a, 0, L >= 31 ? 1 : 1 << (31 - L));
+ }
+ }
+#endif
+ return a;
+ }
+
+static double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ unsigned32 *xa, *xa0, w, y, z;
+ int k;
+ double d;
+ unsigned32 d0, d1;
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+ if (k < Ebits) {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
+#endif
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = z << k | y >> (32 - k);
+#endif
+ }
+ else {
+ d0 = Exp_1 | y;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = z;
+#endif
+ }
+ ret_d:
+#ifdef VAX
+ setwords(d, d0 >> 16 | d0 << 16, d1 >> 16 | d1 << 16);
+#else
+ setwords (d, d0, d1);
+#endif
+ return d;
+ }
+
+static Bigint *
+d2b
+#ifdef KR_headers
+ (result, d, e, bits) Bigint *result; double d; _G_int32_t *e, *bits;
+#else
+ (Bigint *result, double d, _G_int32_t *e, _G_int32_t *bits)
+#endif
+{
+ int de, i, k;
+ unsigned32 *x, y, z;
+ unsigned32 d0, d1;
+#ifdef VAX
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+ d0 = word0(d);
+ d1 = word1(d);
+#endif
+
+ result = Brealloc(result, 1);
+ x = result->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+
+ de = (int)(d0 >> Exp_shift); /* The exponent part of d. */
+
+ /* Put back the suppressed high-order bit, if normalized. */
+#ifndef IBM
+#ifndef Sudden_Underflow
+ if (de)
+#endif
+ z |= Exp_msk11;
+#endif
+
+#ifndef _DOUBLE_IS_32BITS
+ if ((y = d1)) {
+ if ((k = lo0bits(&y))) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = result->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+#endif /* !_DOUBLE_IS_32BITS */
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = result->wds = 1;
+#ifndef _DOUBLE_IS_32BITS
+ k += 32;
+ }
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+ *bits = 32*i - hi0bits(x[i-1]);
+ }
+#endif
+ return result;
+ }
+
+static double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+ k = ka - kb + 32*(a->wds - b->wds);
+#ifdef IBM
+ if (k > 0) {
+ addword0(da, (k >> 2)*Exp_msk1);
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ addword0(db,(k >> 2)*Exp_msk1);
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ addword0(da, k*Exp_msk1);
+ else {
+ k = -k;
+ addword0(db, k*Exp_msk1);
+ }
+#endif
+ return da / db;
+ }
+
+static CONST double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+#ifdef IEEE_Arith
+static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+/* Also used for the case when !_DOUBLE_IS_32BITS. */
+static CONST double bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+ double
+_IO_strtod
+#ifdef KR_headers
+ (s00, se) CONST char *s00; char **se;
+#else
+ (CONST char *s00, char **se)
+#endif
+{
+ _G_int32_t bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ _G_int32_t L;
+ unsigned32 y, z;
+ Bigint _bb, _b_avail, _bd, _bd0, _bs, _delta;
+ Bigint *bb = Binit(&_bb);
+ Bigint *bd = Binit(&_bd);
+ Bigint *bd0 = Binit(&_bd0);
+ Bigint *bs = Binit(&_bs);
+ Bigint *b_avail = Binit(&_b_avail);
+ Bigint *delta = Binit(&_delta);
+
+ TEST_ENDIANNESS;
+ sign = nz0 = nz = 0;
+ rv = 0.;
+ (void)&rv; /* Force rv into the stack */
+ for(s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ /* "+" and "-" should be reported as an error? */
+ sign = 0;
+ s = s00;
+ goto ret;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == '.') {
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ e = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ e = 10*e + c - '0';
+ if (s - s1 > 8)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 9999999;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+ rv = tens[k - 9] * rv + z;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ addword0(rv, - P*Exp_msk1);
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ addword0(rv, P*Exp_msk1);
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15))
+ rv *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ errno = ERANGE;
+#if defined(sun) && !defined(__svr4__)
+/* SunOS defines HUGE_VAL as __infinity(), which is in libm. */
+#undef HUGE_VAL
+#endif
+#ifndef HUGE_VAL
+#define HUGE_VAL 1.7976931348623157E+308
+#endif
+ rv = HUGE_VAL;
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ addword0(rv, -P*Exp_msk1);
+ rv *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ setwords(rv, Big0, Big1);
+ }
+ else
+ addword0(rv, P*Exp_msk1);
+ }
+
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15))
+ rv /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (!rv) {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (!rv) {
+ undfl:
+ rv = 0.;
+ errno = ERANGE;
+ goto ret;
+ }
+ setwords(rv, Tiny0, Tiny1);
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(bd0, s0, nd0, nd, y);
+ bd = Brealloc(bd, bd0->k);
+
+ for(;;) {
+ Bcopy(bd, bd0);
+ bb = d2b(bb, rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(bs, 1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P-Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ Bigint *b_tmp;
+ bs = pow5mult(bs, bb5);
+ b_tmp = mult(b_avail, bs, bb);
+ b_avail = bb;
+ bb = b_tmp;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(delta, bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ setword0(rv, (word0(rv) & Exp_mask)
+ + Exp_msk1);
+#ifdef IBM
+ setword0 (rv,
+ word0(rv) | (Exp_msk1 >> 4));
+#endif
+ setword1(rv, 0);
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ setwords(rv, L | Bndry_mask1, 0xffffffff);
+#ifdef IBM
+ continue;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (!rv)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ addword0(rv, - P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ setwords(rv, Big0, Big1);
+ continue;
+ }
+ else
+ addword0(rv, P*Exp_msk1);
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ addword0(rv, P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ setwords(rv, Tiny0, Tiny1);
+ continue;
+ }
+ else
+ addword0(rv, -P*Exp_msk1);
+ }
+ else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = word0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = (_G_int32_t)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ }
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ Bfree(b_avail);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -rv : rv;
+ }
+
+static int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ _G_int32_t borrow, y;
+ unsigned32 carry, q, ys;
+ unsigned32 *bx, *bxe, *sx, *sxe;
+ _G_int32_t z;
+ unsigned32 si, zs;
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+ }
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the long
+ * calculation.
+ */
+
+ char *
+_IO_dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ _G_int32_t bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick;
+ _G_int32_t L;
+#ifndef Sudden_Underflow
+ int denorm;
+#endif
+ Bigint _b_avail, _b, _mhi, _mlo, _S;
+ Bigint *b_avail = Binit(&_b_avail);
+ Bigint *b = Binit(&_b);
+ Bigint *S = Binit(&_S);
+ /* mhi and mlo are only set and used if leftright. */
+ Bigint *mhi = NULL, *mlo = NULL;
+ double d2, ds, eps;
+ char *s, *s0;
+ static Bigint *result = NULL;
+ static int result_k;
+
+ TEST_ENDIANNESS;
+ if (result) {
+ /* result is contains a string, so its fields (interpreted
+ as a Bigint have been trashed. Restore them.
+ This is a really ugly interface - result should
+ not be static, since that is not thread-safe. FIXME. */
+ result->k = result_k;
+ result->maxwds = 1 << result_k;
+ result->on_stack = 0;
+ }
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ setword0(d, word0(d) & ~Sign_bit); /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff))
+ {
+ s = "Infinity";
+ if (rve)
+ *rve = s + 8;
+ }
+ else
+#endif
+ {
+ s = "NaN";
+ if (rve)
+ *rve = s +3;
+ }
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (!d) {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(b, d, &be, &bbits);
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#ifndef Sudden_Underflow
+ if (i) {
+#endif
+ d2 = d;
+ setword0(d2, (word0(d2) & Frac_mask1) | Exp_11);
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+ d2 /= 1 << j;
+#endif
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+ unsigned32 x;
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
+ : word1(d) << (32 - i);
+ d2 = x;
+ addword0(d2, - 31*Exp_msk1); /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+
+ /* Now i is the unbiased base-2 exponent. */
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = i*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = i*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i) by 0.301029995663981; since |i| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ /* i is now an upper bound of the number of digits to generate. */
+ j = sizeof(unsigned32) * (1<<BIGINT_MINIMUM_K);
+ /* The test is <= so as to allow room for the final '\0'. */
+ for(result_k = BIGINT_MINIMUM_K; BIGINT_HEADER_SIZE + j <= i;
+ j <<= 1) result_k++;
+ if (!result || result_k > result->k)
+ {
+ Bfree (result);
+ result = Balloc(result_k);
+ }
+ s = s0 = (char *)result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if ((j1 = -k)) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ addword0(eps, - (P-1)*Exp_msk1);
+ if (ilim == 0) {
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = (_G_int32_t)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for(i = 1;; i++, d *= 10.) {
+ L = (_G_int32_t)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++) {
+ L = (_G_int32_t)(d / ds);
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ d += d;
+ if (d > ds || (d == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ if (leftright) {
+ if (mode < 2) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(Binit(&_mhi), 1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ Bigint *b_tmp;
+ mhi = pow5mult(mhi, m5);
+ b_tmp = mult(b_avail, mhi, b);
+ b_avail = b;
+ b = b_tmp;
+ }
+ if ((j = b5 - m5))
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(S, 1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & Exp_mask
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
+ i = 32 - i;
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ if (spec_case) {
+ mlo = Brealloc(Binit(&_mlo), mhi->k);
+ Bcopy(mlo, mhi);
+ mhi = lshift(mhi, Log2P);
+ }
+ else
+ mlo = mhi;
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ b_avail = diff(b_avail, S, mhi); /* b_avail = S - mi */
+ j1 = b_avail->sign ? 1 : cmp(b, b_avail);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(word1(d) & 1)) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ )) {
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(b_avail);
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
+#endif /* _IO_USE_DTOA */
diff --git a/gnu/dist/libio/floatio.h b/gnu/dist/libio/floatio.h
new file mode 100644
index 00000000000..827767bde35
--- /dev/null
+++ b/gnu/dist/libio/floatio.h
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * %W% (Berkeley) %G%
+ */
+
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
diff --git a/gnu/dist/libio/fstream.cc b/gnu/dist/libio/fstream.cc
new file mode 100644
index 00000000000..8930e0b9271
--- /dev/null
+++ b/gnu/dist/libio/fstream.cc
@@ -0,0 +1,110 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+extern "C" {
+#include "libioP.h"
+}
+#include <fstream.h>
+
+inline void
+fstreambase::__fb_init()
+{
+#ifdef _IO_NEW_STREAMS
+#if !_IO_UNIFIED_JUMPTABLES
+ /* Uses the _IO_file_jump jumptable, for eficiency. */
+ __my_fb._jumps = &_IO_file_jumps;
+ __my_fb._vtable() = builtinbuf_vtable;
+#endif
+ init (&__my_fb);
+#else
+ init(filebuf::__new());
+ _flags &= ~ios::dont_close;
+#endif
+}
+
+fstreambase::fstreambase()
+{
+ __fb_init ();
+}
+
+fstreambase::fstreambase(int fd)
+{
+ __fb_init ();
+ _IO_file_attach(rdbuf(), fd);
+}
+
+fstreambase::fstreambase(const char *name, int mode, int prot)
+{
+ __fb_init ();
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+fstreambase::fstreambase(int fd, char *p, int l)
+{
+#ifdef _IO_NEW_STREAMS
+ __fb_init ();
+#else
+ init(filebuf::__new());
+#endif
+ _IO_file_attach(rdbuf(), fd);
+ _IO_file_setbuf(rdbuf(), p, l);
+}
+
+void fstreambase::open(const char *name, int mode, int prot)
+{
+ clear();
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+void fstreambase::close()
+{
+ if (!rdbuf()->close())
+ set(ios::failbit);
+}
+
+void fstreambase::attach(int fd)
+{
+ if (!rdbuf()->attach(fd))
+ set(ios::failbit);
+}
+
+#if 0
+static int mode_to_sys(enum open_mode mode)
+{
+ return O_WRONLY;
+}
+
+static char* fopen_cmd_arg(io_mode i)
+{
+ return "w";
+}
+#endif
diff --git a/gnu/dist/libio/fstream.h b/gnu/dist/libio/fstream.h
new file mode 100644
index 00000000000..ea98f5caed0
--- /dev/null
+++ b/gnu/dist/libio/fstream.h
@@ -0,0 +1,92 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _FSTREAM_H
+#define _FSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <iostream.h>
+
+extern "C++" {
+class fstreambase : virtual public ios {
+#ifdef _IO_NEW_STREAMS
+ mutable filebuf __my_fb; // mutable so rdbuf() can be const
+#endif
+ void __fb_init ();
+ public:
+ fstreambase();
+ fstreambase(int fd);
+ fstreambase(int fd, char *p, int l); /* Deprecated */
+ fstreambase(const char *name, int mode, int prot=0664);
+ void close();
+#ifdef _IO_NEW_STREAMS
+ filebuf* rdbuf() const { return &__my_fb; }
+#else
+ filebuf* rdbuf() const { return (filebuf*) ios::rdbuf(); }
+#endif
+ void open(const char *name, int mode, int prot=0664);
+ int is_open() const { return rdbuf()->is_open(); }
+ void setbuf(char *ptr, int len) { rdbuf()->setbuf(ptr, len); }
+ void attach(int fd);
+#ifdef _STREAM_COMPAT
+ int filedesc() { return rdbuf()->fd(); }
+ fstreambase& raw() { rdbuf()->setbuf(NULL, 0); return *this; }
+#endif
+};
+
+class ifstream : public fstreambase, public istream {
+ public:
+ ifstream() : fstreambase() { }
+ ifstream(int fd) : fstreambase(fd) { }
+ ifstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/
+ ifstream(const char *name, int mode=ios::in, int prot=0664)
+ : fstreambase(name, mode, prot) { }
+ void open(const char *name, int mode=ios::in, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+
+class ofstream : public fstreambase, public ostream {
+ public:
+ ofstream() : fstreambase() { }
+ ofstream(int fd) : fstreambase(fd) { }
+ ofstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/
+ ofstream(const char *name, int mode=ios::out, int prot=0664)
+ : fstreambase(name, mode, prot) { }
+ void open(const char *name, int mode=ios::out, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+
+class fstream : public fstreambase, public iostream {
+ public:
+ fstream() : fstreambase() { }
+ fstream(int fd) : fstreambase(fd) { }
+ fstream(const char *name, int mode, int prot=0664)
+ : fstreambase(name, mode, prot) { }
+ fstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/
+ void open(const char *name, int mode, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+} // extern "C++"
+#endif /*!_FSTREAM_H*/
diff --git a/gnu/dist/libio/gen-params b/gnu/dist/libio/gen-params
new file mode 100644
index 00000000000..37ee742e21c
--- /dev/null
+++ b/gnu/dist/libio/gen-params
@@ -0,0 +1,734 @@
+#!/bin/sh
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation
+#
+# This file is part of the GNU IO Library. This library is free
+# software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this library; see the file COPYING. If not, write to the Free
+# Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Written by Per Bothner (bothner@cygnus.com)
+
+# This is a shell-script that figures out various things about a
+# system, and writes (to stdout) a C-style include files with
+# suitable definitions, including all the standard Posix types.
+# It works by compiling various test programs -- some are run through
+# the C pre-processor, and the output examined.
+# The test programs are only compiled, not executed, so the script
+# should even if you're cross-compiling.
+# It uses $CC (which defaults to cc) to compile C programs (extension .c),
+# and $CXX (which defaults to gcc) to compile C++ programs (extension .C).
+# The shell-script is written for libg++.a.
+
+# Usage: gen-params [NAME1=name1 ...]
+# - where an assignment (such as size_t="unsigned int" means to
+# use that value, instead of trying to figure it out.
+
+# Uncomment following line for debugging
+# set -x
+
+SED=sed
+
+# Evaluate the arguments (which should be assignments):
+for arg in "$@"; do
+ # Quote arg (i.e. FOO=bar => FOO='bar'), then eval it.
+ eval `echo "$arg" | ${SED} -e "s|^\(.*\)=\(.*\)|\1='\2'|"`
+done
+
+macro_prefix=${macro_prefix-"_G_"}
+rootdir=`pwd`/..
+gccdir=${gccdir-${rootdir}/gcc}
+binutilsdir=${binutilsdir-${rootdir}/binutils}
+CC=${CC-`if [ -f ${gccdir}/xgcc ] ; \
+ then echo ${gccdir}/xgcc -B${gccdir}/ ; \
+ else echo cc ; fi`}
+CXX=${CXX-`if [ -f ${gccdir}/xgcc ] ; \
+ then echo ${gccdir}/xgcc -B${gccdir}/ ; \
+ else echo gcc ; fi`}
+CPP=${CPP-`echo ${CC} -E`}
+CONFIG_NM=${CONFIG_NM-`if [ -f ${binutilsdir}/nm.new ] ; \
+ then echo ${binutilsdir}/nm.new ; \
+ else echo nm ; fi`}
+
+cat <<!EOF!
+/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
+#ifndef ${macro_prefix}config_h
+#define ${macro_prefix}config_h
+!EOF!
+
+if [ x"${LIB_VERSION}" != "x" ] ; then
+ echo "#define ${macro_prefix}LIB_VERSION" '"'${LIB_VERSION}'"'
+fi
+
+# This program is used to test if the compiler prepends '_' before identifiers.
+# It is also used to check the g++ uses '$' or '.' various places.
+
+if test -z "${NAMES_HAVE_UNDERSCORE}" -o -z "${DOLLAR_IN_LABEL}" \
+ -o -z "${VTABLE_LABEL_PREFIX}"; then
+ cat >dummy.h <<!EOF!
+#ifdef __GNUG__
+#pragma interface
+#endif
+ struct filebuf {
+ virtual int foo();
+ };
+!EOF!
+ cat >dummy.C <<!EOF!
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "dummy.h"
+ int filebuf::foo() { return 0; }
+ extern "C" int FUNC(int);
+ int FUNC(int i) { return i+10; }
+!EOF!
+
+ if ${CXX} -O -c dummy.C ; then
+ if test -z "${NAMES_HAVE_UNDERSCORE}" ; then
+ if test "`${CONFIG_NM} dummy.o | grep _FUNC`" != ""; then
+ NAMES_HAVE_UNDERSCORE=1
+ elif test "`${CONFIG_NM} dummy.o | grep FUNC`" != ""; then
+ NAMES_HAVE_UNDERSCORE=0
+ else
+ echo "${CONFIG_NM} failed to find FUNC in dummy.o!" 1>&2; exit -1;
+ fi
+ fi
+ echo "#define ${macro_prefix}NAMES_HAVE_UNDERSCORE ${NAMES_HAVE_UNDERSCORE}"
+
+ if test -z "${VTABLE_LABEL_PREFIX}" ; then
+ # Determine how virtual function tables are named. This is fragile,
+ # because different nm's produce output in different formats.
+ ${CONFIG_NM} dummy.o >TMP
+ if [ -n "`${SED} -n -e 's/ virtual table/nope/p' <TMP`" ] ; then
+ ${CONFIG_NM} --no-cplus dummy.o >TMP 2>/dev/null ||
+ ${CONFIG_NM} --no-demangle dummy.o >TMP 2>/dev/null ||
+ ${CONFIG_NM} dummy.o >TMP 2>/dev/null
+ fi
+ # First we look for a pattern that matches historical output from g++.
+ # We surround the actual label name by <> to separate it from
+ # other nm junk.
+ ${SED} -n -e 's/_*vt[$_.]7*filebuf/<&>/p' <TMP >dummy.out
+ # For paranoia's sake (e.g. if we're using some other C++ compiler)
+ # we try a more general pattern, and append the result.
+ grep -v foo <TMP \
+ | ${SED} -n -e 's/[a-zA-Z0-9_.$]*filebuf[a-zA-Z0-9_.$]*/<&>/p' \
+ >>dummy.out
+ # Now we get rid of the <>, and any other junk on the nm output line.
+ # (We get rid of <filebuf> in case nm included debugging output for
+ # class filebuf itself.) Finally, we select the first line of
+ # the result, and hope that's what we wanted!
+ vtab_name=`${SED} -n -e '/<filebuf>/d' -e 's/^.*<\(.*\)>.*$/\1/p' \
+ <dummy.out | ${SED} -n -e '1p'`
+ case "${vtab_name}" in
+ *7filebuf) echo "#define ${macro_prefix}VTABLE_LABEL_HAS_LENGTH 1" ;;
+ *) echo "#define ${macro_prefix}VTABLE_LABEL_HAS_LENGTH 0" ;;
+ esac
+ VTABLE_LABEL_PREFIX=`echo $vtab_name | ${SED} -e 's/7*filebuf//'`
+ fi
+ echo "#define ${macro_prefix}VTABLE_LABEL_PREFIX" '"'"${VTABLE_LABEL_PREFIX}"'"'
+ if [ "${VTABLE_LABEL_PREFIX}" = "__vt_" -o \
+ "${VTABLE_LABEL_PREFIX}" = "___vt_" ] ; then
+ echo "#define ${macro_prefix}USING_THUNKS"
+ fi
+
+ # VTABLE_LABEL_PREFIX_ID is the same as VTABLE_LABEL_PREFIX,
+ # but the former is a C identifier, while the latter is a quoted
+ # st
+ if [ -z ""`echo ${VTABLE_LABEL_PREFIX} | ${SED} -e 's/[a-zA-Z0-9_]//g'` ] ; then
+ if [ "${NAMES_HAVE_UNDERSCORE}" = "1" ] ; then
+ VTABLE_LABEL_PREFIX=`echo ${VTABLE_LABEL_PREFIX} | ${SED} -e 's/^_//'`
+ fi
+ echo "#define ${macro_prefix}VTABLE_LABEL_PREFIX_ID ${VTABLE_LABEL_PREFIX}"
+ fi
+
+# if test -n "${DOLLAR_IN_LABEL}" ; then
+# echo "#define ${macro_prefix}DOLLAR_IN_LABEL ${DOLLAR_IN_LABEL}"
+# elif test "`${CONFIG_NM} dummy.o | grep 'vt[$$]7filebuf'`" != ""; then
+# echo "#define ${macro_prefix}DOLLAR_IN_LABEL 1"
+# elif test "`${CONFIG_NM} dummy.o | grep 'vt[.]7filebuf'`" != ""; then
+# echo "#define ${macro_prefix}DOLLAR_IN_LABEL 0"
+# elif test "`${CONFIG_NM} dummy.o | grep 'vtbl__7filebuf'`" != ""; then
+# echo "#define ${macro_prefix}DOLLAR_IN_LABEL 0"
+# else
+# echo "gen-params: ${CONFIG_NM} failed to find vt[.\$]filebuf in dummy.o!" 1>&2; exit 1
+# fi
+ else
+ # The compile failed for some reason (no C++?)
+ echo "gen-params: could not compile dummy.C with ${CXX}" 1>&2; exit 1;
+ fi
+fi
+
+# A little test program to check if struct stat has st_blksize.
+cat >dummy.c <<!EOF!
+#include <sys/types.h>
+#include <sys/stat.h>
+int BLKSIZE(struct stat *st)
+{
+ return st->st_blksize;
+}
+!EOF!
+
+if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_ST_BLKSIZE 1"
+else
+ echo "#define ${macro_prefix}HAVE_ST_BLKSIZE 0"
+fi
+
+# A little test program to check if the name 'clog' is defined in libm,
+# as it is under DEC UNIX.
+cat >dummy.c <<!EOF!
+int clog;
+main () {}
+!EOF!
+
+if ${CC} dummy.c -lm 2>&1 >/dev/null | grep clog >/dev/null; then
+ echo "#define ${macro_prefix}CLOG_CONFLICT 1"
+fi
+
+echo ""
+
+# Next, generate definitions for the standard types (such as mode_t)
+# compatible with those in the standard C header files.
+# It works by a dummy program through the C pre-processor, and then
+# using sed to search for typedefs in the output.
+
+for hdr in wchar wctype; do
+ eval $hdr=0
+ cat >dummy.c <<EOF
+#include <${hdr}.h>
+EOF
+ if ${CPP} dummy.c >/dev/null 2>&1 ; then eval $hdr=1; fi
+done
+
+cat >dummy.c <<!EOF!
+#include <sys/types.h>
+#include <stddef.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else /* !__STDC__ */
+#include <varargs.h>
+#endif /* __STDC__ */
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#ifdef __STDC__
+#include <limits.h>
+#endif
+#if WCHAR == 1
+#include <wchar.h>
+#endif
+#if WCTYPE == 1
+#include <wctype.h>
+#endif
+#ifdef size_t
+typedef size_t Xsize_t;
+#elif defined(__SIZE_TYPE__)
+typedef __SIZE_TYPE__ Xsize_t;
+#endif
+#ifdef ptrdiff_t
+typedef ptrdiff_t Xptrdiff_t;
+#elif defined(__PTRDIFF_TYPE__)
+typedef __PTRDIFF_TYPE__ Xptrdiff_t;
+#endif
+#ifdef wchar_t
+typedef wchar_t Xwchar_t;
+#elif defined(__WCHAR_TYPE__)
+typedef __WCHAR_TYPE__ Xwchar_t;
+#endif
+#ifdef va_list
+typedef va_list XXXva_list;
+#endif
+#ifdef BUFSIZ
+long XBUFSIZ=BUFSIZ;
+#endif
+#ifdef FOPEN_MAX
+long XFOPEN_MAX=FOPEN_MAX;
+#endif
+#ifdef FILENAME_MAX
+long XFILENAME_MAX=FILENAME_MAX;
+#endif
+#ifdef SHRT_MAX
+long XSHRT_MAX=SHRT_MAX;
+#endif
+#ifdef INT_MAX
+long XINT_MAX=INT_MAX;
+#endif
+#ifdef LONG_MAX
+long XLONG_MAX=LONG_MAX;
+#endif
+#ifdef LONG_LONG_MAX
+long XLONG_LONG_MAX=LONG_LONG_MAX;
+#endif
+!EOF!
+
+if ${CPP} dummy.c -DWCHAR=$wchar -DWCTYPE=$wctype >TMP ; then true
+else
+ echo "gen-params: could not invoke ${CPP} on dummy.c" 1>&2 ; exit 1
+fi
+tr ' ' ' ' <TMP >dummy.out
+
+for TYPE in dev_t clock_t fpos_t gid_t ino_t mode_t nlink_t off_t pid_t ptrdiff_t sigset_t size_t ssize_t time_t uid_t va_list wchar_t wint_t int16_t uint16_t int32_t uint_32_t u_int16_t u_int32_t; do
+ eval IMPORTED=\$$TYPE
+ if [ -n "${IMPORTED}" ] ; then
+ eval "$TYPE='$IMPORTED'"
+ else
+ t=$TYPE
+ VALUE=''
+
+ # Follow `typedef VALUE TYPE' chains, but don't loop indefinitely.
+ for iteration in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
+ # Search dummy.out for a typedef for X*$t.
+ sed_script="
+ s/unsigned long long int/_G_ullong/g
+ s/long long int/_G_llong/g
+ s/unsigned long long/_G_ullong/g
+ s/long long/_G_llong/g
+ /.*typedef *\\(.*[^ ]\\) *X*$t *;.*/{s||\1|;p;q;}
+ /.*typedef *\\(.*[^ a-zA-Z0-9_]\\)X*$t *;.*/{s||\1|;p;q;}
+ "
+ t=`${SED} -n "$sed_script" <dummy.out`
+ case "$t" in
+ '')
+ break;;
+ *)
+ # Found a type $t; save it in VALUE.
+ VALUE=$t
+ # If it won't cause problems in matching,
+ # look for a typedef for it in turn.
+ case "$VALUE" in
+ *.* | */* | *\ * | *\** | *\[* | *\\*) break;;
+ esac;;
+ esac
+ done
+
+ case "$VALUE" in
+ ?*) eval "$TYPE=\"$VALUE\""
+ esac
+ fi
+done
+
+# Look for some standard macros.
+for NAME in BUFSIZ FOPEN_MAX FILENAME_MAX NULL; do
+ eval IMPORTED=\$$NAME
+ if [ -n "${IMPORTED}" ] ; then
+ eval "$NAME='$IMPORTED /* specified */'"
+ else
+ rm -f TMP
+ ${SED} -n -e 's| *;|;|g' -e "s|long X${NAME}= *\(.*\);|\1|w TMP" \
+ <dummy.out>/dev/null
+ # Now select the first definition.
+ if [ -s TMP ]; then
+ eval "$NAME='"`${SED} -e '2,$d' <TMP`"'"
+ fi
+ fi
+done
+
+# These macros must be numerical constants; strip any trailing 'L's.
+for NAME in SHRT_MAX INT_MAX LONG_MAX LONG_LONG_MAX; do
+ eval IMPORTED=\$$NAME
+ if [ -n "${IMPORTED}" ] ; then
+ eval "$NAME='$IMPORTED /* specified */'"
+ else
+ rm -f TMP
+ ${SED} -n -e 's| *;|;|g' -e "s|long X${NAME}= *\([0-9]*\)L* *;|\1|w TMP" \
+ <dummy.out>/dev/null
+ # Now select the first definition.
+ if [ -s TMP ]; then
+ eval "$NAME='"`${SED} -e '2,$d' <TMP`"'"
+ fi
+ fi
+done
+
+# Figure out integral type sizes.
+
+default_int16='short /* deduction failed */'
+default_int32='long /* deduction failed */'
+INT16=32767
+INT32=2147483647
+
+if [ "${SHRT_MAX}" = $INT16 ] ; then
+ default_int16='short /* deduced */'
+ if [ "${LONG_MAX}" = $INT32 ] ; then
+ default_int32='long /* deduced */'
+ elif [ "${INT_MAX}" = $INT32 ] ; then
+ default_int32='int /* deduced */'
+ fi
+fi
+
+[ -n "$u_int16_t" ] && uint16_t="$u_int16_t"
+[ -n "$u_int32_t" ] && uint32_t="$u_int32_t"
+
+[ -z "$int16_t" ] && int16_t="$default_int16"
+[ -z "$uint16_t" ] && uint16_t="unsigned $int16_t"
+[ -z "$int32_t" ] && int32_t="$default_int32"
+[ -z "$uint32_t" ] && uint32_t="unsigned $int32_t"
+
+cat <<!EOF!
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+typedef int ${macro_prefix}int8_t __attribute__((__mode__(__QI__)));
+typedef unsigned int ${macro_prefix}uint8_t __attribute__((__mode__(__QI__)));
+typedef int ${macro_prefix}int16_t __attribute__((__mode__(__HI__)));
+typedef unsigned int ${macro_prefix}uint16_t __attribute__((__mode__(__HI__)));
+typedef int ${macro_prefix}int32_t __attribute__((__mode__(__SI__)));
+typedef unsigned int ${macro_prefix}uint32_t __attribute__((__mode__(__SI__)));
+typedef int ${macro_prefix}int64_t __attribute__((__mode__(__DI__)));
+typedef unsigned int ${macro_prefix}uint64_t __attribute__((__mode__(__DI__)));
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 8
+__extension__ typedef long long ${macro_prefix}llong;
+__extension__ typedef unsigned long long ${macro_prefix}ullong;
+#endif
+#else
+typedef $int16_t ${macro_prefix}int16_t;
+typedef $uint16_t ${macro_prefix}uint16_t;
+typedef $int32_t ${macro_prefix}int32_t;
+typedef $uint32_t ${macro_prefix}uint32_t;
+#endif
+
+typedef ${clock_t-int /* default */} ${macro_prefix}clock_t;
+typedef ${dev_t-int /* default */} ${macro_prefix}dev_t;
+typedef ${fpos_t-long /* default */} ${macro_prefix}fpos_t;
+typedef ${gid_t-int /* default */} ${macro_prefix}gid_t;
+typedef ${ino_t-int /* default */} ${macro_prefix}ino_t;
+typedef ${mode_t-int /* default */} ${macro_prefix}mode_t;
+typedef ${nlink_t-int /* default */} ${macro_prefix}nlink_t;
+typedef ${off_t-long /* default */} ${macro_prefix}off_t;
+typedef ${pid_t-int /* default */} ${macro_prefix}pid_t;
+#ifndef __PTRDIFF_TYPE__
+#define __PTRDIFF_TYPE__ ${ptrdiff_t-long int /* default */}
+#endif
+typedef __PTRDIFF_TYPE__ ${macro_prefix}ptrdiff_t;
+typedef ${sigset_t-int /* default */} ${macro_prefix}sigset_t;
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ ${size_t-unsigned long /* default */}
+#endif
+typedef __SIZE_TYPE__ ${macro_prefix}size_t;
+typedef ${time_t-int /* default */} ${macro_prefix}time_t;
+typedef ${uid_t-int /* default */} ${macro_prefix}uid_t;
+typedef ${wchar_t-int /* default */} ${macro_prefix}wchar_t;
+
+#define ${macro_prefix}BUFSIZ ${BUFSIZ-1024 /* default */}
+#define ${macro_prefix}FOPEN_MAX ${FOPEN_MAX-32 /* default */}
+#define ${macro_prefix}FILENAME_MAX ${FILENAME_MAX-1024 /* default */}
+#if defined (__cplusplus) || defined (__STDC__)
+#define ${macro_prefix}ARGS(ARGLIST) ARGLIST
+#else
+#define ${macro_prefix}ARGS(ARGLIST) ()
+#endif
+#if !defined (__GNUG__) || defined (__STRICT_ANSI__)
+#define ${macro_prefix}NO_NRV
+#endif
+#if !defined (__GNUG__)
+#define _G_NO_EXTERN_TEMPLATES
+#endif
+!EOF!
+
+# ssize_t is the signed version of size_t
+if [ -n "${ssize_t}" ] ; then
+ echo "typedef ${ssize_t} ${macro_prefix}ssize_t;"
+elif [ -z "${size_t}" ] ; then
+ echo "typedef long ${macro_prefix}ssize_t;"
+else
+ # Remove "unsigned" from ${size_t} to get ${ssize_t}.
+ tmp="`echo ${size_t} | ${SED} -e 's|unsigned||g' -e 's| | |g'`"
+ if [ -z "$tmp" ] ; then
+ tmp=int
+ else
+ # check $tmp doesn't conflict with <unistd.h>
+ echo "#include <unistd.h>
+ extern $tmp read();" >dummy.c
+ ${CC} -c dummy.c >/dev/null 2>&1 || tmp=int
+ fi
+ echo "typedef $tmp /* default */ ${macro_prefix}ssize_t;"
+fi
+
+# wint_t is often the integral type to which wchar_t promotes.
+if [ -z "${wint_t}" ] ; then
+ for TYPE in int 'unsigned int' 'long int' 'long unsigned int'; do
+ cat >dummy.C <<!EOF!
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ ${wchar_t-int /* default */}
+#endif
+typedef __WCHAR_TYPE__ ${macro_prefix}wchar_t;
+void foo ($TYPE);
+void foo (double);
+void bar (${macro_prefix}wchar_t w)
+{
+ foo (w);
+}
+!EOF!
+ if ${CXX} -c dummy.C >/dev/null 2>&1 ; then
+ wint_t="$TYPE /* default */"
+ break
+ fi
+ done
+fi
+echo "typedef ${wint_t-int /* wchar_t is broken */} ${macro_prefix}wint_t;"
+
+# va_list can cause problems (e.g. some systems have va_list as a struct).
+# Check to see if ${va_list-char*} really is compatible with stdarg.h.
+cat >dummy.C <<!EOF!
+#define X_va_list ${va_list-char* /* default */}
+extern long foo(X_va_list ap); /* Check that X_va_list compiles on its own */
+extern "C" {
+#include <stdarg.h>
+}
+long foo(X_va_list ap) { return va_arg(ap, long); }
+long bar(int i, ...)
+{ va_list ap; long j; va_start(ap, i); j = foo(ap); va_end(ap); return j; }
+!EOF!
+if ${CXX} -c dummy.C >/dev/null 2>&1 ; then
+ # Ok: We have something that works.
+ echo "typedef ${va_list-char* /* default */} ${macro_prefix}va_list;"
+else
+ echo "#define ${macro_prefix}NEED_STDARG_H"
+ # Check and see if we have __gnuc_va_list, as we might set up define
+ # loops if we use va_list.
+ cat >dummy.C <<!EOF!
+#include <stdarg.h>
+long foo(__gnuc_va_list ap) { return va_arg(ap, long); }
+!EOF!
+ if ${CXX} -c dummy.C >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}va_list __gnuc_va_list"
+ else
+ echo "#define ${macro_prefix}va_list va_list"
+ fi
+fi
+
+cat >dummy.c <<!EOF!
+#include <signal.h>
+extern int (*signal())();
+extern int dummy (int);
+main()
+{
+ int (*oldsig)(int) = signal (1, dummy);
+ (void) signal (2, oldsig);
+ return 0;
+}
+!EOF!
+if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}signal_return_type int"
+else
+ echo "#define ${macro_prefix}signal_return_type void"
+fi
+
+# check sprintf return type
+
+cat >dummy.c <<!EOF!
+#include <stdio.h>
+extern int sprintf(); char buf[100];
+int main() { return sprintf(buf, "%d", 34); }
+!EOF!
+if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}sprintf_return_type int"
+else
+ echo "#define ${macro_prefix}sprintf_return_type char*"
+fi
+
+if test -n "${HAVE_ATEXIT}" ; then
+ echo "#define ${macro_prefix}HAVE_ATEXIT ${HAVE_ATEXIT}"
+else
+ cat >dummy.c <<!EOF!
+#include <stdlib.h>
+int main()
+{
+ atexit (0);
+}
+!EOF!
+ if ${CC} dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_ATEXIT 1"
+ else
+ echo "#define ${macro_prefix}HAVE_ATEXIT 0"
+ fi
+fi
+
+
+# *** Check for presence of certain include files ***
+
+# check for sys/resource.h
+
+if test -n "${HAVE_SYS_RESOURCE}" ; then
+ echo "#define ${macro_prefix}HAVE_SYS_RESOURCE ${HAVE_SYS_RESOURCE}"
+else
+ cat >dummy.c <<!EOF!
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+ int main()
+ {
+ struct rusage res;
+ getrusage(RUSAGE_SELF, &res);
+ return (int)(res.ru_utime.tv_sec + (res.ru_utime.tv_usec / 1000000.0));
+ }
+!EOF!
+ # Note: We link because some systems have sys/resource, but not getrusage().
+ if ${CC} dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_SYS_RESOURCE 1"
+ else
+ echo "#define ${macro_prefix}HAVE_SYS_RESOURCE 0"
+ fi
+fi
+
+# check for struct tms in sys/times.h
+
+if test -n "${HAVE_SYS_TIMES}" ; then
+ echo "#define ${macro_prefix}HAVE_SYS_TIMES ${HAVE_SYS_TIMES}"
+else
+ cat >dummy.c <<!EOF!
+#include <sys/types.h>
+#include <sys/times.h>
+ int main()
+ {
+ struct tms s;
+ return s.tms_utime;
+ }
+!EOF!
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_SYS_TIMES 1"
+ else
+ echo "#define ${macro_prefix}HAVE_SYS_TIMES 0"
+ fi
+fi
+
+# check for sys/socket.h
+
+if test -n "${HAVE_SYS_SOCKET}" ; then
+ echo "#define ${macro_prefix}HAVE_SYS_SOCKET ${HAVE_SYS_SOCKET}"
+else
+ echo '#include <sys/types.h>' >dummy.c
+ echo '#include <sys/socket.h>' >>dummy.c
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_SYS_SOCKET 1"
+ else
+ echo "#define ${macro_prefix}HAVE_SYS_SOCKET 0"
+ fi
+fi
+
+# check for sys/cdefs.h
+
+if test -n "${HAVE_SYS_CDEFS}" ; then
+ echo "#define ${macro_prefix}HAVE_SYS_CDEFS ${HAVE_SYS_CDEFS}"
+else
+ echo '#include <sys/cdefs.h>' >dummy.c
+ echo 'extern int myfunc __P((int, int));' >>dummy.c
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_SYS_CDEFS 1"
+ else
+ echo "#define ${macro_prefix}HAVE_SYS_CDEFS 0"
+ fi
+fi
+
+# Check for a (Posix-compatible) sys/wait.h */
+
+if test -n "${HAVE_SYS_WAIT}" ; then
+ echo "#define ${macro_prefix}HAVE_SYS_WAIT ${HAVE_SYS_WAIT}"
+else
+ cat >dummy.c <<!EOF!
+#include <sys/types.h>
+#include <sys/wait.h>
+ int f() { int i; wait(&i); return i; }
+!EOF!
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_SYS_WAIT 1"
+ else
+ echo "#define ${macro_prefix}HAVE_SYS_WAIT 0"
+ fi
+fi
+
+if test -n "${HAVE_UNISTD}" ; then
+ echo "#define ${macro_prefix}HAVE_UNISTD ${HAVE_UNISTD}"
+else
+ echo '#include <unistd.h>' >dummy.c
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_UNISTD 1"
+ else
+ echo "#define ${macro_prefix}HAVE_UNISTD 0"
+ fi
+fi
+
+if test -n "${HAVE_DIRENT}" ; then
+ echo "#define ${macro_prefix}HAVE_DIRENT ${HAVE_DIRENT}"
+else
+ echo '#include <sys/types.h>
+#include <dirent.h>' >dummy.c
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_DIRENT 1"
+ else
+ echo "#define ${macro_prefix}HAVE_DIRENT 0"
+ fi
+fi
+
+if test -n "${HAVE_CURSES}" ; then
+ echo "#define ${macro_prefix}HAVE_CURSES ${HAVE_CURSES}"
+else
+ echo '#include <curses.h>' >dummy.c
+ if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_CURSES 1"
+ else
+ echo "#define ${macro_prefix}HAVE_CURSES 0"
+ fi
+fi
+
+# There is no test for this at the moment; it is just set by the
+# configuration files.
+if test -n "${MATH_H_INLINES}" ; then
+ echo "#define ${macro_prefix}MATH_H_INLINES ${MATH_H_INLINES}"
+else
+ echo "#define ${macro_prefix}MATH_H_INLINES 0"
+fi
+
+if test -n "${HAVE_BOOL}" ; then
+ echo "#define ${macro_prefix}HAVE_BOOL ${HAVE_BOOL}"
+else
+ echo 'bool i=true,j=false;' >dummy.C
+ if ${CXX} -c dummy.C >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_BOOL 1"
+ else
+ echo "#define ${macro_prefix}HAVE_BOOL 0"
+ fi
+fi
+
+if test -n "${NO_USE_DTOA}" ; then
+ echo "#define ${macro_prefix}NO_USE_DTOA 1"
+fi
+if test -n "${USE_INT32_FLAGS}" ; then
+ echo "#define ${macro_prefix}USE_INT32_FLAGS 1"
+fi
+
+# A little test program to check if __printf_fp is available.
+cat >dummy.c <<EOF
+int main()
+{
+ return __printf_fp ();
+}
+EOF
+
+if ${CC} dummy.c >/dev/null 2>&1 ; then
+ echo "#define ${macro_prefix}HAVE_PRINTF_FP 1"
+ echo "#define ${macro_prefix}HAVE_LONG_DOUBLE_IO 1"
+else
+ echo "#define ${macro_prefix}HAVE_PRINTF_FP 0"
+ echo "#define ${macro_prefix}HAVE_LONG_DOUBLE_IO 0"
+fi
+
+# Uncomment the following line if you don't have working templates.
+# echo "#define ${macro_prefix}NO_TEMPLATES"
+
+# Override bogus definitions of NULL in system headers.
+cat <<EOF
+#undef NULL
+#define __need_NULL
+#include <stddef.h>
+EOF
+
+rm -f dummy.C dummy.o dummy.c dummy.out TMP core a.out
+
+echo "#endif /* !${macro_prefix}config_h */"
diff --git a/gnu/dist/libio/genops.c b/gnu/dist/libio/genops.c
new file mode 100644
index 00000000000..de9c826b9fe
--- /dev/null
+++ b/gnu/dist/libio/genops.c
@@ -0,0 +1,944 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* Generic or default I/O operations. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+void
+_IO_un_link (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_flags & _IO_LINKED)
+ {
+ _IO_FILE **f;
+ for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
+ {
+ if (*f == fp)
+ {
+ *f = fp->_chain;
+ break;
+ }
+ }
+ fp->_flags &= ~_IO_LINKED;
+ }
+}
+
+void
+_IO_link_in (fp)
+ _IO_FILE *fp;
+{
+ if ((fp->_flags & _IO_LINKED) == 0)
+ {
+ fp->_flags |= _IO_LINKED;
+ fp->_chain = _IO_list_all;
+ _IO_list_all = fp;
+ }
+}
+
+/* Return minimum _pos markers
+ Assumes the current get area is the main get area. */
+static _IO_size_t _IO_least_marker __P ((_IO_FILE *fp));
+
+static _IO_size_t
+_IO_least_marker (fp)
+ _IO_FILE *fp;
+{
+ _IO_ssize_t least_so_far = fp->_IO_read_end - fp->_IO_read_base;
+ struct _IO_marker *mark;
+ for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+ if (mark->_pos < least_so_far)
+ least_so_far = mark->_pos;
+ return least_so_far;
+}
+
+/* Switch current get area from backup buffer to (start of) main get area. */
+
+void
+_IO_switch_to_main_get_area (fp)
+ _IO_FILE *fp;
+{
+ char *tmp;
+ fp->_flags &= ~_IO_IN_BACKUP;
+ /* Swap _IO_read_end and _IO_save_end. */
+ tmp = fp->_IO_read_end;
+ fp->_IO_read_end = fp->_IO_save_end;
+ fp->_IO_save_end= tmp;
+ /* Swap _IO_read_base and _IO_save_base. */
+ tmp = fp->_IO_read_base;
+ fp->_IO_read_base = fp->_IO_save_base;
+ fp->_IO_save_base = tmp;
+
+ fp->_IO_read_ptr = fp->_IO_read_base;
+}
+
+/* Switch current get area from main get area to (end of) backup area. */
+
+void
+_IO_switch_to_backup_area (fp)
+ _IO_FILE *fp;
+{
+ char *tmp;
+ fp->_flags |= _IO_IN_BACKUP;
+ /* Swap _IO_read_end and _IO_save_end. */
+ tmp = fp->_IO_read_end;
+ fp->_IO_read_end = fp->_IO_save_end;
+ fp->_IO_save_end = tmp;
+ /* Swap _gbase and _IO_save_base. */
+ tmp = fp->_IO_read_base;
+ fp->_IO_read_base = fp->_IO_save_base;
+ fp->_IO_save_base = tmp;
+
+ fp->_IO_read_ptr = fp->_IO_read_end;
+}
+
+int
+_IO_switch_to_get_mode (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ if (_IO_OVERFLOW (fp, EOF) == EOF)
+ return EOF;
+ if (_IO_in_backup (fp))
+ fp->_IO_read_base = fp->_IO_backup_base;
+ else
+ {
+ fp->_IO_read_base = fp->_IO_buf_base;
+ if (fp->_IO_write_ptr > fp->_IO_read_end)
+ fp->_IO_read_end = fp->_IO_write_ptr;
+ }
+ fp->_IO_read_ptr = fp->_IO_write_ptr;
+
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
+
+ fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ return 0;
+}
+
+void
+_IO_free_backup_area (fp)
+ _IO_FILE *fp;
+{
+ if (_IO_in_backup (fp))
+ _IO_switch_to_main_get_area (fp); /* Just in case. */
+ free (fp->_IO_save_base);
+ fp->_IO_save_base = NULL;
+ fp->_IO_save_end = NULL;
+ fp->_IO_backup_base = NULL;
+}
+
+#if 0
+int
+_IO_switch_to_put_mode (fp)
+ _IO_FILE *fp;
+{
+ fp->_IO_write_base = fp->_IO_read_ptr;
+ fp->_IO_write_ptr = fp->_IO_read_ptr;
+ /* Following is wrong if line- or un-buffered? */
+ fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
+ ? fp->_IO_read_end : fp->_IO_buf_end);
+
+ fp->_IO_read_ptr = fp->_IO_read_end;
+ fp->_IO_read_base = fp->_IO_read_end;
+
+ fp->_flags |= _IO_CURRENTLY_PUTTING;
+ return 0;
+}
+#endif
+
+int
+__overflow (f, ch)
+ _IO_FILE *f;
+ int ch;
+{
+ return _IO_OVERFLOW (f, ch);
+}
+
+static int save_for_backup __P ((_IO_FILE *fp));
+
+ static int
+save_for_backup (fp)
+ _IO_FILE *fp;
+{
+ /* Append [_IO_read_base.._IO_read_end] to backup area. */
+ int least_mark = _IO_least_marker (fp);
+ /* needed_size is how much space we need in the backup area. */
+ int needed_size = (fp->_IO_read_end - fp->_IO_read_base) - least_mark;
+ int current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
+ int avail; /* Extra space available for future expansion. */
+ int delta;
+ struct _IO_marker *mark;
+ if (needed_size > current_Bsize)
+ {
+ char *new_buffer;
+ avail = 100;
+ new_buffer = (char *) malloc (avail + needed_size);
+ if (new_buffer == NULL)
+ return EOF; /* FIXME */
+ if (least_mark < 0)
+ {
+ memcpy (new_buffer + avail,
+ fp->_IO_save_end + least_mark,
+ -least_mark);
+ memcpy (new_buffer + avail - least_mark,
+ fp->_IO_read_base,
+ fp->_IO_read_end - fp->_IO_read_base);
+ }
+ else
+ memcpy (new_buffer + avail,
+ fp->_IO_read_base + least_mark,
+ needed_size);
+ if (fp->_IO_save_base)
+ free (fp->_IO_save_base);
+ fp->_IO_save_base = new_buffer;
+ fp->_IO_save_end = new_buffer + avail + needed_size;
+ }
+ else
+ {
+ avail = current_Bsize - needed_size;
+ if (least_mark < 0)
+ {
+ memmove (fp->_IO_save_base + avail,
+ fp->_IO_save_end + least_mark,
+ -least_mark);
+ memcpy (fp->_IO_save_base + avail - least_mark,
+ fp->_IO_read_base,
+ fp->_IO_read_end - fp->_IO_read_base);
+ }
+ else if (needed_size > 0)
+ memcpy (fp->_IO_save_base + avail,
+ fp->_IO_read_base + least_mark,
+ needed_size);
+ }
+ /* FIXME: Dubious arithmetic if pointers are NULL */
+ fp->_IO_backup_base = fp->_IO_save_base + avail;
+ /* Adjust all the streammarkers. */
+ delta = fp->_IO_read_end - fp->_IO_read_base;
+ for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+ mark->_pos -= delta;
+ return 0;
+}
+
+int
+__underflow (fp)
+ _IO_FILE *fp;
+{
+ if (_IO_in_put_mode (fp))
+ if (_IO_switch_to_get_mode (fp) == EOF)
+ return EOF;
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *(unsigned char *) fp->_IO_read_ptr;
+ if (_IO_in_backup (fp))
+ {
+ _IO_switch_to_main_get_area (fp);
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *fp->_IO_read_ptr;
+ }
+ if (_IO_have_markers (fp))
+ {
+ if (save_for_backup (fp))
+ return EOF;
+ }
+ else if (_IO_have_backup (fp))
+ _IO_free_backup_area (fp);
+ return _IO_UNDERFLOW (fp);
+}
+
+int
+__uflow (fp)
+ _IO_FILE *fp;
+{
+ if (_IO_in_put_mode (fp))
+ if (_IO_switch_to_get_mode (fp) == EOF)
+ return EOF;
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *(unsigned char *) fp->_IO_read_ptr++;
+ if (_IO_in_backup (fp))
+ {
+ _IO_switch_to_main_get_area (fp);
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *fp->_IO_read_ptr++;
+ }
+ if (_IO_have_markers (fp))
+ {
+ if (save_for_backup (fp))
+ return EOF;
+ }
+ else if (_IO_have_backup (fp))
+ _IO_free_backup_area (fp);
+ return _IO_UFLOW (fp);
+}
+
+void
+_IO_setb (f, b, eb, a)
+ _IO_FILE *f;
+ char *b;
+ char *eb;
+ int a;
+{
+ if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
+ FREE_BUF (f->_IO_buf_base, _IO_blen (f));
+ f->_IO_buf_base = b;
+ f->_IO_buf_end = eb;
+ if (a)
+ f->_flags &= ~_IO_USER_BUF;
+ else
+ f->_flags |= _IO_USER_BUF;
+}
+
+void
+_IO_doallocbuf (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_IO_buf_base)
+ return;
+ if (!(fp->_flags & _IO_UNBUFFERED))
+ if (_IO_DOALLOCATE (fp) != EOF)
+ return;
+ _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
+}
+
+int
+_IO_default_underflow (fp)
+ _IO_FILE *fp;
+{
+ return EOF;
+}
+
+int
+_IO_default_uflow (fp)
+ _IO_FILE *fp;
+{
+ int ch = _IO_UNDERFLOW (fp);
+ if (ch == EOF)
+ return EOF;
+ return *(unsigned char *) fp->_IO_read_ptr++;
+}
+
+_IO_size_t
+_IO_default_xsputn (f, data, n)
+ _IO_FILE *f;
+ const void *data;
+ _IO_size_t n;
+{
+ const char *s = (char *) data;
+ _IO_size_t more = n;
+ if (more <= 0)
+ return 0;
+ for (;;)
+ {
+ /* Space available. */
+ _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
+ if (count > 0)
+ {
+ if ((_IO_size_t) count > more)
+ count = more;
+ if (count > 20)
+ {
+ memcpy (f->_IO_write_ptr, s, count);
+ s += count;
+ f->_IO_write_ptr += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else
+ {
+ char *p = f->_IO_write_ptr;
+ _IO_ssize_t i;
+ for (i = count; --i >= 0; )
+ *p++ = *s++;
+ f->_IO_write_ptr = p;
+ }
+ more -= count;
+ }
+ if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
+ break;
+ more--;
+ }
+ return n - more;
+}
+
+_IO_size_t
+_IO_sgetn (fp, data, n)
+ _IO_FILE *fp;
+ void *data;
+ _IO_size_t n;
+{
+ /* FIXME handle putback buffer here! */
+ return _IO_XSGETN (fp, data, n);
+}
+
+_IO_size_t
+_IO_default_xsgetn (fp, data, n)
+ _IO_FILE *fp;
+ void *data;
+ _IO_size_t n;
+{
+ _IO_size_t more = n;
+ char *s = (char*) data;
+ for (;;)
+ {
+ /* Data available. */
+ _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (count > 0)
+ {
+ if ((_IO_size_t) count > more)
+ count = more;
+ if (count > 20)
+ {
+ memcpy (s, fp->_IO_read_ptr, count);
+ s += count;
+ fp->_IO_read_ptr += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else
+ {
+ char *p = fp->_IO_read_ptr;
+ int i = (int) count;
+ while (--i >= 0)
+ *s++ = *p++;
+ fp->_IO_read_ptr = p;
+ }
+ more -= count;
+ }
+ if (more == 0 || __underflow (fp) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+#if 0
+/* Seems not to be needed. --drepper */
+int
+_IO_sync (fp)
+ _IO_FILE *fp;
+{
+ return 0;
+}
+#endif
+
+_IO_FILE *
+_IO_default_setbuf (fp, p, len)
+ _IO_FILE *fp;
+ char *p;
+ _IO_ssize_t len;
+{
+ if (_IO_SYNC (fp) == EOF)
+ return NULL;
+ if (p == NULL || len == 0)
+ {
+ fp->_flags |= _IO_UNBUFFERED;
+ _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
+ }
+ else
+ {
+ fp->_flags &= ~_IO_UNBUFFERED;
+ _IO_setb (fp, p, p+len, 0);
+ }
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
+ return fp;
+}
+
+_IO_pos_t
+_IO_default_seekpos (fp, pos, mode)
+ _IO_FILE *fp;
+ _IO_pos_t pos;
+ int mode;
+{
+ return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
+}
+
+int
+_IO_default_doallocate (fp)
+ _IO_FILE *fp;
+{
+ char *buf;
+
+ ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
+ _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
+ return 1;
+}
+
+void
+_IO_init (fp, flags)
+ _IO_FILE *fp;
+ int flags;
+{
+ fp->_flags = _IO_MAGIC|flags;
+ fp->_IO_buf_base = NULL;
+ fp->_IO_buf_end = NULL;
+ fp->_IO_read_base = NULL;
+ fp->_IO_read_ptr = NULL;
+ fp->_IO_read_end = NULL;
+ fp->_IO_write_base = NULL;
+ fp->_IO_write_ptr = NULL;
+ fp->_IO_write_end = NULL;
+ fp->_chain = NULL; /* Not necessary. */
+
+ fp->_IO_save_base = NULL;
+ fp->_IO_backup_base = NULL;
+ fp->_IO_save_end = NULL;
+ fp->_markers = NULL;
+ fp->_cur_column = 0;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_init (*fp->_lock);
+#endif
+}
+
+int
+_IO_default_sync (fp)
+ _IO_FILE *fp;
+{
+ return 0;
+}
+
+/* The way the C++ classes are mapped into the C functions in the
+ current implementation, this function can get called twice! */
+
+void
+_IO_default_finish (fp, dummy)
+ _IO_FILE *fp;
+ int dummy;
+{
+ struct _IO_marker *mark;
+ if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+ {
+ FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
+ fp->_IO_buf_base = fp->_IO_buf_end = NULL;
+ }
+
+ for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+ mark->_sbuf = NULL;
+
+ if (fp->_IO_save_base)
+ {
+ free (fp->_IO_save_base);
+ fp->_IO_save_base = NULL;
+ }
+
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_fini (*fp->_lock);
+#endif
+
+ _IO_un_link (fp);
+}
+
+_IO_pos_t
+_IO_default_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+ int mode;
+{
+ return _IO_pos_BAD;
+}
+
+int
+_IO_sputbackc (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ int result;
+
+ if (fp->_IO_read_ptr > fp->_IO_read_base
+ && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
+ {
+ fp->_IO_read_ptr--;
+ result = (unsigned char) c;
+ }
+ else
+ result = _IO_PBACKFAIL (fp, c);
+
+ if (result != EOF)
+ fp->_flags &= ~_IO_EOF_SEEN;
+
+ return result;
+}
+
+int
+_IO_sungetc (fp)
+ _IO_FILE *fp;
+{
+ int result;
+
+ if (fp->_IO_read_ptr > fp->_IO_read_base)
+ {
+ fp->_IO_read_ptr--;
+ result = (unsigned char) *fp->_IO_read_ptr;
+ }
+ else
+ result = _IO_PBACKFAIL (fp, EOF);
+
+ if (result != EOF)
+ fp->_flags &= ~_IO_EOF_SEEN;
+
+ return result;
+}
+
+#if 0 /* Work in progress */
+/* Seems not to be needed. */
+#if 0
+void
+_IO_set_column (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ if (c == -1)
+ fp->_column = -1;
+ else
+ fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
+}
+#else
+int
+_IO_set_column (fp, i)
+ _IO_FILE *fp;
+ int i;
+{
+ fp->_cur_column = i + 1;
+ return 0;
+}
+#endif
+#endif
+
+
+unsigned
+_IO_adjust_column (start, line, count)
+ unsigned start;
+ const char *line;
+ int count;
+{
+ const char *ptr = line + count;
+ while (ptr > line)
+ if (*--ptr == '\n')
+ return line + count - ptr - 1;
+ return start + count;
+}
+
+#if 0
+/* Seems not to be needed. --drepper */
+int
+_IO_get_column (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_cur_column)
+ return _IO_adjust_column (fp->_cur_column - 1,
+ fp->_IO_write_base,
+ fp->_IO_write_ptr - fp->_IO_write_base);
+ return -1;
+}
+#endif
+
+int
+_IO_flush_all ()
+{
+ int result = 0;
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if (fp->_IO_write_ptr > fp->_IO_write_base
+ && _IO_OVERFLOW (fp, EOF) == EOF)
+ result = EOF;
+ return result;
+}
+
+void
+_IO_flush_all_linebuffered ()
+{
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
+ _IO_OVERFLOW (fp, EOF);
+}
+
+static void _IO_unbuffer_all __P ((void));
+
+static void
+_IO_unbuffer_all ()
+{
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if (! (fp->_flags & _IO_UNBUFFERED))
+ _IO_SETBUF (fp, NULL, 0);
+}
+
+void
+_IO_cleanup ()
+{
+ _IO_flush_all ();
+
+ /* We currently don't have a reliable mechanism for making sure that
+ C++ static destructors are executed in the correct order.
+ So it is possible that other static destructors might want to
+ write to cout - and they're supposed to be able to do so.
+
+ The following will make the standard streambufs be unbuffered,
+ which forces any output from late destructors to be written out. */
+ _IO_unbuffer_all ();
+}
+
+void
+_IO_init_marker (marker, fp)
+ struct _IO_marker *marker;
+ _IO_FILE *fp;
+{
+ marker->_sbuf = fp;
+ if (_IO_in_put_mode (fp))
+ _IO_switch_to_get_mode (fp);
+ if (_IO_in_backup (fp))
+ marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
+ else
+ marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
+
+ /* Should perhaps sort the chain? */
+ marker->_next = fp->_markers;
+ fp->_markers = marker;
+}
+
+void
+_IO_remove_marker (marker)
+ struct _IO_marker *marker;
+{
+ /* Unlink from sb's chain. */
+ struct _IO_marker **ptr = &marker->_sbuf->_markers;
+ for (; ; ptr = &(*ptr)->_next)
+ {
+ if (*ptr == NULL)
+ break;
+ else if (*ptr == marker)
+ {
+ *ptr = marker->_next;
+ return;
+ }
+ }
+#if 0
+ if _sbuf has a backup area that is no longer needed, should we delete
+ it now, or wait until the next underflow?
+#endif
+}
+
+#define BAD_DELTA EOF
+
+int
+_IO_marker_difference (mark1, mark2)
+ struct _IO_marker *mark1;
+ struct _IO_marker *mark2;
+{
+ return mark1->_pos - mark2->_pos;
+}
+
+/* Return difference between MARK and current position of MARK's stream. */
+int
+_IO_marker_delta (mark)
+ struct _IO_marker *mark;
+{
+ int cur_pos;
+ if (mark->_sbuf == NULL)
+ return BAD_DELTA;
+ if (_IO_in_backup (mark->_sbuf))
+ cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
+ else
+ cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
+ return mark->_pos - cur_pos;
+}
+
+int
+_IO_seekmark (fp, mark, delta)
+ _IO_FILE *fp;
+ struct _IO_marker *mark;
+ int delta;
+{
+ if (mark->_sbuf != fp)
+ return EOF;
+ if (mark->_pos >= 0)
+ {
+ if (_IO_in_backup (fp))
+ _IO_switch_to_main_get_area (fp);
+ fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
+ }
+ else
+ {
+ if (!_IO_in_backup (fp))
+ _IO_switch_to_backup_area (fp);
+ fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
+ }
+ return 0;
+}
+
+void
+_IO_unsave_markers (fp)
+ _IO_FILE *fp;
+{
+ struct _IO_marker *mark = fp->_markers;
+ if (mark)
+ {
+#ifdef TODO
+ streampos offset = seekoff (0, ios::cur, ios::in);
+ if (offset != EOF)
+ {
+ offset += eGptr () - Gbase ();
+ for ( ; mark != NULL; mark = mark->_next)
+ mark->set_streampos (mark->_pos + offset);
+ }
+ else
+ {
+ for ( ; mark != NULL; mark = mark->_next)
+ mark->set_streampos (EOF);
+ }
+#endif
+ fp->_markers = 0;
+ }
+
+ if (_IO_have_backup (fp))
+ _IO_free_backup_area (fp);
+}
+
+#if 0
+/* Seems not to be needed. --drepper */
+int
+_IO_nobackup_pbackfail (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ if (fp->_IO_read_ptr > fp->_IO_read_base)
+ fp->_IO_read_ptr--;
+ if (c != EOF && *fp->_IO_read_ptr != c)
+ *fp->_IO_read_ptr = c;
+ return (unsigned char) c;
+}
+#endif
+
+int
+_IO_default_pbackfail (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ if (fp->_IO_read_ptr <= fp->_IO_read_base)
+ {
+ /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
+ if (_IO_have_backup (fp) && !_IO_in_backup (fp))
+ _IO_switch_to_backup_area (fp);
+
+ if (!_IO_have_backup (fp))
+ {
+ /* No backup buffer: allocate one. */
+ /* Use nshort buffer, if unused? (probably not) FIXME */
+ int backup_size = 128;
+ char *bbuf = (char *) malloc (backup_size);
+ if (bbuf == NULL)
+ return EOF;
+ fp->_IO_save_base = bbuf;
+ fp->_IO_save_end = fp->_IO_save_base + backup_size;
+ fp->_IO_backup_base = fp->_IO_save_end;
+ _IO_switch_to_backup_area (fp);
+ }
+ else if (fp->_IO_read_ptr <= fp->_IO_read_base)
+ {
+ /* Increase size of existing backup buffer. */
+ _IO_size_t new_size;
+ _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
+ char *new_buf;
+ new_size = 2 * old_size;
+ new_buf = (char *) malloc (new_size);
+ if (new_buf == NULL)
+ return EOF;
+ memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
+ old_size);
+ free (fp->_IO_read_base);
+ _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
+ new_buf + new_size);
+ fp->_IO_backup_base = fp->_IO_read_ptr;
+ }
+ }
+ --fp->_IO_read_ptr;
+ if (c != EOF && *fp->_IO_read_ptr != c)
+ *fp->_IO_read_ptr = c;
+ return (unsigned char) *fp->_IO_read_ptr;
+}
+
+_IO_pos_t
+_IO_default_seek (fp, offset, dir)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+{
+ return _IO_pos_BAD;
+}
+
+int
+_IO_default_stat (fp, st)
+ _IO_FILE *fp;
+ void* st;
+{
+ return EOF;
+}
+
+_IO_ssize_t
+_IO_default_read (fp, data, n)
+ _IO_FILE* fp;
+ void *data;
+ _IO_ssize_t n;
+{
+ return -1;
+}
+
+_IO_ssize_t
+_IO_default_write (fp, data, n)
+ _IO_FILE *fp;
+ const void *data;
+ _IO_ssize_t n;
+{
+ return 0;
+}
+
+
+#ifdef TODO
+#if defined(linux)
+#define IO_CLEANUP ;
+#endif
+
+#ifdef IO_CLEANUP
+ IO_CLEANUP
+#else
+struct __io_defs {
+ __io_defs() { }
+ ~__io_defs() { _IO_cleanup (); }
+};
+__io_defs io_defs__;
+#endif
+
+#endif /* TODO */
+
+#ifdef weak_alias
+weak_alias (_IO_cleanup, _cleanup)
+#endif
+
+#ifdef text_set_element
+text_set_element(__libc_atexit, _cleanup);
+#endif
diff --git a/gnu/dist/libio/include/empty.h b/gnu/dist/libio/include/empty.h
new file mode 100644
index 00000000000..dcbf758df9c
--- /dev/null
+++ b/gnu/dist/libio/include/empty.h
@@ -0,0 +1,37 @@
+/* Thread package specific definitions of stream lock type.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#ifndef _LIBIO_LOCK_H
+#define _LIBIO_LOCK_H 1
+
+typedef void *_IO_lock_t;
+
+/* We need recursive (counting) mutexes. */
+#define _IO_lock_initializer NULL
+
+
+#define _IO_cleanup_region_start(_fct, _fp)
+#define _IO_cleanup_region_end(_doit)
+#define _IO_lock_init(_name)
+#define _IO_lock_fini(_name)
+#define _IO_lock_lock(_name)
+#define _IO_lock_unlock(_name)
+
+#endif /* libio-lock.h */
+/* this will be used later*/
diff --git a/gnu/dist/libio/indstream.cc b/gnu/dist/libio/indstream.cc
new file mode 100644
index 00000000000..15a1bb2778d
--- /dev/null
+++ b/gnu/dist/libio/indstream.cc
@@ -0,0 +1,121 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <indstream.h>
+
+indirectbuf::indirectbuf(streambuf *get, streambuf *put, int delete_mode)
+: streambuf()
+{
+ _get_stream = get;
+ _put_stream = put == NULL ? get : put;
+ _delete_flags = delete_mode;
+}
+
+indirectbuf::~indirectbuf()
+{
+ if (_delete_flags & ios::in) delete get_stream();
+ if (_delete_flags & ios::out) delete put_stream();
+}
+
+streamsize indirectbuf::xsputn(const char* s, streamsize n)
+{
+ return put_stream()->sputn(s, n);
+}
+
+streamsize indirectbuf::xsgetn(char* s, streamsize n)
+{
+ return get_stream()->sgetn(s, n);
+}
+
+int indirectbuf::overflow(int c /* = EOF */)
+{
+ if (c == EOF)
+ return put_stream()->overflow(c);
+ else
+ return put_stream()->sputc(c);
+}
+
+int indirectbuf::underflow()
+{
+ return get_stream()->sgetc();
+}
+
+int indirectbuf::uflow()
+{
+ return get_stream()->sbumpc();
+}
+
+streampos indirectbuf::seekoff(streamoff off, _seek_dir dir, int mode)
+{
+ int ret_val = 0;
+ int select = mode == 0 ? (ios::in|ios::out) : mode;
+ streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL;
+ if (gbuf == pbuf)
+ ret_val = gbuf->seekoff(off, dir, mode);
+ else {
+ if (gbuf)
+ ret_val = gbuf->seekoff(off, dir, ios::in);
+ if (pbuf && ret_val != EOF)
+ ret_val = pbuf->seekoff(off, dir, ios::out);
+ }
+ return ret_val;
+}
+
+streampos indirectbuf::seekpos(streampos pos, int mode)
+{
+ int ret_val = EOF;
+ int select = mode == 0 ? (ios::in|ios::out) : mode;
+ streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL;
+ if (gbuf == pbuf && gbuf != NULL)
+ ret_val = gbuf->seekpos(pos, mode);
+ else {
+ if (gbuf)
+ ret_val = gbuf->seekpos(pos, ios::in);
+ if (pbuf && ret_val != EOF)
+ ret_val = pbuf->seekpos(pos, ios::out);
+ }
+ return ret_val;
+}
+
+int indirectbuf::sync()
+{
+ streambuf *gbuf = get_stream();
+ int get_ret_val = gbuf ? gbuf->sync() : 0;
+ streambuf *pbuf = put_stream();
+ int put_ret_val = (pbuf && pbuf != gbuf) ? pbuf->sync() : 0;
+ return get_ret_val || put_ret_val;
+}
+
+int indirectbuf::pbackfail(int c)
+{
+ return get_stream()->sputbackc(c);
+}
diff --git a/gnu/dist/libio/indstream.h b/gnu/dist/libio/indstream.h
new file mode 100644
index 00000000000..c4558623d07
--- /dev/null
+++ b/gnu/dist/libio/indstream.h
@@ -0,0 +1,77 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _INDSTREAM_H
+#define _INDSTREAM_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <iostream.h>
+
+extern "C++" {
+// An indirectbuf is one that forwards all of its I/O requests
+// to another streambuf.
+// All get-related requests are sent to get_stream().
+// All put-related requests are sent to put_stream().
+
+// An indirectbuf can be used to implement Common Lisp
+// synonym-streams and two-way-streams.
+//
+// class synonymbuf : public indirectbuf {
+// Symbol *sym;
+// synonymbuf(Symbol *s) { sym = s; }
+// virtual streambuf *lookup_stream(int mode) {
+// return coerce_to_streambuf(lookup_value(sym)); }
+// };
+
+class indirectbuf : public streambuf {
+ protected:
+ streambuf *_get_stream; // Optional cache for get_stream().
+ streambuf *_put_stream; // Optional cache for put_stream().
+ int _delete_flags;
+ public:
+ streambuf *get_stream()
+ { return _get_stream ? _get_stream : lookup_stream(ios::in); }
+ streambuf *put_stream()
+ { return _put_stream ? _put_stream : lookup_stream(ios::out); }
+ virtual streambuf *lookup_stream(int/*mode*/) { return NULL; } // ERROR!
+ indirectbuf(streambuf *get=NULL, streambuf *put=NULL, int delete_mode=0);
+ virtual ~indirectbuf();
+ virtual streamsize xsputn(const char* s, streamsize n);
+ virtual streamsize xsgetn(char* s, streamsize n);
+ virtual int underflow();
+ virtual int uflow();
+ virtual int overflow(int c = EOF);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual int sync();
+ virtual int pbackfail(int c);
+};
+} // extern "C++"
+
+#endif /* !_INDSTREAM_H */
diff --git a/gnu/dist/libio/ioassign.cc b/gnu/dist/libio/ioassign.cc
new file mode 100644
index 00000000000..5b8e68bbf53
--- /dev/null
+++ b/gnu/dist/libio/ioassign.cc
@@ -0,0 +1,49 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include <iostream.h>
+#include "libioP.h"
+
+// These method are provided for backward compatibility reasons.
+// It's generally poor style to use them.
+// They are not supported by the ANSI/ISO working paper.
+
+_IO_istream_withassign& _IO_istream_withassign::operator=(istream& rhs)
+{
+ if (&rhs != (istream*)this)
+ {
+ init (rhs.rdbuf ());
+ _gcount = 0;
+ }
+ return *this;
+}
+
+_IO_ostream_withassign& _IO_ostream_withassign::operator=(ostream& rhs)
+{
+ if (&rhs != (ostream*)this)
+ init (rhs.rdbuf ());
+ return *this;
+}
diff --git a/gnu/dist/libio/ioextend.cc b/gnu/dist/libio/ioextend.cc
new file mode 100644
index 00000000000..a31ff36e6e5
--- /dev/null
+++ b/gnu/dist/libio/ioextend.cc
@@ -0,0 +1,132 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <iostream.h>
+
+static int __xalloc = 0;
+
+int ios::xalloc()
+{
+ return __xalloc++;
+}
+
+static ios::fmtflags __used_fmt_flags
+= ios::skipws | ios::left | ios::right | ios::internal
+| ios::dec | ios::oct | ios::hex | ios::showbase | ios::showpoint
+| ios::uppercase | ios::showpos | ios::scientific | ios::fixed
+#ifndef _IO_NEW_STREAMS
+| ios::dont_close
+#endif
+| ios::unitbuf | ios::stdio;
+
+ios::fmtflags ios::bitalloc()
+{
+ fmtflags bit_to_try = (fmtflags)1;
+ for (; bit_to_try; bit_to_try <<= 1)
+ {
+ if ((__used_fmt_flags & bit_to_try) == 0)
+ {
+ __used_fmt_flags |= bit_to_try;
+ return bit_to_try;
+ }
+ }
+ return 0;
+}
+
+// NOTE: This implementation of ios::iword and ios::pword assumes
+// that these methods are seldom used, so we want to minimize
+// the space and time overhead when NOT using these methods.
+//
+// ANSI specifies two conceptually-infinite arrays, one whose
+// elements are longs, and one whose elements are (void*)s.
+// We implement this as a single array, each of whose element is
+// a (struct ptr_and_long), which has space for both a long and a void*.
+// We also specify that (the i field of) the 0'th element of the array
+// contains the allocated length of the array (not counting that
+// initial element).
+
+struct ptr_and_long {
+ void *p;
+ long i;
+};
+
+static struct ptr_and_long&
+get_array_element(ios& io, int index)
+{
+ if (index < 0)
+ io._throw_failure();
+ register struct ptr_and_long *array = (ptr_and_long*)io._arrays;
+ int old_length = array == NULL ? 0 : array[0].i;
+ if (index >= old_length)
+ {
+ register int i;
+ int new_length = index + 10;
+ register struct ptr_and_long *new_array
+ = new ptr_and_long[1 + new_length];
+ if (array != NULL)
+ {
+ for (i = 1; i <= old_length; i++)
+ new_array[i] = array[i];
+ delete [] array;
+ }
+ for (i = old_length + 1; i <= new_length; i++)
+ {
+ new_array[i].i = 0;
+ new_array[i].p = NULL;
+ }
+ new_array[0].i = new_length;
+ new_array[0].p = NULL;
+ io._arrays = (void*)new_array;
+ array = new_array;
+ }
+ return array[index+1];
+}
+
+long& ios::iword(int index)
+{
+ return get_array_element(*this, index).i;
+}
+
+void*& ios::pword(int index)
+{
+ return get_array_element(*this, index).p;
+}
+
+long ios::iword(int index) const
+{
+ if (index < 0)
+ _throw_failure();
+ register struct ptr_and_long *pl_array = (ptr_and_long*)_arrays;
+ int len = pl_array == NULL ? 0 : pl_array[0].i;
+ return index >= len ? 0 : pl_array[index+1].i;
+}
+
+void* ios::pword(int index) const
+{
+ if (index < 0)
+ _throw_failure();
+ register struct ptr_and_long *pl_array = (ptr_and_long*)_arrays;
+ int len = pl_array == NULL ? 0 : pl_array[0].i;
+ return index >= len ? 0 : pl_array[index+1].p;
+}
diff --git a/gnu/dist/libio/iofclose.c b/gnu/dist/libio/iofclose.c
new file mode 100644
index 00000000000..b6f18e58c2c
--- /dev/null
+++ b/gnu/dist/libio/iofclose.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+int
+_IO_fclose (fp)
+ _IO_FILE *fp;
+{
+ int status;
+
+ CHECK_FILE(fp, EOF);
+
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (fp->_IO_file_flags & _IO_IS_FILEBUF)
+ status = _IO_file_close_it (fp);
+ else
+ status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
+ _IO_FINISH (fp);
+ _IO_cleanup_region_end (1);
+ if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
+ {
+ fp->_IO_file_flags = 0;
+ free(fp);
+ }
+
+ return status;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fclose, fclose)
+#else
+#ifdef __linux__
+#pragma weak fclose = _IO_fclose
+#endif
+#endif
diff --git a/gnu/dist/libio/iofdopen.c b/gnu/dist/libio/iofdopen.c
new file mode 100644
index 00000000000..841e7032b80
--- /dev/null
+++ b/gnu/dist/libio/iofdopen.c
@@ -0,0 +1,134 @@
+/* Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <fcntl.h>
+
+#ifndef _IO_fcntl
+#define _IO_fcntl fcntl
+#endif
+
+_IO_FILE *
+_IO_fdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ int read_write;
+ int posix_mode = 0;
+ struct locked_FILE
+ {
+ struct _IO_FILE_plus fp;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ } *new_f;
+ int fd_flags;
+
+ switch (*mode++)
+ {
+ case 'r':
+ read_write = _IO_NO_WRITES;
+ break;
+ case 'w':
+ read_write = _IO_NO_READS;
+ break;
+ case 'a':
+ posix_mode = O_APPEND;
+ read_write = _IO_NO_READS|_IO_IS_APPENDING;
+ break;
+ default:
+ MAYBE_SET_EINVAL;
+ return NULL;
+ }
+ if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
+ read_write &= _IO_IS_APPENDING;
+#ifdef F_GETFL
+ fd_flags = _IO_fcntl (fd, F_GETFL);
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
+ if (fd_flags == -1
+ || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
+ || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
+ return NULL;
+
+ /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
+ [System Application Program Interface (API) Amendment 1:
+ Realtime Extensions], Rationale B.8.3.3
+ Open a Stream on a File Descriptor says:
+
+ Although not explicitly required by POSIX.1, a good
+ implementation of append ("a") mode would cause the
+ O_APPEND flag to be set.
+
+ (Historical implementations [such as Solaris2] do a one-time
+ seek in fdopen.)
+
+ However, we do not turn O_APPEND off if the mode is "w" (even
+ though that would seem consistent) because that would be more
+ likely to break historical programs.
+ */
+ if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
+ {
+#ifdef F_SETFL
+ if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
+#endif
+ return NULL;
+ }
+#endif
+
+ new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
+ if (new_f == NULL)
+ return NULL;
+#ifdef _IO_MTSAFE_IO
+ new_f->fp.file._lock = &new_f->lock;
+#endif
+ _IO_init (&new_f->fp.file, 0);
+ _IO_JUMPS (&new_f->fp.file) = &_IO_file_jumps;
+ _IO_file_init (&new_f->fp.file);
+#if !_IO_UNIFIED_JUMPTABLES
+ new_f->fp.vtable = NULL;
+#endif
+ if (_IO_file_attach (&new_f->fp.file, fd) == NULL)
+ {
+ _IO_un_link (&new_f->fp.file);
+ free (new_f);
+ return NULL;
+ }
+ new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE;
+
+ new_f->fp.file._IO_file_flags =
+ _IO_mask_flags (&new_f->fp.file, read_write,
+ _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+
+ return (_IO_FILE *) &new_f->fp;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fdopen, fdopen)
+#endif
diff --git a/gnu/dist/libio/iofeof.c b/gnu/dist/libio/iofeof.c
new file mode 100644
index 00000000000..d06de044fba
--- /dev/null
+++ b/gnu/dist/libio/iofeof.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+_IO_feof (fp)
+ _IO_FILE* fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_flockfile (fp);
+ result = _IO_feof_unlocked (fp);
+ _IO_funlockfile (fp);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_feof, feof)
+#endif
diff --git a/gnu/dist/libio/ioferror.c b/gnu/dist/libio/ioferror.c
new file mode 100644
index 00000000000..855627ade66
--- /dev/null
+++ b/gnu/dist/libio/ioferror.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+_IO_ferror (fp)
+ _IO_FILE* fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_flockfile (fp);
+ result = _IO_ferror_unlocked (fp);
+ _IO_funlockfile (fp);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_ferror, ferror)
+#endif
diff --git a/gnu/dist/libio/iofflush.c b/gnu/dist/libio/iofflush.c
new file mode 100644
index 00000000000..540c99d535e
--- /dev/null
+++ b/gnu/dist/libio/iofflush.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <stdio.h>
+
+int
+_IO_fflush (fp)
+ _IO_FILE *fp;
+{
+ if (fp == NULL)
+ return _IO_flush_all ();
+ else
+ {
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_SYNC (fp) ? EOF : 0;
+ _IO_cleanup_region_end (1);
+ return result;
+ }
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fflush, fflush)
+#endif
diff --git a/gnu/dist/libio/iofflush_u.c b/gnu/dist/libio/iofflush_u.c
new file mode 100644
index 00000000000..b46ae4a3f94
--- /dev/null
+++ b/gnu/dist/libio/iofflush_u.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <stdio.h>
+
+int
+fflush_unlocked (fp)
+ _IO_FILE *fp;
+{
+ if (fp == NULL)
+ return _IO_flush_all ();
+ else
+ {
+ CHECK_FILE (fp, EOF);
+ return _IO_SYNC (fp) ? EOF : 0;
+ }
+}
diff --git a/gnu/dist/libio/iofgetpos.c b/gnu/dist/libio/iofgetpos.c
new file mode 100644
index 00000000000..716be4bca10
--- /dev/null
+++ b/gnu/dist/libio/iofgetpos.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <errno.h>
+/* ANSI explicitly requires setting errno to a positive value on failure. */
+
+int
+_IO_fgetpos (fp, posp)
+ _IO_FILE* fp;
+ _IO_fpos_t *posp;
+{
+ _IO_fpos_t pos;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+ _IO_cleanup_region_end (1);
+ if (pos == _IO_pos_BAD)
+ {
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ return EOF;
+ }
+ *posp = pos;
+ return 0;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fgetpos, fgetpos)
+#endif
diff --git a/gnu/dist/libio/iofgets.c b/gnu/dist/libio/iofgets.c
new file mode 100644
index 00000000000..74754d5d1ea
--- /dev/null
+++ b/gnu/dist/libio/iofgets.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <stdio.h>
+
+char *
+_IO_fgets (buf, n, fp)
+ char *buf;
+ int n;
+ _IO_FILE *fp;
+{
+ _IO_size_t count;
+ char *result;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ count = _IO_getline (fp, buf, n - 1, '\n', 1);
+ if (count == 0 || (fp->_IO_file_flags & _IO_ERR_SEEN))
+ result = NULL;
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fgets, fgets)
+#endif
diff --git a/gnu/dist/libio/iofopen.c b/gnu/dist/libio/iofopen.c
new file mode 100644
index 00000000000..1dbeccb81a8
--- /dev/null
+++ b/gnu/dist/libio/iofopen.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+_IO_FILE *
+_IO_fopen (filename, mode)
+ const char *filename;
+ const char *mode;
+{
+ struct locked_FILE
+ {
+ struct _IO_FILE_plus fp;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
+
+ if (new_f == NULL)
+ return NULL;
+#ifdef _IO_MTSAFE_IO
+ new_f->fp.file._lock = &new_f->lock;
+#endif
+ _IO_init (&new_f->fp.file, 0);
+ _IO_JUMPS (&new_f->fp.file) = &_IO_file_jumps;
+ _IO_file_init (&new_f->fp.file);
+#if !_IO_UNIFIED_JUMPTABLES
+ new_f->fp.vtable = NULL;
+#endif
+ if (_IO_file_fopen (&new_f->fp.file, filename, mode) != NULL)
+ return (_IO_FILE *) &new_f->fp;
+ _IO_un_link (&new_f->fp.file);
+ free (new_f);
+ return NULL;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fopen, fopen)
+#endif
diff --git a/gnu/dist/libio/iofprintf.c b/gnu/dist/libio/iofprintf.c
new file mode 100644
index 00000000000..4dc9d3f6617
--- /dev/null
+++ b/gnu/dist/libio/iofprintf.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#ifdef __STDC__
+_IO_fprintf (_IO_FILE *fp, const char* format, ...)
+#else
+_IO_fprintf (fp, format, va_alist)
+ _IO_FILE *fp;
+ char *format;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ CHECK_FILE (fp, -1);
+ _IO_va_start (args, format);
+ ret = _IO_vfprintf (fp, format, args);
+ va_end (args);
+ return ret;
+}
diff --git a/gnu/dist/libio/iofputs.c b/gnu/dist/libio/iofputs.c
new file mode 100644
index 00000000000..1a329bbe26f
--- /dev/null
+++ b/gnu/dist/libio/iofputs.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <string.h>
+
+int
+_IO_fputs (str, fp)
+ const char *str;
+ _IO_FILE *fp;
+{
+ _IO_size_t len = strlen (str);
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_sputn (fp, str, len) != len)
+ result = EOF;
+ else
+ result = 1;
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fputs, fputs)
+#endif
diff --git a/gnu/dist/libio/iofread.c b/gnu/dist/libio/iofread.c
new file mode 100644
index 00000000000..c83d2b638c9
--- /dev/null
+++ b/gnu/dist/libio/iofread.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+_IO_size_t
+_IO_fread (buf, size, count, fp)
+ void *buf;
+ _IO_size_t size;
+ _IO_size_t count;
+ _IO_FILE *fp;
+{
+ _IO_size_t bytes_requested = size*count;
+ _IO_size_t bytes_read;
+ CHECK_FILE (fp, 0);
+ if (bytes_requested == 0)
+ return 0;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
+ _IO_cleanup_region_end (1);
+ return bytes_requested == bytes_read ? count : bytes_read / size;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fread, fread)
+#endif
diff --git a/gnu/dist/libio/iofscanf.c b/gnu/dist/libio/iofscanf.c
new file mode 100644
index 00000000000..3e12d9b5315
--- /dev/null
+++ b/gnu/dist/libio/iofscanf.c
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_fscanf
+#ifdef __STDC__
+ (_IO_FILE *fp, const char* format, ...)
+#else
+(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ CHECK_FILE(fp, EOF);
+ _IO_va_start(args, format);
+ ret = _IO_vfscanf(fp, format, args, NULL);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/dist/libio/iofsetpos.c b/gnu/dist/libio/iofsetpos.c
new file mode 100644
index 00000000000..a8d816f5a39
--- /dev/null
+++ b/gnu/dist/libio/iofsetpos.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libioP.h>
+#include <errno.h>
+
+int
+_IO_fsetpos (fp, posp)
+ _IO_FILE *fp;
+ const _IO_fpos_t *posp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
+ {
+ /* ANSI explicitly requires setting errno to a positive value on
+ failure. */
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ result = EOF;
+ }
+ else
+ result = 0;
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fsetpos, fsetpos)
+#endif
diff --git a/gnu/dist/libio/ioftell.c b/gnu/dist/libio/ioftell.c
new file mode 100644
index 00000000000..d8a1ce1d242
--- /dev/null
+++ b/gnu/dist/libio/ioftell.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <errno.h>
+/* ANSI explicily requires setting errno to a positive value on failure. */
+
+long int
+_IO_ftell (fp)
+ _IO_FILE *fp;
+{
+ _IO_pos_t pos;
+ CHECK_FILE (fp, -1L);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+ _IO_cleanup_region_end (1);
+ if (pos == _IO_pos_BAD)
+ {
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ return -1L;
+ }
+ return _IO_pos_as_off (pos);
+}
+
+#ifdef weak_alias
+weak_alias (_IO_ftell, ftell)
+#endif
diff --git a/gnu/dist/libio/iofwrite.c b/gnu/dist/libio/iofwrite.c
new file mode 100644
index 00000000000..5bc525ffc70
--- /dev/null
+++ b/gnu/dist/libio/iofwrite.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+_IO_size_t
+_IO_fwrite (buf, size, count, fp)
+ const void *buf;
+ _IO_size_t size;
+ _IO_size_t count;
+ _IO_FILE *fp;
+{
+ _IO_size_t request = size * count;
+ _IO_size_t written;
+ CHECK_FILE (fp, 0);
+ if (request == 0)
+ return 0;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ written = _IO_sputn (fp, (const char *) buf, request);
+ _IO_cleanup_region_end (1);
+ /* Many traditional implementations return 0 if size==0 && count > 0,
+ but ANSI requires us to return count in this case. */
+ if (written == request)
+ return count;
+ else
+ return written / size;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fwrite, fwrite)
+#endif
diff --git a/gnu/dist/libio/iogetc.c b/gnu/dist/libio/iogetc.c
new file mode 100644
index 00000000000..f7465f1914b
--- /dev/null
+++ b/gnu/dist/libio/iogetc.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef _IO_getc
+
+int
+_IO_getc (fp)
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_getc_unlocked (fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#undef getc
+
+#ifdef weak_alias
+weak_alias (_IO_getc, getc)
+#endif
diff --git a/gnu/dist/libio/iogetdelim.c b/gnu/dist/libio/iogetdelim.c
new file mode 100644
index 00000000000..50918b3e8dc
--- /dev/null
+++ b/gnu/dist/libio/iogetdelim.c
@@ -0,0 +1,125 @@
+/* Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <string.h>
+#include <errno.h>
+
+/* Read up to (and including) a TERMINATOR from FP into *LINEPTR
+ (and null-terminate it). *LINEPTR is a pointer returned from malloc (or
+ NULL), pointing to *N characters of space. It is realloc'ed as
+ necessary. Returns the number of characters read (not including the
+ null terminator), or -1 on error or EOF. */
+
+_IO_ssize_t
+_IO_getdelim (lineptr, n, delimiter, fp)
+ char **lineptr;
+ _IO_size_t *n;
+ int delimiter;
+ _IO_FILE *fp;
+{
+ int result;
+ _IO_ssize_t cur_len = 0;
+ _IO_ssize_t len;
+
+ if (lineptr == NULL || n == NULL)
+ {
+ MAYBE_SET_EINVAL;
+ return -1;
+ }
+ CHECK_FILE (fp, -1);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_ferror_unlocked (fp))
+ {
+ result = -1;
+ goto unlock_return;
+ }
+
+ if (*lineptr == NULL || *n == 0)
+ {
+ *n = 120;
+ *lineptr = (char *) malloc (*n);
+ if (*lineptr == NULL)
+ {
+ result = -1;
+ goto unlock_return;
+ }
+ }
+
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (len <= 0)
+ {
+ if (__underflow (fp) == EOF)
+ {
+ result = -1;
+ goto unlock_return;
+ }
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+
+ for (;;)
+ {
+ _IO_size_t needed;
+ char *t;
+ t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
+ if (t != NULL)
+ len = (t - fp->_IO_read_ptr) + 1;
+ /* Make enough space for len+1 (for final NUL) bytes. */
+ needed = cur_len + len + 1;
+ if (needed > *n)
+ {
+ if (needed < 2 * *n)
+ needed = 2 * *n; /* Be generous. */
+ *n = needed;
+ *lineptr = (char *) realloc (*lineptr, needed);
+ if (*lineptr == NULL)
+ {
+ result = -1;
+ goto unlock_return;
+ }
+ }
+ memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
+ fp->_IO_read_ptr += len;
+ cur_len += len;
+ if (t != NULL || __underflow (fp) == EOF)
+ break;
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+ (*lineptr)[cur_len] = '\0';
+ result = cur_len;
+
+unlock_return:
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_getdelim, __getdelim)
+weak_alias (_IO_getdelim, getdelim)
+#endif
diff --git a/gnu/dist/libio/iogetline.c b/gnu/dist/libio/iogetline.c
new file mode 100644
index 00000000000..631db78d127
--- /dev/null
+++ b/gnu/dist/libio/iogetline.c
@@ -0,0 +1,112 @@
+/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <string.h>
+
+#if defined(_LIBC) || !_G_HAVE_IO_GETLINE_INFO
+
+_IO_size_t
+_IO_getline (fp, buf, n, delim, extract_delim)
+ _IO_FILE *fp;
+ char *buf;
+ _IO_size_t n;
+ int delim;
+ int extract_delim;
+{
+ return _IO_getline_info (fp, buf, n, delim, extract_delim, (int *) 0);
+}
+
+/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation.
+
+ Read chars into buf (of size n), until delim is seen.
+ Return number of chars read (at most n).
+ Does not put a terminating '\0' in buf.
+ If extract_delim < 0, leave delimiter unread.
+ If extract_delim > 0, insert delim in output. */
+
+_IO_size_t
+_IO_getline_info (fp, buf, n, delim, extract_delim, eof)
+ _IO_FILE *fp;
+ char *buf;
+ _IO_size_t n;
+ int delim;
+ int extract_delim;
+ int *eof;
+{
+ char *ptr = buf;
+ if (eof) *eof = 0;
+ do
+ {
+ _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (len <= 0)
+ {
+ int c = __uflow (fp);
+ if (c == EOF)
+ {
+ if (eof) *eof = c;
+ break;
+ }
+ if (c == delim)
+ {
+ if (extract_delim > 0)
+ *ptr++ = c;
+ else if (extract_delim < 0)
+ _IO_sputbackc (fp, c);
+ return ptr - buf;
+ }
+ *ptr++ = c;
+ n--;
+ }
+ else
+ {
+ char *t;
+ if ((_IO_size_t) len >= n)
+ len = n;
+ t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len);
+ if (t != NULL)
+ {
+ _IO_size_t old_len = ptr-buf;
+ len = t - fp->_IO_read_ptr;
+ if (extract_delim >= 0)
+ {
+ ++t;
+ if (extract_delim > 0)
+ ++len;
+ }
+ memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
+ fp->_IO_read_ptr = t;
+ return old_len + len;
+ }
+ memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
+ fp->_IO_read_ptr += len;
+ ptr += len;
+ n -= len;
+ }
+ } while (n != 0);
+ return ptr - buf;
+}
+
+#endif /* Defined(_LIBC) || !_G_HAVE_IO_GETLINE_INFO */
diff --git a/gnu/dist/libio/iogets.c b/gnu/dist/libio/iogets.c
new file mode 100644
index 00000000000..9e88ca1037a
--- /dev/null
+++ b/gnu/dist/libio/iogets.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <limits.h>
+
+char*
+_IO_gets (buf)
+ char *buf;
+{
+ _IO_size_t count;
+ int ch;
+ char *retval;
+
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _IO_stdin);
+ _IO_flockfile (_IO_stdin);
+ ch = _IO_getc_unlocked (_IO_stdin);
+ if (ch == EOF)
+ {
+ retval = NULL;
+ goto unlock_return;
+ }
+ if (ch == '\n')
+ count = 0;
+ else
+ {
+ buf[0] = (char) ch;
+ count = _IO_getline (_IO_stdin, buf + 1, INT_MAX, '\n', 0) + 1;
+ if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN)
+ {
+ retval = NULL;
+ goto unlock_return;
+ }
+ }
+ buf[count] = 0;
+ retval = buf;
+unlock_return:
+ _IO_cleanup_region_end (1);
+ return retval;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_gets, gets)
+#endif
+
+#ifdef _LIBC
+link_warning (gets, "the `gets' function is dangerous and should not be used.")
+#endif
diff --git a/gnu/dist/libio/ioignore.c b/gnu/dist/libio/ioignore.c
new file mode 100644
index 00000000000..ac0678ed7b9
--- /dev/null
+++ b/gnu/dist/libio/ioignore.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+int
+_IO_ignore (fp, n)
+ _IO_FILE *fp;
+ _IO_size_t n;
+{
+ register _IO_size_t more = n;
+ for (;;)
+ {
+ _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (count > 0)
+ {
+ if (count > more)
+ count = more;
+ fp->_IO_read_ptr += count;
+ more -= count;
+ }
+ if (more == 0 || __underflow(fp) == EOF)
+ break;
+ }
+ return n - more;
+}
diff --git a/gnu/dist/libio/iolibio.h b/gnu/dist/libio/iolibio.h
new file mode 100644
index 00000000000..083b198b448
--- /dev/null
+++ b/gnu/dist/libio/iolibio.h
@@ -0,0 +1,63 @@
+#include "libio.h"
+
+/* These emulate stdio functionality, but with a different name
+ (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int _IO_fclose __P((_IO_FILE*));
+extern _IO_FILE *_IO_fdopen __P((int, const char*));
+extern int _IO_fflush __P((_IO_FILE*));
+extern int _IO_fgetpos __P((_IO_FILE*, _IO_fpos_t*));
+extern char* _IO_fgets __P((char*, int, _IO_FILE*));
+extern _IO_FILE *_IO_fopen __P((const char*, const char*));
+extern int _IO_fprintf __P((_IO_FILE*, const char*, ...));
+extern int _IO_fputs __P((const char*, _IO_FILE*));
+extern int _IO_fsetpos __P((_IO_FILE*, const _IO_fpos_t *));
+extern long int _IO_ftell __P((_IO_FILE*));
+extern _IO_size_t _IO_fread __P((void*, _IO_size_t, _IO_size_t, _IO_FILE*));
+extern _IO_size_t _IO_fwrite __P((const void*,
+ _IO_size_t, _IO_size_t, _IO_FILE*));
+extern char* _IO_gets __P((char*));
+extern void _IO_perror __P((const char*));
+extern int _IO_printf __P((const char*, ...));
+extern int _IO_puts __P((const char*));
+extern int _IO_scanf __P((const char*, ...));
+extern void _IO_setbuffer __P((_IO_FILE *, char*, _IO_size_t));
+extern int _IO_setvbuf __P((_IO_FILE*, char*, int, _IO_size_t));
+extern int _IO_sscanf __P((const char*, const char*, ...));
+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
+#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
+#define _IO_fseek(__fp, __offset, __whence) \
+ (_IO_seekoff(__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD ? EOF : 0)
+#define _IO_rewind(FILE) (void)_IO_seekoff(FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT)
+#define _IO_vprintf(FORMAT, ARGS) _IO_vfprintf(_IO_stdout, FORMAT, ARGS)
+#if _G_IO_IO_FILE_VERSION == 0x20001
+#define _IO_freopen(FILENAME, MODE, FP) \
+ (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE, 0))
+#else
+#define _IO_freopen(FILENAME, MODE, FP) \
+ (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE))
+#endif
+#define _IO_fileno(FP) ((FP)->_fileno)
+extern _IO_FILE* _IO_popen __P((const char*, const char*));
+#define _IO_pclose _IO_fclose
+#define _IO_setbuf(_FP, _BUF) _IO_setbuffer(_FP, _BUF, _IO_BUFSIZ)
+#define _IO_setlinebuf(_FP) _IO_setvbuf(_FP, NULL, 1, 0)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gnu/dist/libio/iomanip.cc b/gnu/dist/libio/iomanip.cc
new file mode 100644
index 00000000000..fddba55a2b9
--- /dev/null
+++ b/gnu/dist/libio/iomanip.cc
@@ -0,0 +1,90 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "iomanip.h"
+
+
+// Those functions are called through a pointer,
+// thus it does not make sense, to inline them.
+
+ios & __iomanip_setbase (ios& i, int n)
+{
+ ios::fmtflags b;
+ switch (n)
+ {
+ case 8:
+ b = ios::oct; break;
+ case 10:
+ b = ios::dec; break;
+ case 16:
+ b = ios::hex; break;
+ default:
+ b = 0;
+ }
+ i.setf(b, ios::basefield);
+ return i;
+}
+
+ios & __iomanip_setfill (ios& i, int n)
+{
+ //FIXME if ( i.flags() & ios::widechar )
+ i.fill( (char) n);
+ //FIXME else
+ //FIXME i.fill( (wchar) n);
+ return i;
+}
+
+ios & __iomanip_setprecision (ios& i, int n)
+{
+ i.precision(n);
+ return i;
+}
+ios & __iomanip_setw (ios& i, int n)
+{
+ i.width(n);
+ return i;
+}
+
+ios & __iomanip_setiosflags (ios& i, ios::fmtflags n)
+{
+ i.setf(n,n);
+ return i;
+}
+
+ios & __iomanip_resetiosflags (ios& i, ios::fmtflags n)
+{
+ i.setf(0,n);
+ return i;
+}
+
+template class smanip<int>;
+template class smanip<ios::fmtflags>;
+template istream& operator>>(istream&, const smanip<int>&);
+template istream& operator>>(istream&, const smanip<ios::fmtflags>&);
+template ostream& operator<<(ostream&, const smanip<int>&);
+template ostream& operator<<(ostream&, const smanip<ios::fmtflags>&);
diff --git a/gnu/dist/libio/iomanip.h b/gnu/dist/libio/iomanip.h
new file mode 100644
index 00000000000..d80e98ed604
--- /dev/null
+++ b/gnu/dist/libio/iomanip.h
@@ -0,0 +1,176 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _IOMANIP_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _IOMANIP_H
+
+#include <iostream.h>
+
+extern "C++" {
+//-----------------------------------------------------------------------------
+// Parametrized Manipulators as specified by ANSI draft
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class smanip; // TP = Type Param
+
+template<class TP> class sapp {
+ ios& (*_f)(ios&, TP);
+public:
+ sapp(ios& (*f)(ios&, TP)) : _f(f) {}
+ //
+ smanip<TP> operator()(TP a)
+ { return smanip<TP>(_f, a); }
+};
+
+template<class TP>
+inline istream& operator>>(istream& i, const smanip<TP>& m);
+template<class TP>
+inline ostream& operator<<(ostream& o, const smanip<TP>& m);
+
+template <class TP> class smanip {
+ ios& (*_f)(ios&, TP);
+ TP _a;
+public:
+ smanip(ios& (*f)(ios&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ istream& operator>> <>(istream& i, const smanip<TP>& m);
+ friend
+ ostream& operator<< <>(ostream& o, const smanip<TP>& m);
+};
+
+#ifdef __GNUG__
+extern template class smanip<int>;
+extern template class smanip<ios::fmtflags>;
+#endif
+
+template<class TP>
+inline istream& operator>>(istream& i, const smanip<TP>& m)
+{ (*m._f)(i, m._a); return i; }
+
+template<class TP>
+inline ostream& operator<<(ostream& o, const smanip<TP>& m)
+{ (*m._f)(o, m._a); return o;}
+
+#ifdef __GNUG__
+extern template istream& operator>>(istream&, const smanip<int>&);
+extern template istream& operator>>(istream&, const smanip<ios::fmtflags>&);
+extern template ostream& operator<<(ostream&, const smanip<int>&);
+extern template ostream& operator<<(ostream&, const smanip<ios::fmtflags>&);
+#endif
+
+//-----------------------------------------------------------------------------
+// Input-Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class imanip;
+
+template<class TP> class iapp {
+ istream& (*_f)(istream&, TP);
+public:
+ iapp(istream& (*f)(istream&,TP)) : _f(f) {}
+ //
+ imanip<TP> operator()(TP a)
+ { return imanip<TP>(_f, a); }
+};
+
+template <class TP>
+inline istream& operator>>(istream&, const imanip<TP>&);
+
+template <class TP> class imanip {
+ istream& (*_f)(istream&, TP);
+ TP _a;
+public:
+ imanip(istream& (*f)(istream&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ istream& operator>> <>(istream& i, const imanip<TP>& m);
+};
+
+template <class TP>
+inline istream& operator>>(istream& i, const imanip<TP>& m)
+{ return (*m._f)( i, m._a); }
+
+//-----------------------------------------------------------------------------
+// Output-Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class omanip;
+
+template<class TP> class oapp {
+ ostream& (*_f)(ostream&, TP);
+public:
+ oapp(ostream& (*f)(ostream&,TP)) : _f(f) {}
+ //
+ omanip<TP> operator()(TP a)
+ { return omanip<TP>(_f, a); }
+};
+
+template <class TP>
+inline ostream& operator<<(ostream&, const omanip<TP>&);
+
+template <class TP> class omanip {
+ ostream& (*_f)(ostream&, TP);
+ TP _a;
+public:
+ omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ ostream& operator<< <>(ostream& o, const omanip<TP>& m);
+};
+
+template <class TP>
+inline ostream& operator<<(ostream& o, const omanip<TP>& m)
+{ return (*m._f)(o, m._a); }
+
+//-----------------------------------------------------------------------------
+// Available Manipulators
+//-----------------------------------------------------------------------------
+
+//
+// Macro to define an iomanip function, with one argument
+// The underlying function is `__iomanip_<name>'
+//
+#define __DEFINE_IOMANIP_FN1(type,param,function) \
+ extern ios& __iomanip_##function (ios&, param); \
+ inline type<param> function (param n) \
+ { return type<param> (__iomanip_##function, n); }
+
+__DEFINE_IOMANIP_FN1( smanip, int, setbase)
+__DEFINE_IOMANIP_FN1( smanip, int, setfill)
+__DEFINE_IOMANIP_FN1( smanip, int, setprecision)
+__DEFINE_IOMANIP_FN1( smanip, int, setw)
+
+__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, resetiosflags)
+__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, setiosflags)
+} // extern "C++"
+
+#endif /*!_IOMANIP_H*/
diff --git a/gnu/dist/libio/iopadn.c b/gnu/dist/libio/iopadn.c
new file mode 100644
index 00000000000..087715b349b
--- /dev/null
+++ b/gnu/dist/libio/iopadn.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+#define PADSIZE 16
+static char const blanks[PADSIZE] =
+{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+static char const zeroes[PADSIZE] =
+{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+_IO_ssize_t
+_IO_padn (fp, pad, count)
+ _IO_FILE *fp;
+ int pad;
+ _IO_ssize_t count;
+{
+ char padbuf[PADSIZE];
+ const char *padptr;
+ int i;
+ _IO_size_t written = 0;
+ _IO_size_t w;
+
+ if (pad == ' ')
+ padptr = blanks;
+ else if (pad == '0')
+ padptr = zeroes;
+ else
+ {
+ for (i = PADSIZE; --i >= 0; )
+ padbuf[i] = pad;
+ padptr = padbuf;
+ }
+ for (i = count; i >= PADSIZE; i -= PADSIZE)
+ {
+ w = _IO_sputn (fp, padptr, PADSIZE);
+ written += w;
+ if (w != PADSIZE)
+ return written;
+ }
+
+ if (i > 0)
+ {
+ w = _IO_sputn (fp, padptr, i);
+ written += w;
+ }
+ return written;
+}
diff --git a/gnu/dist/libio/ioperror.c b/gnu/dist/libio/ioperror.c
new file mode 100644
index 00000000000..7ca72b0bb60
--- /dev/null
+++ b/gnu/dist/libio/ioperror.c
@@ -0,0 +1,22 @@
+#include "libioP.h"
+#include <errno.h>
+#include <string.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifndef _IO_strerror
+extern char* _IO_strerror __P((int));
+#endif
+
+void
+_IO_perror (s)
+ const char *s;
+{
+ char *error = _IO_strerror (errno);
+
+ if (s != NULL && *s != '\0')
+ _IO_fprintf (_IO_stderr, "%s:", s);
+
+ _IO_fprintf (_IO_stderr, "%s\n", error ? error : "");
+}
diff --git a/gnu/dist/libio/iopopen.c b/gnu/dist/libio/iopopen.c
new file mode 100644
index 00000000000..59d4fc3f0ed
--- /dev/null
+++ b/gnu/dist/libio/iopopen.c
@@ -0,0 +1,251 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+ Written by Per Bothner <bothner@cygnus.com>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include "libioP.h"
+#if _IO_HAVE_SYS_WAIT
+#include <signal.h>
+#include <unistd.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#ifdef _LIBC
+# include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifndef _IO_fork
+#define _IO_fork vfork /* defined in libiberty, if needed */
+extern _IO_pid_t _IO_fork __P ((void));
+#endif
+
+#endif /* _IO_HAVE_SYS_WAIT */
+
+#ifndef _IO_pipe
+#define _IO_pipe pipe
+extern int _IO_pipe __P ((int des[2]));
+#endif
+
+#ifndef _IO_dup2
+#define _IO_dup2 dup2
+extern int _IO_dup2 __P ((int fd, int fd2));
+#endif
+
+#ifndef _IO_waitpid
+#define _IO_waitpid waitpid
+#endif
+
+#ifndef _IO_execl
+#define _IO_execl execl
+#endif
+#ifndef _IO__exit
+#define _IO__exit _exit
+#endif
+
+#ifndef _IO_close
+#define _IO_close close
+#endif
+
+struct _IO_proc_file
+{
+ struct _IO_FILE_plus file;
+ /* Following fields must match those in class procbuf (procbuf.h) */
+ _IO_pid_t pid;
+ struct _IO_proc_file *next;
+};
+typedef struct _IO_proc_file _IO_proc_file;
+
+static struct _IO_proc_file *proc_file_chain = NULL;
+
+_IO_FILE *
+_IO_proc_open (fp, command, mode)
+ _IO_FILE *fp;
+ const char *command;
+ const char *mode;
+{
+#if _IO_HAVE_SYS_WAIT
+ volatile int read_or_write;
+ volatile int parent_end, child_end;
+ int pipe_fds[2];
+ _IO_pid_t child_pid;
+ if (_IO_file_is_open (fp))
+ return NULL;
+ if (_IO_pipe (pipe_fds) < 0)
+ return NULL;
+ if (mode[0] == 'r')
+ {
+ parent_end = pipe_fds[0];
+ child_end = pipe_fds[1];
+ read_or_write = _IO_NO_WRITES;
+ }
+ else
+ {
+ parent_end = pipe_fds[1];
+ child_end = pipe_fds[0];
+ read_or_write = _IO_NO_READS;
+ }
+ ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
+ if (child_pid == 0)
+ {
+ int child_std_end = mode[0] == 'r' ? 1 : 0;
+ _IO_close (parent_end);
+ if (child_end != child_std_end)
+ {
+ _IO_dup2 (child_end, child_std_end);
+ _IO_close (child_end);
+ }
+ /* POSIX.2: "popen() shall ensure that any streams from previous
+ popen() calls that remain open in the parent process are closed
+ in the new child process." */
+ while (proc_file_chain)
+ {
+ _IO_close (_IO_fileno ((_IO_FILE *) proc_file_chain));
+ proc_file_chain = proc_file_chain->next;
+ }
+
+ _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0);
+ _IO__exit (127);
+ }
+ _IO_close (child_end);
+ if (child_pid < 0)
+ {
+ _IO_close (parent_end);
+ return NULL;
+ }
+ _IO_fileno (fp) = parent_end;
+
+ /* Link into proc_file_chain. */
+ ((_IO_proc_file *) fp)->next = proc_file_chain;
+ proc_file_chain = (_IO_proc_file *) fp;
+
+ _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
+ return fp;
+#else /* !_IO_HAVE_SYS_WAIT */
+ return NULL;
+#endif
+}
+
+_IO_FILE *
+_IO_popen (command, mode)
+ const char *command;
+ const char *mode;
+{
+ struct locked_FILE
+ {
+ struct _IO_proc_file fpx;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ } *new_f;
+ _IO_FILE *fp;
+
+ new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
+ if (new_f == NULL)
+ return NULL;
+#ifdef _IO_MTSAFE_IO
+ new_f->fpx.file.file._lock = &new_f->lock;
+#endif
+ fp = (_IO_FILE*)&new_f->fpx;
+ _IO_init (fp, 0);
+ _IO_JUMPS (fp) = &_IO_proc_jumps;
+ _IO_file_init (fp);
+#if !_IO_UNIFIED_JUMPTABLES
+ ((struct _IO_FILE_plus *) fp)->vtable = NULL;
+#endif
+ if (_IO_proc_open (fp, command, mode) != NULL)
+ return fp;
+ free (new_f);
+ return NULL;
+}
+
+#ifdef strong_alias
+strong_alias (_IO_popen, popen);
+#endif
+
+int
+_IO_proc_close (fp)
+ _IO_FILE *fp;
+{
+ /* This is not name-space clean. FIXME! */
+#if _IO_HAVE_SYS_WAIT
+ int wstatus;
+ _IO_proc_file **ptr = &proc_file_chain;
+ _IO_pid_t wait_pid;
+ int status = -1;
+
+ /* Unlink from proc_file_chain. */
+ for ( ; *ptr != NULL; ptr = &(*ptr)->next)
+ {
+ if (*ptr == (_IO_proc_file *) fp)
+ {
+ *ptr = (*ptr)->next;
+ status = 0;
+ break;
+ }
+ }
+
+ if (status < 0 || _IO_close (_IO_fileno(fp)) < 0)
+ return -1;
+ /* POSIX.2 Rationale: "Some historical implementations either block
+ or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
+ for the child process to terminate. Since this behavior is not
+ described in POSIX.2, such implementations are not conforming." */
+ do
+ {
+ wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
+ }
+ while (wait_pid == -1 && errno == EINTR);
+ if (wait_pid == -1)
+ return -1;
+ return wstatus;
+#else /* !_IO_HAVE_SYS_WAIT */
+ return -1;
+#endif
+}
+
+struct _IO_jump_t _IO_proc_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_file_finish),
+ JUMP_INIT(overflow, _IO_file_overflow),
+ JUMP_INIT(underflow, _IO_file_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_file_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_file_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_file_setbuf),
+ JUMP_INIT(sync, _IO_file_sync),
+ JUMP_INIT(doallocate, _IO_file_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_proc_close),
+ JUMP_INIT(stat, _IO_file_stat)
+};
diff --git a/gnu/dist/libio/ioprims.c b/gnu/dist/libio/ioprims.c
new file mode 100644
index 00000000000..e3e0d7e75cd
--- /dev/null
+++ b/gnu/dist/libio/ioprims.c
@@ -0,0 +1,80 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* I/O OS-level primitives.
+ Needs to be replaced if not using Unix.
+ Also needs to be replaced if avoiding name-space pollution
+ (in which case read would be defined in terms of _IO_read,
+ rather than vice versa). */
+
+#include "libioP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifdef TODO
+/* Add open, isatty */
+#endif
+
+_IO_ssize_t
+_IO_read (fildes, buf, nbyte)
+ int fildes;
+ void *buf;
+ _IO_size_t nbyte;
+{
+ return read (fildes, buf, nbyte);
+}
+
+_IO_ssize_t
+_IO_write (fildes, buf, nbyte)
+ int fildes;
+ const void *buf;
+ _IO_size_t nbyte;
+{
+ return write (fildes, buf, nbyte);
+}
+
+_IO_off_t
+_IO_lseek (fildes, offset, whence)
+ int fildes;
+ _IO_off_t offset;
+ int whence;
+{
+ return lseek (fildes, offset, whence);
+}
+
+int
+_IO_close (fildes)
+ int fildes;
+{
+ return close (fildes);
+}
+
+int
+_IO_fstat (fildes, buf)
+ int fildes;
+ struct stat *buf;
+{
+ return fstat (fildes, buf);
+}
diff --git a/gnu/dist/libio/ioprintf.c b/gnu/dist/libio/ioprintf.c
new file mode 100644
index 00000000000..0b99c2a6637
--- /dev/null
+++ b/gnu/dist/libio/ioprintf.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_printf
+#ifdef __STDC__
+ (const char* format, ...)
+#else
+(format, va_alist) char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vfprintf(_IO_stdout, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/dist/libio/ioputc.c b/gnu/dist/libio/ioputc.c
new file mode 100644
index 00000000000..3c35c365f07
--- /dev/null
+++ b/gnu/dist/libio/ioputc.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef _IO_putc
+
+int
+_IO_putc (c, fp)
+ int c;
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_putc_unlocked (c, fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#undef putc
+
+#ifdef weak_alias
+weak_alias (_IO_putc, putc)
+#endif
diff --git a/gnu/dist/libio/ioputs.c b/gnu/dist/libio/ioputs.c
new file mode 100644
index 00000000000..ab5e6aaa4cc
--- /dev/null
+++ b/gnu/dist/libio/ioputs.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <string.h>
+
+int
+_IO_puts (str)
+ const char *str;
+{
+ int result;
+ _IO_size_t len = strlen (str);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _IO_stdout);
+ _IO_flockfile (_IO_stdout);
+ if (_IO_sputn (_IO_stdout, str, len) == len
+ && _IO_putc_unlocked ('\n', _IO_stdout) != EOF)
+ result = len + 1;
+ else
+ result = EOF;
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_puts, puts)
+#endif
diff --git a/gnu/dist/libio/ioscanf.c b/gnu/dist/libio/ioscanf.c
new file mode 100644
index 00000000000..405d1e2eb0f
--- /dev/null
+++ b/gnu/dist/libio/ioscanf.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_scanf
+#ifdef __STDC__
+ (const char* format, ...)
+#else
+(format, va_alist) char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vfscanf(_IO_stdin, format, args, NULL);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/dist/libio/ioseekoff.c b/gnu/dist/libio/ioseekoff.c
new file mode 100644
index 00000000000..b1c4729b3d1
--- /dev/null
+++ b/gnu/dist/libio/ioseekoff.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libioP.h>
+
+_IO_pos_t
+_IO_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+ int mode;
+{
+ _IO_pos_t retval;
+
+ /* If we have a backup buffer, get rid of it, since the __seekoff
+ callback may not know to do the right thing about it.
+ This may be over-kill, but it'll do for now. TODO */
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+
+
+ if (_IO_have_backup (fp))
+ {
+ if (dir == _IO_seek_cur && _IO_in_backup (fp))
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ _IO_free_backup_area (fp);
+ }
+ retval = _IO_SEEKOFF (fp, offset, dir, mode);
+
+ _IO_cleanup_region_end (1);
+ return retval;
+}
diff --git a/gnu/dist/libio/ioseekpos.c b/gnu/dist/libio/ioseekpos.c
new file mode 100644
index 00000000000..2ce0c2224ec
--- /dev/null
+++ b/gnu/dist/libio/ioseekpos.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libioP.h>
+
+_IO_pos_t
+_IO_seekpos (fp, pos, mode)
+ _IO_FILE *fp;
+ _IO_pos_t pos;
+ int mode;
+{
+ _IO_pos_t retval;
+
+ /* If we have a backup buffer, get rid of it, since the __seekoff
+ callback may not know to do the right thing about it.
+ This may be over-kill, but it'll do for now. TODO */
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+
+ if (_IO_have_backup (fp))
+ _IO_free_backup_area (fp);
+ retval = _IO_SEEKPOS (fp, pos, mode);
+
+ _IO_cleanup_region_end (1);
+ return retval;
+}
diff --git a/gnu/dist/libio/iosetbuffer.c b/gnu/dist/libio/iosetbuffer.c
new file mode 100644
index 00000000000..f140a9ad046
--- /dev/null
+++ b/gnu/dist/libio/iosetbuffer.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+void
+_IO_setbuffer (fp, buf, size)
+ _IO_FILE *fp;
+ char *buf;
+ _IO_size_t size;
+{
+ CHECK_FILE (fp, );
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ fp->_flags &= ~_IO_LINE_BUF;
+ if (!buf)
+ size = 0;
+ (void) _IO_SETBUF (fp, buf, size);
+ _IO_cleanup_region_end (1);
+}
+
+#ifdef weak_alias
+weak_alias (_IO_setbuffer, setbuffer)
+#endif
diff --git a/gnu/dist/libio/iosetvbuf.c b/gnu/dist/libio/iosetvbuf.c
new file mode 100644
index 00000000000..65eeea51a6f
--- /dev/null
+++ b/gnu/dist/libio/iosetvbuf.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+int
+_IO_setvbuf (fp, buf, mode, size)
+ _IO_FILE *fp;
+ char *buf;
+ int mode;
+ _IO_size_t size;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ switch (mode)
+ {
+ case _IOFBF:
+ fp->_IO_file_flags &= ~_IO_LINE_BUF|_IO_UNBUFFERED;
+ if (buf == NULL)
+ {
+ if (fp->_IO_buf_base == NULL)
+ {
+ /* There is no flag to distinguish between "fully buffered
+ mode has been explicitly set" as opposed to "line
+ buffering has not been explicitly set". In both
+ cases, _IO_LINE_BUF is off. If this is a tty, and
+ _IO_filedoalloc later gets called, it cannot know if
+ it should set the _IO_LINE_BUF flag (because that is
+ the default), or not (because we have explicitly asked
+ for fully buffered mode). So we make sure a buffer
+ gets allocated now, and explicitly turn off line
+ buffering.
+
+ A possibly cleaner alternative would be to add an
+ extra flag, but then flags are a finite resource. */
+ if (_IO_DOALLOCATE (fp) < 0)
+ {
+ result = EOF;
+ goto unlock_return;
+ }
+ fp->_IO_file_flags &= ~_IO_LINE_BUF;
+ }
+ result = 0;
+ goto unlock_return;
+ }
+ break;
+ case _IOLBF:
+ fp->_IO_file_flags &= ~_IO_UNBUFFERED;
+ fp->_IO_file_flags |= _IO_LINE_BUF;
+ if (buf == NULL)
+ {
+ result = 0;
+ goto unlock_return;
+ }
+ break;
+ case _IONBF:
+ buf = NULL;
+ size = 0;
+ break;
+ default:
+ result = EOF;
+ goto unlock_return;
+ }
+ result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
+unlock_return:
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_setvbuf, setvbuf)
+#endif
diff --git a/gnu/dist/libio/iosprintf.c b/gnu/dist/libio/iosprintf.c
new file mode 100644
index 00000000000..704a6dbd72d
--- /dev/null
+++ b/gnu/dist/libio/iosprintf.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#ifdef __STDC__
+_IO_sprintf (char *string, const char* format, ...)
+#else
+_IO_sprintf (string, format, va_alist)
+ char *string;
+ char *format;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start (args, format);
+ ret = _IO_vsprintf (string, format, args);
+ va_end (args);
+ return ret;
+}
diff --git a/gnu/dist/libio/iosscanf.c b/gnu/dist/libio/iosscanf.c
new file mode 100644
index 00000000000..58868778c48
--- /dev/null
+++ b/gnu/dist/libio/iosscanf.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_sscanf
+#ifdef __STDC__
+ (const char * string, const char* format, ...)
+#else
+(string, format, va_alist) char *string; char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vsscanf(string, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/dist/libio/iostdio.h b/gnu/dist/libio/iostdio.h
new file mode 100644
index 00000000000..9ed47a4654a
--- /dev/null
+++ b/gnu/dist/libio/iostdio.h
@@ -0,0 +1,114 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* This file defines a stdio-like environment, except that it avoid
+ link-time name clashes with an existing stdio.
+ It allows for testing the libio using stdio-using programs
+ with an incompatible libc.a.
+ It is not predantically correct - e.g. some macros are used
+ that may evaluate a stream argument more than once. */
+
+#ifndef _IOSTDIO_H
+#define _IOSTDIO_H
+
+#include "iolibio.h"
+
+typedef _IO_FILE FILE;
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+/* #define size_t, fpos_t L_tmpname TMP_MAX */
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define stdin _IO_stdin
+#define stdout _IO_stdout
+#define stderr _IO_stderr
+
+#define getc(_fp) _IO_getc(_fp)
+#define putc(_ch, _fp) _IO_putc(_ch, _fp)
+
+#define clearerr _IO_clearerr
+#define fclose _IO_fclose
+#define feof _IO_feof
+#define ferror _IO_ferror
+#define fflush _IO_fflush
+#define fgetc(__fp) _IO_getc(_fp)
+#define fgetpos _IO_fgetpos
+#define fgets _IO_fgets
+#define fopen _IO_fopen
+#define fprintf _IO_fprintf
+#define fputc(_ch, _fp) _IO_putc(_ch, _fp)
+#define fputs _IO_fputs
+#define fread _IO_fread
+#define freopen _IO_freopen
+#define fscanf _IO_fscanf
+#define fseek _IO_fseek
+#define fsetpos _IO_fsetpos
+#define ftell _IO_ftell
+#define fwrite _IO_fwrite
+#define gets _IO_gets
+#define perror _IO_perror
+#define printf _IO_printf
+#define puts _IO_puts
+#define rewind _IO_rewind
+#define scanf _IO_scanf
+#define setbuf _IO_setbuf
+#define setbuffer _IO_setbuffer
+#define setvbuf _IO_setvbuf
+#define sprintf _IO_sprintf
+#define sscanf _IO_sscanf
+#define ungetc _IO_ungetc
+#define vfprintf _IO_vfprintf
+#define vprintf(__fmt, __args) vfprintf(stdout, __fmt, __args)
+#define vsprintf _IO_vsprintf
+
+#if 0
+/* We can use the libc versions of these, since they don't pass FILE*s. */
+#define remove ??? __P((const char*))
+#define rename ??? __P((const char* _old, const char* _new))
+#define tmpfile ??? __P((void))
+#define tmpnam ??? __P((char*))
+#endif
+
+#if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)
+#define fdopen _IO_fdopen
+#define fileno _IO_fileno
+#define popen _IO_popen
+#define pclose _IO_pclose
+#define setbuf _IO_setbuf
+#define setlinebuf _IO_setlinebuf
+#endif
+
+#endif /* _IOSTDIO_H */
diff --git a/gnu/dist/libio/iostream.cc b/gnu/dist/libio/iostream.cc
new file mode 100644
index 00000000000..921a00c21a9
--- /dev/null
+++ b/gnu/dist/libio/iostream.cc
@@ -0,0 +1,990 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+ Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+
+ This file is part of the GNU IO Library. This library is free
+ software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does not cause
+ the resulting executable to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+#include <iostream.h>
+#include "libioP.h"
+#include <stdio.h> /* Needed for sprintf */
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+
+#if _G_HAVE_PRINTF_FP
+#include <printf.h>
+extern "C" int __printf_fp (_IO_FILE *, const struct printf_info *,
+ const void *const *);
+#else
+#include "floatio.h"
+# ifndef _IO_USE_DTOA
+int __cvt_double(double number, register int prec, int flags, int *signp,
+ int fmtch, char *startp, char *endp);
+# endif
+#endif
+
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+
+//#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
+
+istream::istream(streambuf *sb, ostream* tied)
+{
+ init (sb, tied);
+ _gcount = 0;
+}
+
+int skip_ws(streambuf* sb)
+{
+ int ch;
+ for (;;) {
+ ch = sb->sbumpc();
+ if (ch == EOF || !isspace(ch))
+ return ch;
+ }
+}
+
+istream& istream::get(char& c)
+{
+ if (ipfx1()) {
+ int ch = _strbuf->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ _gcount = 0;
+ }
+ else {
+ c = (char)ch;
+ _gcount = 1;
+ }
+ }
+ else
+ _gcount = 0;
+ return *this;
+}
+
+int istream::peek()
+{
+ if (!good())
+ return EOF;
+ if (_tie && rdbuf()->in_avail() == 0)
+ _tie->flush();
+ int ch = _strbuf->sgetc();
+ if (ch == EOF)
+ set(ios::eofbit);
+ return ch;
+}
+
+istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
+{
+ _gcount = 0;
+ if (ipfx1()) {
+ register streambuf* sb = _strbuf;
+ if (delim == EOF) {
+ _gcount = sb->ignore(n);
+ return *this;
+ }
+ for (;;) {
+#if 0
+ if (n != MAXINT) // FIXME
+#endif
+ if (--n < 0)
+ break;
+ int ch = sb->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ break;
+ }
+ _gcount++;
+ if (ch == delim)
+ break;
+ }
+ }
+ return *this;
+}
+
+istream& istream::read(char *s, streamsize n)
+{
+ if (ipfx1()) {
+ _gcount = _strbuf->sgetn(s, n);
+ if (_gcount != n)
+ set(ios::failbit|ios::eofbit);
+ }
+ else
+ _gcount = 0;
+ return *this;
+}
+
+int
+istream::sync ()
+{
+ streambuf *sb = rdbuf ();
+ if (sb == NULL)
+ return EOF;
+ if (sb->sync ()) // Later: pubsync
+ {
+ setstate (ios::badbit);
+ return EOF;
+ }
+ else
+ return 0;
+}
+
+istream& istream::seekg(streampos pos)
+{
+ pos = _strbuf->pubseekpos(pos, ios::in);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+istream& istream::seekg(streamoff off, _seek_dir dir)
+{
+ streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos istream::tellg()
+{
+#if 0
+ streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in);
+#else
+ streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT);
+#endif
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+istream& istream::operator>>(char& c)
+{
+ if (ipfx0()) {
+ int ch = _strbuf->sbumpc();
+ if (ch == EOF)
+ set(ios::eofbit|ios::failbit);
+ else
+ c = (char)ch;
+ }
+ return *this;
+}
+
+istream&
+istream::operator>> (char* ptr)
+{
+ register char *p = ptr;
+ int w = width(0);
+ if (ipfx0())
+ {
+ register streambuf* sb = _strbuf;
+ for (;;)
+ {
+ int ch = sb->sbumpc();
+ if (ch == EOF)
+ {
+ set(ios::eofbit);
+ break;
+ }
+ else if (isspace(ch) || w == 1)
+ {
+ sb->sputbackc(ch);
+ break;
+ }
+ else *p++ = ch;
+ w--;
+ }
+ if (p == ptr)
+ set(ios::failbit);
+ }
+ *p = '\0';
+ return *this;
+}
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define LONGEST long long
+#else
+#define LONGEST long
+#endif
+
+static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
+{
+ if (!stream.ipfx0())
+ return 0;
+ register streambuf* sb = stream.rdbuf();
+ int base = 10;
+ int ndigits = 0;
+ register int ch = skip_ws(sb);
+ if (ch == EOF)
+ goto eof_fail;
+ neg = 0;
+ if (ch == '+') {
+ ch = skip_ws(sb);
+ }
+ else if (ch == '-') {
+ neg = 1;
+ ch = skip_ws(sb);
+ }
+ if (ch == EOF) goto eof_fail;
+ if (!(stream.flags() & ios::basefield)) {
+ if (ch == '0') {
+ ch = sb->sbumpc();
+ if (ch == EOF) {
+ val = 0;
+ return 1;
+ }
+ if (ch == 'x' || ch == 'X') {
+ base = 16;
+ ch = sb->sbumpc();
+ if (ch == EOF) goto eof_fail;
+ }
+ else {
+ sb->sputbackc(ch);
+ base = 8;
+ ch = '0';
+ }
+ }
+ }
+ else if ((stream.flags() & ios::basefield) == ios::hex)
+ base = 16;
+ else if ((stream.flags() & ios::basefield) == ios::oct)
+ base = 8;
+ val = 0;
+ for (;;) {
+ if (ch == EOF)
+ break;
+ int digit;
+ if (ch >= '0' && ch <= '9')
+ digit = ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ digit = ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ digit = ch - 'a' + 10;
+ else
+ digit = 999;
+ if (digit >= base) {
+ sb->sputbackc(ch);
+ if (ndigits == 0)
+ goto fail;
+ else
+ return 1;
+ }
+ ndigits++;
+ val = base * val + digit;
+ ch = sb->sbumpc();
+ }
+ return 1;
+ fail:
+ stream.set(ios::failbit);
+ return 0;
+ eof_fail:
+ stream.set(ios::failbit|ios::eofbit);
+ return 0;
+}
+
+#define READ_INT(TYPE) \
+istream& istream::operator>>(TYPE& i)\
+{\
+ unsigned LONGEST val; int neg;\
+ if (read_int(*this, val, neg)) {\
+ if (neg) val = -val;\
+ i = (TYPE)val;\
+ }\
+ return *this;\
+}
+
+READ_INT(short)
+READ_INT(unsigned short)
+READ_INT(int)
+READ_INT(unsigned int)
+READ_INT(long)
+READ_INT(unsigned long)
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+READ_INT(long long)
+READ_INT(unsigned long long)
+#endif
+#if _G_HAVE_BOOL
+READ_INT(bool)
+#endif
+
+istream& istream::operator>>(long double& x)
+{
+ if (ipfx0())
+ {
+#if _G_HAVE_LONG_DOUBLE_IO
+ scan("%Lg", &x);
+#else
+ double y;
+ scan("%lg", &y);
+ x = y;
+#endif
+ }
+ return *this;
+}
+
+istream& istream::operator>>(double& x)
+{
+ if (ipfx0())
+ scan("%lg", &x);
+ return *this;
+}
+
+istream& istream::operator>>(float& x)
+{
+ if (ipfx0())
+ scan("%g", &x);
+ return *this;
+}
+
+istream& istream::operator>>(register streambuf* sbuf)
+{
+ if (ipfx0()) {
+ register streambuf* inbuf = rdbuf();
+ // FIXME: Should optimize!
+ for (;;) {
+ register int ch = inbuf->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit);
+ break;
+ }
+ if (sbuf->sputc(ch) == EOF) {
+ set(ios::failbit);
+ break;
+ }
+ }
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(char c)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+#if 1
+ // This is what the cfront implementation does.
+ if (_strbuf->sputc(c) == EOF) {
+ set(ios::badbit);
+ goto failed;
+ }
+#else
+ // This is what cfront documentation and current ANSI drafts say.
+ int w = width(0);
+ char fill_char = fill();
+ register int padding = w > 0 ? w - 1 : 0;
+ register streambuf *sb = _strbuf;
+ if (!(flags() & ios::left) && padding) // Default adjustment.
+ if (_IO_padn(sb, fill_char, padding) < padding) {
+ set(ios::badbit);
+ goto failed;
+ }
+ if (sb->sputc(c) == EOF) {
+ set(ios::badbit);
+ goto failed;
+ }
+ if (flags() & ios::left && padding) // Left adjustment.
+ if (_IO_padn(sb, fill_char, padding) < padding)
+ set(ios::badbit);
+#endif
+ failed:
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+/* Write VAL on STREAM.
+ If SIGN<0, val is the absolute value of a negative number.
+ If SIGN>0, val is a signed non-negative number.
+ If SIGN==0, val is unsigned. */
+
+static void write_int(ostream& stream, unsigned LONGEST val, int sign)
+{
+#define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
+ char buf[WRITE_BUF_SIZE];
+ register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
+ const char *show_base = "";
+ int show_base_len = 0;
+ int show_pos = 0; // If 1, print a '+'.
+
+ // Now do the actual conversion, placing the result at the *end* of buf.
+ // Note that we use separate code for decimal, octal, and hex,
+ // so we can divide by optimizable constants.
+ if ((stream.flags() & ios::basefield) == ios::oct) { // Octal
+ do {
+ *--buf_ptr = (val & 7) + '0';
+ val = val >> 3;
+ } while (val != 0);
+ if ((stream.flags() & ios::showbase) && (*buf_ptr != '0'))
+ *--buf_ptr = '0';
+ }
+ else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
+ const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
+ : "0123456789abcdef0x";
+ do {
+ *--buf_ptr = xdigs[val & 15];
+ val = val >> 4;
+ } while (val != 0);
+ if ((stream.flags() & ios::showbase)) {
+ show_base = xdigs + 16; // Either "0X" or "0x".
+ show_base_len = 2;
+ }
+ }
+ else { // Decimal
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+ // Optimization: Only use long long when we need to.
+ while (val > UINT_MAX) {
+ *--buf_ptr = (val % 10) + '0';
+ val /= 10;
+ }
+ // Use more efficient (int) arithmetic for the rest.
+ register unsigned int ival = (unsigned int)val;
+#else
+ register unsigned LONGEST ival = val;
+#endif
+ do {
+ *--buf_ptr = (ival % 10) + '0';
+ ival /= 10;
+ } while (ival != 0);
+ if (sign > 0 && (stream.flags() & ios::showpos))
+ show_pos=1;
+ }
+
+ int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
+ int w = stream.width(0);
+
+ // Calculate padding.
+ int len = buf_len+show_pos;
+ if (sign < 0) len++;
+ len += show_base_len;
+ int padding = len > w ? 0 : w - len;
+
+ // Do actual output.
+ register streambuf* sbuf = stream.rdbuf();
+ ios::fmtflags pad_kind =
+ stream.flags() & (ios::left|ios::right|ios::internal);
+ char fill_char = stream.fill();
+ if (padding > 0
+ && pad_kind != (ios::fmtflags)ios::left
+ && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
+ if (_IO_padn(sbuf, fill_char, padding) < padding)
+ goto failed;
+ if (sign < 0 || show_pos)
+ {
+ char ch = sign < 0 ? '-' : '+';
+ if (sbuf->sputc(ch) < 0)
+ goto failed;
+ }
+ if (show_base_len)
+ if (_IO_sputn(sbuf, show_base, show_base_len) <= 0)
+ goto failed;
+ if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
+ if (_IO_padn(sbuf, fill_char, padding) < padding)
+ goto failed;
+ if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len)
+ goto failed;
+ if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
+ if (_IO_padn(sbuf, fill_char, padding) < padding)
+ goto failed;
+ stream.osfx();
+ return;
+ failed:
+ stream.set(ios::badbit);
+ stream.osfx();
+}
+
+ostream& ostream::operator<<(int n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ int sign = 1;
+ unsigned int abs_n = (unsigned)n;
+ if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
+ abs_n = -((unsigned)n), sign = -1;
+ write_int(*this, abs_n, sign);
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(unsigned int n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ write_int(*this, n, 0);
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+
+ostream& ostream::operator<<(long n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ int sign = 1;
+ unsigned long abs_n = (unsigned long)n;
+ if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
+ abs_n = -((unsigned long)n), sign = -1;
+ write_int(*this, abs_n, sign);
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(unsigned long n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ write_int(*this, n, 0);
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+ostream& ostream::operator<<(long long n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ int sign = 1;
+ unsigned long long abs_n = (unsigned long long)n;
+ if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
+ abs_n = -((unsigned long long)n), sign = -1;
+ write_int(*this, abs_n, sign);
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+
+ostream& ostream::operator<<(unsigned long long n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ write_int(*this, n, 0);
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+#endif /*__GNUC__*/
+
+ostream& ostream::operator<<(double n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ // Uses __cvt_double (renamed from static cvt), in Chris Torek's
+ // stdio implementation. The setup code uses the same logic
+ // as in __vsbprintf.C (also based on Torek's code).
+ int format_char;
+ if ((flags() & ios::floatfield) == ios::fixed)
+ format_char = 'f';
+ else if ((flags() & ios::floatfield) == ios::scientific)
+ format_char = flags() & ios::uppercase ? 'E' : 'e';
+ else
+ format_char = flags() & ios::uppercase ? 'G' : 'g';
+
+ int prec = precision();
+ if (prec <= 0 && !(flags() & ios::fixed))
+ prec = 6; /* default */
+
+ // Do actual conversion.
+#if _G_HAVE_PRINTF_FP
+ {
+ struct printf_info info = { prec: prec,
+ width: width(0),
+ spec: format_char,
+ is_long_double: 0,
+ is_short: 0,
+ is_long: 0,
+ alt: (flags() & ios::showpoint) != 0,
+ space: 0,
+ left: (flags() & ios::left) != 0,
+ showsign: (flags() & ios::showpos) != 0,
+ group: 0,
+#if defined __GLIBC__ && __GLIBC__ >= 2
+ extra: 0,
+#if __GLIBC_MINOR__ >= 1
+ is_char: 0,
+#endif
+#endif
+ pad: fill()
+ };
+ const void *ptr = (const void *) &n;
+ if (__printf_fp (rdbuf(), &info, &ptr) < 0)
+ set(ios::badbit|ios::failbit);
+ }
+#elif defined _IO_USE_DTOA
+ if (_IO_outfloat(n, rdbuf(), format_char, width(0),
+ prec, flags(),
+ flags() & ios::showpos ? '+' : 0,
+ fill()) < 0)
+ set(ios::badbit|ios::failbit); // ??
+#else
+ int fpprec = 0; // 'Extra' (suppressed) floating precision.
+ if (prec > MAXFRACT) {
+ if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
+ fpprec = prec - MAXFRACT;
+ prec = MAXFRACT;
+ }
+ int negative;
+ char buf[BUF];
+ int sign = '\0';
+ char *cp = buf;
+ *cp = 0;
+ int size = __cvt_double(n, prec,
+ flags() & ios::showpoint ? 0x80 : 0,
+ &negative,
+ format_char, cp, buf + sizeof(buf));
+ if (negative) sign = '-';
+ else if (flags() & ios::showpos) sign = '+';
+ if (*cp == 0)
+ cp++;
+
+ // Calculate padding.
+ int fieldsize = size + fpprec;
+ if (sign) fieldsize++;
+ int padding = 0;
+ int w = width(0);
+ if (fieldsize < w)
+ padding = w - fieldsize;
+
+ // Do actual output.
+ register streambuf* sbuf = rdbuf();
+ register i;
+ char fill_char = fill();
+ ios::fmtflags pad_kind =
+ flags() & (ios::left|ios::right|ios::internal);
+ if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
+ && pad_kind != (ios::fmtflags)ios::internal)
+ for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+ if (sign)
+ sbuf->sputc(sign);
+ if (pad_kind == (ios::fmtflags)ios::internal)
+ for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+
+ // Emit the actual concented field, followed by extra zeros.
+ _IO_sputn (sbuf, cp, size);
+ for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
+
+ if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
+ for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+#endif
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+#if _G_HAVE_LONG_DOUBLE_IO
+ostream& ostream::operator<<(long double n)
+{
+ if (opfx())
+ {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ int format_char;
+ if ((flags() & ios::floatfield) == ios::fixed)
+ format_char = 'f';
+ else if ((flags() & ios::floatfield) == ios::scientific)
+ format_char = flags() & ios::uppercase ? 'E' : 'e';
+ else
+ format_char = flags() & ios::uppercase ? 'G' : 'g';
+
+ int prec = precision();
+ if (prec <= 0 && !(flags() & ios::fixed))
+ prec = 6; /* default */
+
+#if _G_HAVE_PRINTF_FP
+ // Do actual conversion.
+ struct printf_info info = { prec: prec,
+ width: width(0),
+ spec: format_char,
+ is_long_double: 1,
+ is_short: 0,
+ is_long: 0,
+ alt: (flags() & ios::showpoint) != 0,
+ space: 0,
+ left: (flags() & ios::left) != 0,
+ showsign: (flags() & ios::showpos) != 0,
+ group: 0,
+#if defined __GLIBC__ && __GLIBC__ >= 2
+ extra: 0,
+#if __GLIBC_MINOR__ >= 1
+ is_char: 0,
+#endif
+#endif
+ pad: fill()
+ };
+
+ const void *ptr = (const void *) &n;
+
+ if (__printf_fp (rdbuf(), &info, &ptr) < 0)
+ set (ios::badbit|ios::failbit);
+#else
+# error "long double I/O using dtoa or cvt_double is not implemented"
+#endif
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+#endif
+
+ostream& ostream::operator<<(const char *s)
+{
+ if (opfx())
+ {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ if (s == NULL)
+ s = "(null)";
+ int len = strlen(s);
+ int w = width(0);
+// FIXME: Should we: if (w && len>w) len = w;
+ char fill_char = fill();
+ register streambuf *sbuf = rdbuf();
+ register int padding = w > len ? w - len : 0;
+ if (!(flags() & ios::left) && padding > 0) // Default adjustment.
+ if (_IO_padn(sbuf, fill_char, padding) != padding)
+ {
+ set(ios::badbit);
+ goto failed;
+ }
+ if (_IO_sputn (sbuf, s, len) != len)
+ {
+ set(ios::badbit);
+ goto failed;
+ }
+ if (flags() & ios::left && padding > 0) // Left adjustment.
+ if (_IO_padn(sbuf, fill_char, padding) != padding)
+ set(ios::badbit);
+ osfx();
+ failed:
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+#if 0
+ostream& ostream::operator<<(const void *p)
+{ Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
+#endif
+
+ostream& ostream::operator<<(register streambuf* sbuf)
+{
+ if (opfx())
+ {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ char buffer[_IO_BUFSIZ];
+ register streambuf* outbuf = _strbuf;
+ for (;;)
+ {
+ _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
+ if (count <= 0)
+ break;
+ if (_IO_sputn(outbuf, buffer, count) != count)
+ {
+ set(ios::badbit);
+ break;
+ }
+ }
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+ostream::ostream(streambuf* sb, ostream* tied)
+{
+ init (sb, tied);
+}
+
+ostream& ostream::seekp(streampos pos)
+{
+ pos = _strbuf->pubseekpos(pos, ios::out);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+ostream& ostream::seekp(streamoff off, _seek_dir dir)
+{
+ streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos ostream::tellp()
+{
+#if 1
+ streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
+#else
+ streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
+#endif
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+ostream& ostream::flush()
+{
+ if (_strbuf->sync())
+ set(ios::badbit);
+ return *this;
+}
+
+ostream& flush(ostream& outs)
+{
+ return outs.flush();
+}
+
+istream& ws(istream& ins)
+{
+ if (ins.ipfx1()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ ins._strbuf);
+ int ch = skip_ws(ins._strbuf);
+ if (ch == EOF)
+ ins.set(ios::eofbit);
+ else
+ ins._strbuf->sputbackc(ch);
+ ins.isfx();
+ _IO_cleanup_region_end (0);
+ }
+ return ins;
+}
+
+// Skip white-space. Return 0 on failure (EOF), or 1 on success.
+// Differs from ws() manipulator in that failbit is set on EOF.
+// Called by ipfx() and ipfx0() if needed.
+
+int istream::_skip_ws()
+{
+ int ch = skip_ws(_strbuf);
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ return 0;
+ }
+ else {
+ _strbuf->sputbackc(ch);
+ return 1;
+ }
+}
+
+ostream& ends(ostream& outs)
+{
+ outs.put('\0');
+ return outs;
+}
+
+ostream& endl(ostream& outs)
+{
+ return flush(outs.put('\n'));
+}
+
+istream& lock(istream& ins)
+{
+ _IO_flockfile (ins._strbuf);
+ return ins;
+}
+istream& unlock(istream& ins)
+{
+ _IO_funlockfile (ins._strbuf);
+ return ins;
+}
+ostream& lock(ostream& outs)
+{
+ _IO_flockfile (outs._strbuf);
+ return outs;
+}
+ostream& unlock(ostream& outs)
+{
+ _IO_funlockfile (outs._strbuf);
+ return outs;
+}
+
+
+ostream& ostream::write(const char *s, streamsize n)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ if (_IO_sputn(_strbuf, s, n) != n)
+ set(ios::failbit);
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+void ostream::do_osfx()
+{
+ if (flags() & ios::unitbuf)
+ flush();
+ if (flags() & ios::stdio) {
+ fflush(stdout);
+ fflush(stderr);
+ }
+}
+
+iostream::iostream(streambuf* sb, ostream* tied)
+{
+ init (sb, tied);
+}
+
+// NOTE: extension for compatibility with old libg++.
+// Not really compatible with fistream::close().
+#ifdef _STREAM_COMPAT
+void ios::close()
+{
+ if (_strbuf->_flags & _IO_IS_FILEBUF)
+ ((struct filebuf*)rdbuf())->close();
+ else if (_strbuf != NULL)
+ rdbuf()->sync();
+ _strbuf = NULL;
+ _state = badbit;
+}
+
+int istream::skip(int i)
+{
+ int old = (_flags & ios::skipws) != 0;
+ if (i)
+ _flags |= ios::skipws;
+ else
+ _flags &= ~ios::skipws;
+ return old;
+}
+#endif
diff --git a/gnu/dist/libio/iostream.h b/gnu/dist/libio/iostream.h
new file mode 100644
index 00000000000..f3de3639906
--- /dev/null
+++ b/gnu/dist/libio/iostream.h
@@ -0,0 +1,272 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _IOSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _IOSTREAM_H
+
+#include <streambuf.h>
+
+extern "C++" {
+class istream; class ostream;
+typedef ios& (*__manip)(ios&);
+typedef istream& (*__imanip)(istream&);
+typedef ostream& (*__omanip)(ostream&);
+
+extern istream& ws(istream& ins);
+extern ostream& flush(ostream& outs);
+extern ostream& endl(ostream& outs);
+extern ostream& ends(ostream& outs);
+
+class ostream : virtual public ios
+{
+ // NOTE: If fields are changed, you must fix _fake_ostream in stdstreams.C!
+ void do_osfx();
+ public:
+ ostream() { }
+ ostream(streambuf* sb, ostream* tied=NULL);
+ int opfx() {
+ if (!good()) return 0;
+ else { if (_tie) _tie->flush(); _IO_flockfile(_strbuf); return 1;} }
+ void osfx() { _IO_funlockfile(_strbuf);
+ if (flags() & (ios::unitbuf|ios::stdio))
+ do_osfx(); }
+ ostream& flush();
+ ostream& put(char c) { _strbuf->sputc(c); return *this; }
+#ifdef _STREAM_COMPAT
+ /* Temporary binary compatibility. REMOVE IN NEXT RELEASE. */
+ ostream& put(unsigned char c) { return put((char)c); }
+ ostream& put(signed char c) { return put((char)c); }
+#endif
+ ostream& write(const char *s, streamsize n);
+ ostream& write(const unsigned char *s, streamsize n)
+ { return write((const char*)s, n);}
+ ostream& write(const signed char *s, streamsize n)
+ { return write((const char*)s, n);}
+ ostream& write(const void *s, streamsize n)
+ { return write((const char*)s, n);}
+ ostream& seekp(streampos);
+ ostream& seekp(streamoff, _seek_dir);
+ streampos tellp();
+ ostream& form(const char *format ...);
+ ostream& vform(const char *format, _IO_va_list args);
+
+ ostream& operator<<(char c);
+ ostream& operator<<(unsigned char c) { return (*this) << (char)c; }
+ ostream& operator<<(signed char c) { return (*this) << (char)c; }
+ ostream& operator<<(const char *s);
+ ostream& operator<<(const unsigned char *s)
+ { return (*this) << (const char*)s; }
+ ostream& operator<<(const signed char *s)
+ { return (*this) << (const char*)s; }
+ ostream& operator<<(const void *p);
+ ostream& operator<<(int n);
+ ostream& operator<<(unsigned int n);
+ ostream& operator<<(long n);
+ ostream& operator<<(unsigned long n);
+#if defined(__GNUC__)
+ __extension__ ostream& operator<<(long long n);
+ __extension__ ostream& operator<<(unsigned long long n);
+#endif
+ ostream& operator<<(short n) {return operator<<((int)n);}
+ ostream& operator<<(unsigned short n) {return operator<<((unsigned int)n);}
+#if _G_HAVE_BOOL
+ ostream& operator<<(bool b) { return operator<<((int)b); }
+#endif
+ ostream& operator<<(double n);
+ ostream& operator<<(float n) { return operator<<((double)n); }
+#if _G_HAVE_LONG_DOUBLE_IO
+ ostream& operator<<(long double n);
+#else
+ ostream& operator<<(long double n) { return operator<<((double)n); }
+#endif
+ ostream& operator<<(__omanip func) { return (*func)(*this); }
+ ostream& operator<<(__manip func) {(*func)(*this); return *this;}
+ ostream& operator<<(streambuf*);
+#ifdef _STREAM_COMPAT
+ streambuf* ostreambuf() const { return _strbuf; }
+#endif
+};
+
+class istream : virtual public ios
+{
+ // NOTE: If fields are changed, you must fix _fake_istream in stdstreams.C!
+protected:
+ _IO_size_t _gcount;
+
+ int _skip_ws();
+ public:
+ istream(): _gcount (0) { }
+ istream(streambuf* sb, ostream*tied=NULL);
+ istream& get(char* ptr, int len, char delim = '\n');
+ istream& get(unsigned char* ptr, int len, char delim = '\n')
+ { return get((char*)ptr, len, delim); }
+ istream& get(char& c);
+ istream& get(unsigned char& c) { return get((char&)c); }
+ istream& getline(char* ptr, int len, char delim = '\n');
+ istream& getline(unsigned char* ptr, int len, char delim = '\n')
+ { return getline((char*)ptr, len, delim); }
+ istream& get(signed char& c) { return get((char&)c); }
+ istream& get(signed char* ptr, int len, char delim = '\n')
+ { return get((char*)ptr, len, delim); }
+ istream& getline(signed char* ptr, int len, char delim = '\n')
+ { return getline((char*)ptr, len, delim); }
+ istream& read(char *ptr, streamsize n);
+ istream& read(unsigned char *ptr, streamsize n)
+ { return read((char*)ptr, n); }
+ istream& read(signed char *ptr, streamsize n)
+ { return read((char*)ptr, n); }
+ istream& read(void *ptr, streamsize n)
+ { return read((char*)ptr, n); }
+ istream& get(streambuf& sb, char delim = '\n');
+ istream& gets(char **s, char delim = '\n');
+ int ipfx(int need = 0) {
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ _IO_flockfile(_strbuf);
+ if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush();
+ if (!need && (flags() & ios::skipws)) return _skip_ws();
+ else return 1;
+ }
+ }
+ int ipfx0() { // Optimized version of ipfx(0).
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ _IO_flockfile(_strbuf);
+ if (_tie) _tie->flush();
+ if (flags() & ios::skipws) return _skip_ws();
+ else return 1;
+ }
+ }
+ int ipfx1() { // Optimized version of ipfx(1).
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ _IO_flockfile(_strbuf);
+ if (_tie && rdbuf()->in_avail() == 0) _tie->flush();
+ return 1;
+ }
+ }
+ void isfx() { _IO_funlockfile(_strbuf); }
+ int get() { if (!ipfx1()) return EOF;
+ else { int ch = _strbuf->sbumpc();
+ if (ch == EOF) set(ios::eofbit);
+ return ch;
+ } }
+ int peek();
+ _IO_size_t gcount() { return _gcount; }
+ istream& ignore(int n=1, int delim = EOF);
+ int sync ();
+ istream& seekg(streampos);
+ istream& seekg(streamoff, _seek_dir);
+ streampos tellg();
+ istream& putback(char ch) {
+ if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::badbit);
+ return *this;}
+ istream& unget() {
+ if (good() && _strbuf->sungetc() == EOF) clear(ios::badbit);
+ return *this;}
+ istream& scan(const char *format ...);
+ istream& vscan(const char *format, _IO_va_list args);
+#ifdef _STREAM_COMPAT
+ istream& unget(char ch) { return putback(ch); }
+ int skip(int i);
+ streambuf* istreambuf() const { return _strbuf; }
+#endif
+
+ istream& operator>>(char*);
+ istream& operator>>(unsigned char* p) { return operator>>((char*)p); }
+ istream& operator>>(signed char*p) { return operator>>((char*)p); }
+ istream& operator>>(char& c);
+ istream& operator>>(unsigned char& c) {return operator>>((char&)c);}
+ istream& operator>>(signed char& c) {return operator>>((char&)c);}
+ istream& operator>>(int&);
+ istream& operator>>(long&);
+#if defined(__GNUC__)
+ __extension__ istream& operator>>(long long&);
+ __extension__ istream& operator>>(unsigned long long&);
+#endif
+ istream& operator>>(short&);
+ istream& operator>>(unsigned int&);
+ istream& operator>>(unsigned long&);
+ istream& operator>>(unsigned short&);
+#if _G_HAVE_BOOL
+ istream& operator>>(bool&);
+#endif
+ istream& operator>>(float&);
+ istream& operator>>(double&);
+ istream& operator>>(long double&);
+ istream& operator>>( __manip func) {(*func)(*this); return *this;}
+ istream& operator>>(__imanip func) { return (*func)(*this); }
+ istream& operator>>(streambuf*);
+};
+
+class iostream : public istream, public ostream
+{
+ public:
+ iostream() { }
+ iostream(streambuf* sb, ostream*tied=NULL);
+};
+
+class _IO_istream_withassign : public istream {
+public:
+ _IO_istream_withassign& operator=(istream&);
+ _IO_istream_withassign& operator=(_IO_istream_withassign& rhs)
+ { return operator= (static_cast<istream&> (rhs)); }
+};
+
+class _IO_ostream_withassign : public ostream {
+public:
+ _IO_ostream_withassign& operator=(ostream&);
+ _IO_ostream_withassign& operator=(_IO_ostream_withassign& rhs)
+ { return operator= (static_cast<ostream&> (rhs)); }
+};
+
+extern _IO_istream_withassign cin;
+// clog->rdbuf() == cerr->rdbuf()
+extern _IO_ostream_withassign cout, cerr;
+
+extern _IO_ostream_withassign clog
+#if _G_CLOG_CONFLICT
+__asm__ ("__IO_clog")
+#endif
+;
+
+extern istream& lock(istream& ins);
+extern istream& unlock(istream& ins);
+extern ostream& lock(ostream& outs);
+extern ostream& unlock(ostream& outs);
+
+struct Iostream_init { } ; // Compatibility hack for AT&T library.
+
+inline ios& dec(ios& i)
+{ i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; }
+inline ios& hex(ios& i)
+{ i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; }
+inline ios& oct(ios& i)
+{ i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; }
+} // extern "C++"
+
+#endif /*!_IOSTREAM_H*/
diff --git a/gnu/dist/libio/iostream.texi b/gnu/dist/libio/iostream.texi
new file mode 100644
index 00000000000..54ccced6e71
--- /dev/null
+++ b/gnu/dist/libio/iostream.texi
@@ -0,0 +1,1971 @@
+\input texinfo @c -*-Texinfo-*-
+@c Copyright (c) 1993 Free Software Foundation, Inc.
+
+@c %**start of header
+@setfilename iostream.info
+@settitle The GNU C++ Iostream Library
+@setchapternewpage odd
+@c %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* iostream: (iostream). The C++ input/output facility.
+END-INFO-DIR-ENTRY
+@end format
+
+This file describes libio, the GNU library for C++ iostreams and C stdio.
+
+libio includes software developed by the University of California,
+Berkeley.
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@finalout
+@syncodeindex fn cp
+@syncodeindex vr cp
+
+@titlepage
+@title The GNU C++ Iostream Library
+@subtitle Reference Manual for @code{libio} Version 0.64
+@sp 3
+@author Per Bothner @hfill @code{bothner@@cygnus.com}
+@author Cygnus Support @hfill @code{doc@@cygnus.com}
+@page
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1993 Free Software Foundation, Inc.
+
+@code{libio} includes software developed by the University of
+California, Berkeley.
+
+@code{libio} uses floating-point software written by David M. Gay, which
+includes the following notice:
+
+@quotation
+The author of this software is David M. Gay.
+
+Copyright (c) 1991 by AT&T.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose without fee is hereby granted, provided that this entire notice
+is included in all copies of any software which is or includes a copy
+or modification of this software and in all copies of the supporting
+documentation for such software.
+
+THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+@end quotation
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+
+@ifinfo
+@node Top
+@top The GNU C++ Iostream Library
+
+This file provides reference information on the GNU C++ iostream library
+(@code{libio}), version 0.64.
+
+@menu
+* Introduction::
+* Operators:: Operators and default streams.
+* Streams:: Stream classes.
+* Files and Strings:: Classes for files and strings.
+* Streambuf:: Using the streambuf layer.
+* Stdio:: C input and output.
+* Index::
+@end menu
+@end ifinfo
+
+@node Introduction
+@chapter Introduction
+
+The iostream classes implement most of the features of AT&T version 2.0
+iostream library classes, and most of the features of the ANSI X3J16
+library draft (which is based on the AT&T design).
+
+This manual is meant as a reference; for tutorial material on iostreams,
+see the corresponding section of any recent popular introduction to C++.
+
+@menu
+* Copying:: Special GNU licensing terms for libio.
+* Acknowledgements:: Contributors to GNU iostream.
+@end menu
+
+@node Copying
+@section Licensing terms for @code{libio}
+
+Since the @code{iostream} classes are so fundamental to standard C++,
+the Free Software Foundation has agreed to a special exception to its
+standard license, when you link programs with @code{libio.a}:
+
+@quotation
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+@end quotation
+
+The code is under the @sc{gnu} General Public License (version 2) for
+all other purposes than linking with this library; that means that you
+can modify and redistribute the code as usual, but remember that if you
+do, your modifications, and anything you link with the modified code,
+must be available to others on the same terms.
+
+These functions are also available as part of the @code{libg++}
+library; if you link with that library instead of @code{libio}, the
+@sc{gnu} Library General Public License applies.
+
+@node Acknowledgements
+@section Acknowledgements
+
+Per Bothner wrote most of the @code{iostream} library, but some portions
+have their origins elsewhere in the free software community. Heinz
+Seidl wrote the IO manipulators. The floating-point conversion software
+is by David M. Gay of AT&T. Some code was derived from parts of BSD
+4.4, which was written at the University of California, Berkeley.
+
+The iostream classes are found in the @code{libio} library. An early
+version was originally distributed in @code{libg++}, and they are still
+included there as well, for convenience if you need other @code{libg++}
+classes. Doug Lea was the original author of @code{libg++}, and some of
+the file-management code still in @code{libio} is his.
+
+Various people found bugs or offered suggestions. Hongjiu Lu worked
+hard to use the library as the default stdio implementation for Linux,
+and has provided much stress-testing of the library.
+
+@node Operators
+@chapter Operators and Default Streams
+
+The @sc{gnu} iostream library, @file{libio}, implements the standard
+input and output facilities for C++. These facilities are roughly
+analogous (in their purpose and ubiquity, at least) with those defined
+by the C @file{stdio} functions.
+
+Although these definitions come from a library, rather than being part
+of the ``core language'', they are sufficiently central to be specified
+in the latest working papers for C++.
+
+You can use two operators defined in this library for basic input and
+output operations. They are familiar from any C++ introductory
+textbook: @code{<<} for output, and @code{>>} for input. (Think of data
+flowing in the direction of the ``arrows''.)
+
+These operators are often used in conjunction with three streams that
+are open by default:
+
+@deftypevar ostream cout
+The standard output stream, analogous to the C @code{stdout}.
+@end deftypevar
+
+@deftypevar istream cin
+The standard input stream, analogous to the C @code{stdin}.
+@end deftypevar
+
+@deftypevar ostream cerr
+An alternative output stream for errors, analogous to the C
+@code{stderr}.
+@end deftypevar
+
+@noindent
+For example, this bare-bones C++ version of the traditional ``hello''
+program uses @code{<<} and @code{cout}:
+
+@example
+#include <iostream.h>
+
+int main(int argc, char **argv)
+@{
+ cout << "Well, hi there.\n";
+ return 0;
+@}
+@end example
+
+Casual use of these operators may be seductive, but---other than in
+writing throwaway code for your own use---it is not necessarily simpler
+than managing input and output in any other language. For example,
+robust code should check the state of the input and output streams
+between operations (for example, using the method @code{good}).
+@xref{States,,Checking the state of a stream}. You may also need to
+adjust maximum input or output field widths, using manipulators like
+@code{setw} or @code{setprecision}.
+
+@defop Operator ostream <<
+Write output to an open output stream of class @code{ostream}.
+Defined by this library on any @var{object} of a C++ primitive type, and
+on other classes of the library. You can overload the definition for any
+of your own applications' classes.
+
+Returns a reference to the implied argument @code{*this} (the open stream it
+writes on), permitting statements like
+@example
+cout << "The value of i is " << i << "\n";
+@end example
+@end defop
+
+@defop Operator istream >>
+Read input from an open input stream of class @code{istream}. Defined
+by this library on primitive numeric, pointer, and string types; you can
+extend the definition for any of your own applications' classes.
+
+Returns a reference to the implied argument @code{*this} (the open stream
+it reads), permitting multiple inputs in one statement.
+@end defop
+
+@node Streams
+@chapter Stream Classes
+
+The previous chapter referred in passing to the classes @code{ostream}
+and @code{istream}, for output and input respectively. These classes
+share certain properties, captured in their base class @code{ios}.
+
+@menu
+* Ios:: Shared properties.
+* Ostream:: Managing output streams.
+* Istream:: Managing input streams.
+* Iostream:: Input and output together.
+@end menu
+
+@node Ios
+@section Shared properties: class @code{ios}
+
+The base class @code{ios} provides methods to test and manage the state
+of input or output streams.
+
+@code{ios} delegates the job of actually reading and writing bytes to
+the abstract class @code{streambuf}, which is designed to provide
+buffered streams (compatible with C, in the @sc{gnu} implementation).
+@xref{Streambuf,,Using the @code{streambuf} layer}, for information on
+the facilities available at the @code{streambuf} level.
+
+@deftypefn Constructor {} ios::ios ([streambuf* @var{sb} @w{[, ostream*} @var{tie}])
+The @code{ios} constructor by default initializes a new @code{ios}, and
+if you supply a @code{streambuf} @var{sb} to associate with it, sets the
+state @code{good} in the new @code{ios} object. It also sets the
+default properties of the new object.
+
+@ignore
+@c FIXME--future: this (a) doesn't work, (b) is controversial at ANSI
+An @code{ios} without a @code{streambuf} has the state @code{bad} until
+you supply a @code{streambuf}; you can do that by assigning a new value
+to the @code{ios} with @samp{=}.
+@end ignore
+
+You can also supply an optional second argument @var{tie} to the
+constructor: if present, it is an initial value for @code{ios::tie}, to
+associate the new @code{ios} object with another stream.
+@end deftypefn
+
+@deftypefn Destructor {} ios::~ios ()
+The @code{ios} destructor is virtual, permitting application-specific
+behavior when a stream is closed---typically, the destructor frees any
+storage associated with the stream and releases any other associated
+objects.
+@end deftypefn
+
+@c FIXME-future: Is @deftypefn really the best way of displaying these?
+
+@c FIXME-future: Undocumented: ios::_throw_failure, ios::exceptions; things
+@c controlled by _STREAM_COMPAT; ios::Init; ios::_IO_fix_vtable.
+
+@menu
+* States:: Checking the state of a stream.
+* Format Control:: Choices in formatting.
+* Manipulators:: Convenient ways of changing stream properties.
+* Extending:: Extended data fields.
+* Synchronization:: Synchronizing related streams.
+* Streambuf from Ios:: Reaching the underlying streambuf.
+@end menu
+
+@node States
+@subsection Checking the state of a stream
+
+Use this collection of methods to test for (or signal) errors and other
+exceptional conditions of streams:
+
+@deftypefn Method {ios::operator void*} () const
+You can do a quick check on the state of the most recent operation on a
+stream by examining a pointer to the stream itself. The pointer is
+arbitrary except for its truth value; it is true if no failures have
+occurred (@code{ios::fail} is not true). For example, you might ask for
+input on @code{cin} only if all prior output operations succeeded:
+
+@example
+if (cout)
+@{
+ // Everything OK so far
+ cin >> new_value;
+ @dots{}
+@}
+@end example
+@end deftypefn
+
+@deftypefn Method {ios::operator !} () const
+In case it is more convenient to check whether something has failed, the
+operator @code{!} returns true if @code{ios::fail} is true (an operation
+has failed). For example,
+you might issue an error message if input failed:
+
+@example
+if (!cin)
+@{
+ // Oops
+ cerr << "Eh?\n";
+@}
+@end example
+@end deftypefn
+
+@deftypefn Method iostate ios::rdstate () const
+Return the state flags for this stream. The value is from the
+enumeration @code{iostate}. You can test for any combination of
+
+@vtable @code
+@item goodbit
+There are no indications of exceptional states on this stream.
+
+@item eofbit
+End of file.
+
+@item failbit
+An operation has failed on this stream; this usually indicates bad
+format of input.
+
+@item badbit
+The stream is unusable.
+@end vtable
+@end deftypefn
+
+@deftypefn Method void ios::setstate (iostate @var{state})
+@findex ios::set
+Set the state flag for this stream to @var{state} @emph{in addition to}
+any state flags already set. Synonym (for upward compatibility):
+@code{ios::set}.
+
+See @code{ios::clear} to set the stream state without regard to existing
+state flags. See @code{ios::good}, @code{ios::eof}, @code{ios::fail},
+and @code{ios::bad}, to test the state.
+@end deftypefn
+
+@deftypefn Method int ios::good () const
+Test the state flags associated with this stream; true if no error
+indicators are set.
+@end deftypefn
+
+@deftypefn Method int ios::bad () const
+Test whether a stream is marked as unusable. (Whether
+@code{ios::badbit} is set.)
+@end deftypefn
+
+@deftypefn Method int ios::eof () const
+True if end of file was reached on this stream. (If @code{ios::eofbit}
+is set.)
+@end deftypefn
+
+@deftypefn Method int ios::fail () const
+Test for any kind of failure on this stream: @emph{either} some
+operation failed, @emph{or} the stream is marked as bad. (If either
+@code{ios::failbit} or @code{ios::badbit} is set.)
+@end deftypefn
+
+@deftypefn Method void ios::clear (iostate @var{state})
+@c FIXME-future: There is some complication to do with buffering and _throw_failure
+Set the state indication for this stream to the argument @var{state}.
+You may call @code{ios::clear} with no argument, in which case the state
+is set to @code{good} (no errors pending).
+
+See @code{ios::good}, @code{ios::eof}, @code{ios::fail}, and
+@code{ios::bad}, to test the state; see @code{ios::set} or
+@code{ios::setstate} for an alternative way of setting the state.
+@end deftypefn
+
+@node Format Control
+@subsection Choices in formatting
+
+These methods control (or report on) settings for some details of
+controlling streams, primarily to do with formatting output:
+
+@deftypefn Method char ios::fill () const
+Report on the padding character in use.
+@end deftypefn
+
+@deftypefn Method char ios::fill (char @var{padding})
+Set the padding character. You can also use the manipulator
+@code{setfill}. @xref{Manipulators,,Changing stream properties in
+expressions}.
+
+Default: blank.
+@end deftypefn
+
+@deftypefn Method int ios::precision () const
+Report the number of significant digits currently in use for output of
+floating point numbers.
+
+Default: @code{6}.
+@end deftypefn
+
+@deftypefn Method int ios::precision (int @var{signif})
+Set the number of significant digits (for input and output numeric
+conversions) to @var{signif}.
+
+@findex setprecision
+@cindex setting @code{ios::precision}
+You can also use the manipulator @code{setprecision} for this purpose.
+@xref{Manipulators,,Changing stream properties using manipulators}.
+@end deftypefn
+
+@deftypefn Method int ios::width () const
+Report the current output field width setting (the number of
+characters to write on the next @samp{<<} output operation).
+
+Default: @code{0}, which means to use as many characters as necessary.
+@end deftypefn
+
+@deftypefn Method int ios::width (int @var{num})
+Set the input field width setting to @var{num}. Return the
+@emph{previous} value for this stream.
+
+@findex setw
+@cindex setting @code{ios::width}
+This value resets to zero (the default) every time you use @samp{<<}; it is
+essentially an additional implicit argument to that operator. You can
+also use the manipulator @code{setw} for this purpose.
+@xref{Manipulators,,Changing stream properties using manipulators}.
+@end deftypefn
+
+@need 2000
+@deftypefn Method fmtflags ios::flags () const
+Return the current value of the complete collection of flags controlling
+the format state. These are the flags and their meanings when set:
+
+@vtable @code
+@item ios::dec
+@itemx ios::oct
+@itemx ios::hex
+What numeric base to use in converting integers from internal to display
+representation, or vice versa: decimal, octal, or hexadecimal,
+respectively. (You can change the base using the manipulator
+@code{setbase}, or any of the manipulators @code{dec}, @code{oct}, or
+@code{hex}; @pxref{Manipulators,,Changing stream properties in
+expressions}.)
+
+On input, if none of these flags is set, read numeric constants
+according to the prefix: decimal if no prefix (or a @samp{.} suffix),
+octal if a @samp{0} prefix is present, hexadecimal if a @samp{0x} prefix
+is present.
+
+Default: @code{dec}.
+
+@item ios::fixed
+Avoid scientific notation, and always show a fixed number of digits after
+the decimal point, according to the output precision in effect.
+Use @code{ios::precision} to set precision.
+
+@item ios::left
+@itemx ios::right
+@itemx ios::internal
+Where output is to appear in a fixed-width field; left-justified,
+right-justified, or with padding in the middle (e.g. between a numeric
+sign and the associated value), respectively.
+
+@item ios::scientific
+Use scientific (exponential) notation to display numbers.
+
+@item ios::showbase
+Display the conventional prefix as a visual indicator of the conversion
+base: no prefix for decimal, @samp{0} for octal, @samp{0x} for hexadecimal.
+
+@item ios::showpoint
+Display a decimal point and trailing zeros after it to fill out numeric
+fields, even when redundant.
+
+@item ios::showpos
+Display a positive sign on display of positive numbers.
+
+@item ios::skipws
+Skip white space. (On by default).
+
+@item ios::stdio
+Flush the C @code{stdio} streams @code{stdout} and @code{stderr} after
+each output operation (for programs that mix C and C++ output conventions).
+
+@item ios::unitbuf
+Flush after each output operation.
+
+@item ios::uppercase
+Use upper-case characters for the non-numeral elements in numeric
+displays; for instance, @samp{0X7A} rather than @samp{0x7a}, or
+@samp{3.14E+09} rather than @samp{3.14e+09}.
+@end vtable
+@end deftypefn
+
+@deftypefn Method fmtflags ios::flags (fmtflags @var{value})
+Set @var{value} as the complete collection of flags controlling the
+format state. The flag values are described under @samp{ios::flags ()}.
+
+Use @code{ios::setf} or @code{ios::unsetf} to change one property at a
+time.
+@end deftypefn
+
+@deftypefn Method fmtflags ios::setf (fmtflags @var{flag})
+Set one particular flag (of those described for @samp{ios::flags ()};
+return the complete collection of flags @emph{previously} in effect.
+(Use @code{ios::unsetf} to cancel.)
+@end deftypefn
+
+@deftypefn Method fmtflags ios::setf (fmtflags @var{flag}, fmtflags @var{mask})
+Clear the flag values indicated by @var{mask}, then set any of them that
+are also in @var{flag}. (Flag values are described for @samp{ios::flags
+()}.) Return the complete collection of flags @emph{previously} in
+effect. (See @code{ios::unsetf} for another way of clearing flags.)
+@end deftypefn
+
+@deftypefn Method fmtflags ios::unsetf (fmtflags @var{flag})
+Make certain @var{flag} (a combination of flag values described for
+@samp{ios::flags ()}) is not set for this stream; converse of
+@code{ios::setf}. Returns the old values of those flags.
+@c FIXME-future: should probably be fixed to give same result as setf.
+@end deftypefn
+
+@node Manipulators
+@subsection Changing stream properties using manipulators
+
+For convenience, @var{manipulators} provide a way to change certain
+properties of streams, or otherwise affect them, in the middle of
+expressions involving @samp{<<} or @samp{>>}. For example, you might
+write
+
+@example
+cout << "|" << setfill('*') << setw(5) << 234 << "|";
+@end example
+
+@noindent
+to produce @samp{|**234|} as output.
+
+@deftypefn Manipulator {} ws
+Skip whitespace.
+@end deftypefn
+
+@deftypefn Manipulator {} flush
+Flush an output stream. For example, @samp{cout << @dots{} <<flush;}
+has the same effect as @samp{cout << @dots{}; cout.flush();}.
+@end deftypefn
+
+@deftypefn Manipulator {} endl
+Write an end of line character @samp{\n}, then flushes the output stream.
+@end deftypefn
+
+@deftypefn Manipulator {} ends
+Write @samp{\0} (the string terminator character).
+@end deftypefn
+
+@deftypefn Manipulator {} setprecision (int @var{signif})
+You can change the value of @code{ios::precision} in @samp{<<}
+expressions with the manipulator @samp{setprecision(@var{signif})}; for
+example,
+
+@example
+cout << setprecision(2) << 4.567;
+@end example
+
+@noindent
+prints @samp{4.6}. Requires @file{#include <iomanip.h>}.
+@end deftypefn
+
+@deftypefn Manipulator {} setw (int @var{n})
+You can change the value of @code{ios::width} in @samp{<<} expressions
+with the manipulator @samp{setw(@var{n})}; for example,
+
+@example
+cout << setw(5) << 234;
+@end example
+
+@noindent
+prints @w{@samp{ 234}} with two leading blanks. Requires @file{#include
+<iomanip.h>}.
+@end deftypefn
+
+@deftypefn Manipulator {} setbase (int @var{base})
+Where @var{base} is one of @code{10} (decimal), @code{8} (octal), or
+@code{16} (hexadecimal), change the base value for numeric
+representations. Requires @file{#include <iomanip.h>}.
+@end deftypefn
+
+@deftypefn Manipulator {} dec
+Select decimal base; equivalent to @samp{setbase(10)}.
+@end deftypefn
+
+@deftypefn Manipulator {} hex
+Select hexadecimal base; equivalent to @samp{setbase(16)}.
+@end deftypefn
+
+@deftypefn Manipulator {} oct
+Select octal base; equivalent to @samp{setbase(8)}.
+@end deftypefn
+
+@deftypefn Manipulator {} setfill (char @var{padding})
+Set the padding character, in the same way as @code{ios::fill}.
+Requires @file{#include <iomanip.h>}.
+@end deftypefn
+
+@node Extending
+@subsection Extended data fields
+
+A related collection of methods allows you to extend this collection of
+flags and parameters for your own applications, without risk of conflict
+between them:
+
+@deftypefn Method {static fmtflags} ios::bitalloc ()
+Reserve a bit (the single bit on in the result) to use as a flag. Using
+@code{bitalloc} guards against conflict between two packages that use
+@code{ios} objects for different purposes.
+
+This method is available for upward compatibility, but is not in the
+@sc{ansi} working paper. The number of bits available is limited; a
+return value of @code{0} means no bit is available.
+@end deftypefn
+
+@deftypefn Method {static int} ios::xalloc ()
+Reserve space for a long integer or pointer parameter. The result is a
+unique nonnegative integer. You can use it as an index to
+@code{ios::iword} or @code{ios::pword}. Use @code{xalloc} to arrange
+for arbitrary special-purpose data in your @code{ios} objects, without
+risk of conflict between packages designed for different purposes.
+@end deftypefn
+
+@deftypefn Method long& ios::iword (int @var{index})
+Return a reference to arbitrary data, of long integer type, stored in an
+@code{ios} instance. @var{index}, conventionally returned from
+@code{ios::xalloc}, identifies what particular data you need.
+@end deftypefn
+
+@deftypefn Method long ios::iword (int @var{index}) const
+Return the actual value of a long integer stored in an @code{ios}.
+@end deftypefn
+
+@deftypefn Method void*& ios::pword (int @var{index})
+Return a reference to an arbitrary pointer, stored in an @code{ios}
+instance. @var{index}, originally returned from @code{ios::xalloc},
+identifies what particular pointer you need.
+@end deftypefn
+
+@deftypefn Method void* ios::pword (int @var{index}) const
+Return the actual value of a pointer stored in an @code{ios}.
+@end deftypefn
+
+@node Synchronization
+@subsection Synchronizing related streams
+
+You can use these methods to synchronize related streams with
+one another:
+
+@deftypefn Method ostream* ios::tie () const
+Report on what output stream, if any, is to be flushed before accessing
+this one. A pointer value of @code{0} means no stream is tied.
+@end deftypefn
+
+@deftypefn Method ostream* ios::tie (ostream* @var{assoc})
+Declare that output stream @var{assoc} must be flushed before accessing
+this stream.
+@end deftypefn
+
+@deftypefn Method int ios::sync_with_stdio ([int @var{switch}])
+Unless iostreams and C @code{stdio} are designed to work together, you
+may have to choose between efficient C++ streams output and output
+compatible with C @code{stdio}. Use @samp{ios::sync_with_stdio()} to
+select C compatibility.
+
+The argument @var{switch} is a @sc{gnu} extension; use @code{0} as the
+argument to choose output that is not necessarily compatible with C
+@code{stdio}. The default value for @var{switch} is @code{1}.
+
+If you install the @code{stdio} implementation that comes with @sc{gnu}
+@code{libio}, there are compatible input/output facilities for both C
+and C++. In that situation, this method is unnecessary---but you may
+still want to write programs that call it, for portability.
+@end deftypefn
+
+@node Streambuf from Ios
+@subsection Reaching the underlying @code{streambuf}
+
+Finally, you can use this method to access the underlying object:
+
+@deftypefn Method streambuf* ios::rdbuf () const
+Return a pointer to the @code{streambuf} object that underlies this
+@code{ios}.
+@end deftypefn
+
+@node Ostream
+@section Managing output streams: class @code{ostream}
+
+Objects of class @code{ostream} inherit the generic methods from
+@code{ios}, and in addition have the following methods available.
+Declarations for this class come from @file{iostream.h}.
+
+@deftypefn Constructor {} ostream::ostream ()
+The simplest form of the constructor for an @code{ostream} simply
+allocates a new @code{ios} object.
+@end deftypefn
+
+@deftypefn Constructor {} ostream::ostream (streambuf* @var{sb} @w{[, ostream} @var{tie}])
+This alternative constructor requires a first argument @var{sb} of type
+@code{streambuf*}, to use an existing open stream for output. It also
+accepts an optional second argument @var{tie}, to specify a related
+@code{ostream*} as the initial value for @code{ios::tie}.
+
+If you give the @code{ostream} a @code{streambuf} explicitly, using
+this constructor, the @var{sb} is @emph{not} destroyed (or deleted or
+closed) when the @code{ostream} is destroyed.
+@end deftypefn
+
+@menu
+* Writing:: Writing on an ostream.
+* Output Position:: Repositioning an ostream.
+* Ostream Housekeeping:: Miscellaneous ostream utilities.
+@end menu
+
+@node Writing
+@subsection Writing on an @code{ostream}
+
+These methods write on an @code{ostream} (you may also use the operator
+@code{<<}; @pxref{Operators,,Operators and Default Streams}).
+
+@deftypefn Method ostream& ostream::put (char @var{c})
+Write the single character @var{c}.
+@end deftypefn
+
+@deftypefn Method ostream& ostream::write (@var{string}, int @var{length})
+Write @var{length} characters of a string to this @code{ostream},
+beginning at the pointer @var{string}.
+
+@var{string} may have any of these types: @code{char*}, @code{unsigned
+char*}, @code{signed char*}.
+@end deftypefn
+
+@deftypefn Method ostream& ostream::form (const char *@var{format}, ...)
+A @sc{gnu} extension, similar to @code{fprintf(@var{file},
+@var{format}, ...)}.
+
+@var{format} is a @code{printf}-style format control string, which is used
+to format the (variable number of) arguments, printing the result on
+this @code{ostream}. See @code{ostream::vform} for a version that uses
+an argument list rather than a variable number of arguments.
+@end deftypefn
+
+@deftypefn Method ostream& ostream::vform (const char *@var{format}, va_list @var{args})
+A @sc{gnu} extension, similar to @code{vfprintf(@var{file},
+@var{format}, @var{args})}.
+
+@var{format} is a @code{printf}-style format control string, which is used
+to format the argument list @var{args}, printing the result on
+this @code{ostream}. See @code{ostream::form} for a version that uses a
+variable number of arguments rather than an argument list.
+@end deftypefn
+
+@node Output Position
+@subsection Repositioning an @code{ostream}
+
+You can control the output position (on output streams that actually
+support positions, typically files) with these methods:
+@c FIXME-future: sort out which classes support this and which
+@c don't; fstream, filebuf? And what is failure condition when not supported?
+
+@deftypefn Method streampos ostream::tellp ()
+Return the current write position in the stream.
+@end deftypefn
+
+@deftypefn Method ostream& ostream::seekp (streampos @var{loc})
+Reset the output position to @var{loc} (which is usually the result of a
+previous call to @code{ostream::tellp}). @var{loc} specifies an
+absolute position in the output stream.
+@end deftypefn
+
+@deftypefn Method ostream& ostream::seekp (streamoff @var{loc}, @var{rel})
+@findex ios::seekdir
+Reset the output position to @var{loc}, relative to the beginning, end,
+or current output position in the stream, as indicated by @var{rel} (a
+value from the enumeration @code{ios::seekdir}):
+
+@vtable @code
+@item beg
+Interpret @var{loc} as an absolute offset from the beginning of the
+file.
+
+@item cur
+Interpret @var{loc} as an offset relative to the current output
+position.
+
+@item end
+Interpret @var{loc} as an offset from the current end of the output
+stream.
+@end vtable
+@end deftypefn
+
+@node Ostream Housekeeping
+@subsection Miscellaneous @code{ostream} utilities
+
+You may need to use these @code{ostream} methods for housekeeping:
+
+@deftypefn Method ostream& flush ()
+Deliver any pending buffered output for this @code{ostream}.
+@end deftypefn
+
+@deftypefn Method int ostream::opfx ()
+@code{opfx} is a @dfn{prefix} method for operations on @code{ostream}
+objects; it is designed to be called before any further processing. See
+@code{ostream::osfx} for the converse.
+@c FIXME-future: specify sometime which methods start with opfx.
+
+@code{opfx} tests that the stream is in state @code{good}, and if so
+flushes any stream tied to this one.
+
+The result is @code{1} when @code{opfx} succeeds; else (if the stream state is
+not @code{good}), the result is @code{0}.
+@end deftypefn
+
+@deftypefn Method void ostream::osfx ()
+@code{osfx} is a @dfn{suffix} method for operations on @code{ostream}
+objects; it is designed to be called at the conclusion of any processing. All
+the @code{ostream} methods end by calling @code{osfx}. See
+@code{ostream::opfx} for the converse.
+
+If the @code{unitbuf} flag is set for this stream, @code{osfx} flushes
+any buffered output for it.
+
+If the @code{stdio} flag is set for this stream, @code{osfx} flushes any
+output buffered for the C output streams @file{stdout} and @file{stderr}.
+@end deftypefn
+
+@node Istream
+@section Managing input streams: class @code{istream}
+
+Class @code{istream} objects are specialized for input; as for
+@code{ostream}, they are derived from @code{ios}, so you can use any of
+the general-purpose methods from that base class. Declarations for this
+class also come from @file{iostream.h}.
+
+@deftypefn Constructor {} istream::istream ()
+When used without arguments, the @code{istream} constructor simply
+allocates a new @code{ios} object and initializes the input counter (the
+value reported by @code{istream::gcount}) to @code{0}.
+@end deftypefn
+
+@deftypefn Constructor {} istream::istream (streambuf *@var{sb} @w{[, ostream} @var{tie}])
+You can also call the constructor with one or two arguments. The first
+argument @var{sb} is a @code{streambuf*}; if you supply this pointer,
+the constructor uses that @code{streambuf} for input.
+You can use the second optional argument @var{tie} to specify a related
+output stream as the initial value for @code{ios::tie}.
+
+If you give the @code{istream} a @code{streambuf} explicitly, using
+this constructor, the @var{sb} is @emph{not} destroyed (or deleted or
+closed) when the @code{ostream} is destroyed.
+@end deftypefn
+
+@menu
+* Char Input:: Reading one character.
+* String Input:: Reading strings.
+* Input Position:: Repositioning an istream.
+* Istream Housekeeping:: Miscellaneous istream utilities.
+@end menu
+
+@node Char Input
+@subsection Reading one character
+
+Use these methods to read a single character from the input stream:
+
+@deftypefn Method int istream::get ()
+Read a single character (or @code{EOF}) from the input stream, returning
+it (coerced to an unsigned char) as the result.
+@end deftypefn
+
+@deftypefn Method istream& istream::get (char& @var{c})
+Read a single character from the input stream, into @code{&@var{c}}.
+@end deftypefn
+
+@deftypefn Method int istream::peek ()
+Return the next available input character, but @emph{without} changing
+the current input position.
+@end deftypefn
+
+@node String Input
+@subsection Reading strings
+
+Use these methods to read strings (for example, a line at a time) from
+the input stream:
+
+@deftypefn Method istream& istream::get (char* @var{c}, int @var{len} @w{[, char} @var{delim}])
+Read a string from the input stream, into the array at @var{c}.
+
+The remaining arguments limit how much to read: up to @samp{len-1}
+characters, or up to (but not including) the first occurrence in the
+input of a particular delimiter character @var{delim}---newline
+(@code{\n}) by default. (Naturally, if the stream reaches end of file
+first, that too will terminate reading.)
+
+If @var{delim} was present in the input, it remains available as if
+unread; to discard it instead, see @code{iostream::getline}.
+
+@code{get} writes @samp{\0} at the end of the string, regardless
+of which condition terminates the read.
+@end deftypefn
+
+@deftypefn Method istream& istream::get (streambuf& @var{sb} @w{[, char} @var{delim}])
+Read characters from the input stream and copy them on the
+@code{streambuf} object @var{sb}. Copying ends either just before the
+next instance of the delimiter character @var{delim} (newline @code{\n}
+by default), or when either stream ends. If @var{delim} was present in
+the input, it remains available as if unread.
+@end deftypefn
+
+@deftypefn Method istream& istream::getline (@var{charptr}, int @var{len} @w{[, char} @var{delim}])
+Read a line from the input stream, into the array at @var{charptr}.
+@var{charptr} may be any of three kinds of pointer: @code{char*},
+@code{unsigned char*}, or @code{signed char*}.
+
+The remaining arguments limit how much to read: up to (but not
+including) the first occurrence in the input of a line delimiter
+character @var{delim}---newline (@code{\n}) by default, or up to
+@samp{len-1} characters (or to end of file, if that happens sooner).
+
+If @code{getline} succeeds in reading a ``full line'', it also discards
+the trailing delimiter character from the input stream. (To preserve it
+as available input, see the similar form of @code{iostream::get}.)
+
+If @var{delim} was @emph{not} found before @var{len} characters or end
+of file, @code{getline} sets the @code{ios::fail} flag, as well as the
+@code{ios::eof} flag if appropriate.
+
+@code{getline} writes a null character at the end of the string, regardless
+of which condition terminates the read.
+@end deftypefn
+
+@deftypefn Method istream& istream::read (@var{pointer}, int @var{len})
+Read @var{len} bytes into the location at @var{pointer}, unless the
+input ends first.
+
+@var{pointer} may be of type @code{char*}, @code{void*}, @code{unsigned
+char*}, or @code{signed char*}.
+
+If the @code{istream} ends before reading @var{len} bytes, @code{read}
+sets the @code{ios::fail} flag.
+@end deftypefn
+
+@deftypefn Method istream& istream::gets (char **@var{s} @w{[, char} @var{delim}])
+A @sc{gnu} extension, to read an arbitrarily long string
+from the current input position to the next instance of the @var{delim}
+character (newline @code{\n} by default).
+
+To permit reading a string of arbitrary length, @code{gets} allocates
+whatever memory is required. Notice that the first argument @var{s} is
+an address to record a character pointer, rather than the pointer
+itself.
+@end deftypefn
+
+@deftypefn Method istream& istream::scan (const char *format ...)
+A @sc{gnu} extension, similar to @code{fscanf(@var{file},
+@var{format}, ...)}. The @var{format} is a @code{scanf}-style format
+control string, which is used to read the variables in the remainder of
+the argument list from the @code{istream}.
+@end deftypefn
+
+@deftypefn Method istream& istream::vscan (const char *format, va_list args)
+Like @code{istream::scan}, but takes a single @code{va_list} argument.
+@end deftypefn
+
+@node Input Position
+@subsection Repositioning an @code{istream}
+
+Use these methods to control the current input position:
+
+@deftypefn Method streampos istream::tellg ()
+Return the current read position, so that you can save it and return to
+it later with @code{istream::seekg}.
+@end deftypefn
+
+@deftypefn Method istream& istream::seekg (streampos @var{p})
+Reset the input pointer (if the input device permits it) to @var{p},
+usually the result of an earlier call to @code{istream::tellg}.
+@end deftypefn
+
+@deftypefn Method istream& istream::seekg (streamoff @var{offset}, ios::seek_dir @var{ref})
+Reset the input pointer (if the input device permits it) to @var{offset}
+characters from the beginning of the input, the current position, or the
+end of input. Specify how to interpret @var{offset} with one of these
+values for the second argument:
+
+@vtable @code
+@item ios::beg
+Interpret @var{loc} as an absolute offset from the beginning of the
+file.
+
+@item ios::cur
+Interpret @var{loc} as an offset relative to the current output
+position.
+
+@item ios::end
+Interpret @var{loc} as an offset from the current end of the output
+stream.
+@end vtable
+@end deftypefn
+
+@node Istream Housekeeping
+@subsection Miscellaneous @code{istream} utilities
+
+Use these methods for housekeeping on @code{istream} objects:
+
+@deftypefn Method int istream::gcount ()
+Report how many characters were read from this @code{istream} in the
+last unformatted input operation.
+@c FIXME! Define "unformatted input" somewhere...
+@end deftypefn
+
+@deftypefn Method int istream::ipfx (int @var{keepwhite})
+Ensure that the @code{istream} object is ready for reading; check for
+errors and end of file and flush any tied stream. @code{ipfx} skips
+whitespace if you specify @code{0} as the @var{keepwhite}
+argument, @emph{and} @code{ios::skipws} is set for this stream.
+
+To avoid skipping whitespace (regardless of the @code{skipws} setting on
+the stream), use @code{1} as the argument.
+
+Call @code{istream::ipfx} to simplify writing your own methods for reading
+@code{istream} objects.
+@end deftypefn
+
+@deftypefn Method void istream::isfx ()
+A placeholder for compliance with the draft @sc{ansi} standard; this
+method does nothing whatever.
+
+If you wish to write portable standard-conforming code on @code{istream}
+objects, call @code{isfx} after any operation that reads from an
+@code{istream}; if @code{istream::ipfx} has any special effects that
+must be cancelled when done, @code{istream::isfx} will cancel them.
+@end deftypefn
+
+@deftypefn Method istream& istream::ignore ([int @var{n}] @w{[, int} @var{delim}])
+Discard some number of characters pending input. The first optional
+argument @var{n} specifies how many characters to skip. The second
+optional argument @var{delim} specifies a ``boundary'' character:
+@code{ignore} returns immediately if this character appears in the
+input.
+
+By default, @var{delim} is @code{EOF}; that is, if you do not specify a
+second argument, only the count @var{n} restricts how much to ignore
+(while input is still available).
+
+If you do not specify how many characters to ignore, @code{ignore}
+returns after discarding only one character.
+@end deftypefn
+
+@deftypefn Method istream& istream::putback (char @var{ch})
+Attempts to back up one character, replacing the character backed-up
+over by @var{ch}. Returns @code{EOF} if this is not allowed. Putting
+back the most recently read character is always allowed. (This method
+corresponds to the C function @code{ungetc}.)
+@end deftypefn
+
+@deftypefn Method istream& istream::unget ()
+Attempt to back up one character.
+@end deftypefn
+
+@node Iostream
+@section Input and output together: class @code{iostream}
+
+If you need to use the same stream for input and output, you can use an
+object of the class @code{iostream}, which is derived from @emph{both}
+@code{istream} and @code{ostream}.
+
+The constructors for @code{iostream} behave just like the constructors
+for @code{istream}.
+
+@deftypefn Constructor {} iostream::iostream ()
+When used without arguments, the @code{iostream} constructor simply
+allocates a new @code{ios} object, and initializes the input counter
+(the value reported by @code{istream::gcount}) to @code{0}.
+@end deftypefn
+
+@deftypefn Constructor {} iostream::iostream (streambuf* @var{sb} @w{[, ostream*} @var{tie}])
+You can also call a constructor with one or two arguments. The first
+argument @var{sb} is a @code{streambuf*}; if you supply this pointer,
+the constructor uses that @code{streambuf} for input and output.
+
+You can use the optional second argument @var{tie} (an @code{ostream*})
+to specify a related output stream as the initial value for
+@code{ios::tie}.
+@end deftypefn
+
+@cindex @code{iostream} destructor
+@cindex destructor for @code{iostream}
+As for @code{ostream} and @code{istream}, @code{iostream} simply uses
+the @code{ios} destructor. However, an @code{iostream} is not deleted by
+its destructor.
+
+You can use all the @code{istream}, @code{ostream}, and @code{ios}
+methods with an @code{iostream} object.
+
+@node Files and Strings
+@chapter Classes for Files and Strings
+
+There are two very common special cases of input and output: using files,
+and using strings in memory.
+
+@code{libio} defines four specialized classes for these cases:
+
+@ftable @code
+@item ifstream
+Methods for reading files.
+
+@item ofstream
+Methods for writing files.
+
+@item istrstream
+Methods for reading strings from memory.
+
+@item ostrstream
+Methods for writing strings in memory.
+@end ftable
+
+@menu
+* Files:: Reading and writing files.
+* Strings:: Reading and writing strings in memory.
+@end menu
+
+@node Files
+@section Reading and writing files
+
+These methods are declared in @file{fstream.h}.
+
+@findex ifstream
+@cindex class @code{ifstream}
+You can read data from class @code{ifstream} with any operation from class
+@code{istream}. There are also a few specialized facilities:
+
+@deftypefn Constructor {} ifstream::ifstream ()
+Make an @code{ifstream} associated with a new file for input. (If you
+use this version of the constructor, you need to call
+@code{ifstream::open} before actually reading anything)
+@end deftypefn
+
+@deftypefn Constructor {} ifstream::ifstream (int @var{fd})
+Make an @code{ifstream} for reading from a file that was already open,
+using file descriptor @var{fd}. (This constructor is compatible with
+other versions of iostreams for @sc{posix} systems, but is not part of
+the @sc{ansi} working paper.)
+@end deftypefn
+
+@deftypefn Constructor {} ifstream::ifstream (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]])
+Open a file @code{*@var{fname}} for this @code{ifstream} object.
+
+By default, the file is opened for input (with @code{ios::in} as
+@var{mode}). If you use this constructor, the file will be closed when
+the @code{ifstream} is destroyed.
+
+You can use the optional argument @var{mode} to specify how to open the
+file, by combining these enumerated values (with @samp{|} bitwise or).
+(These values are actually defined in class @code{ios}, so that all
+file-related streams may inherit them.) Only some of these modes are
+defined in the latest draft @sc{ansi} specification; if portability is
+important, you may wish to avoid the others.
+
+@vtable @code
+@item ios::in
+Open for input. (Included in @sc{ansi} draft.)
+
+@item ios::out
+Open for output. (Included in @sc{ansi} draft.)
+
+@item ios::ate
+Set the initial input (or output) position to the end of the file.
+
+@item ios::app
+Seek to end of file before each write. (Included in @sc{ansi} draft.)
+
+@item ios::trunc
+Guarantee a fresh file; discard any contents that were previously
+associated with it.
+
+@item ios::nocreate
+Guarantee an existing file; fail if the specified file did not already
+exist.
+
+@item ios::noreplace
+Guarantee a new file; fail if the specified file already existed.
+
+@item ios::bin
+Open as a binary file (on systems where binary and text files have different
+properties, typically how @samp{\n} is mapped; included in @sc{ansi} draft).
+@end vtable
+
+@noindent
+The last optional argument @var{prot} is specific to Unix-like systems;
+it specifies the file protection (by default @samp{644}).
+@end deftypefn
+
+@deftypefn Method void ifstream::open (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]])
+Open a file explicitly after the associated @code{ifstream} object
+already exists (for instance, after using the default constructor). The
+arguments, options and defaults all have the same meanings as in the
+fully specified @code{ifstream} constructor.
+@end deftypefn
+
+@findex ostream
+@cindex class @code{ostream}
+You can write data to class @code{ofstream} with any operation from class
+@code{ostream}. There are also a few specialized facilities:
+
+@deftypefn Constructor {} ofstream::ofstream ()
+Make an @code{ofstream} associated with a new file for output.
+@end deftypefn
+
+@deftypefn Constructor {} ofstream::ofstream (int @var{fd})
+Make an @code{ofstream} for writing to a file that was already open,
+using file descriptor @var{fd}.
+@end deftypefn
+
+@deftypefn Constructor {} ofstream::ofstream (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]])
+Open a file @code{*@var{fname}} for this @code{ofstream} object.
+
+By default, the file is opened for output (with @code{ios::out} as @var{mode}).
+You can use the optional argument @var{mode} to specify how to open the
+file, just as described for @code{ifstream::ifstream}.
+
+The last optional argument @var{prot} specifies the file protection (by
+default @samp{644}).
+@end deftypefn
+
+@deftypefn Destructor {} ofstream::~ofstream ()
+The files associated with @code{ofstream} objects are closed when the
+corresponding object is destroyed.
+@end deftypefn
+
+@deftypefn Method void ofstream::open (const char* @var{fname} @w{[, int} @var{mode} @w{[, int} @var{prot}]])
+Open a file explicitly after the associated @code{ofstream} object
+already exists (for instance, after using the default constructor). The
+arguments, options and defaults all have the same meanings as in the
+fully specified @code{ofstream} constructor.
+@end deftypefn
+
+@findex fstream
+@cindex class @code{fstream}
+The class @code{fstream} combines the facilities of @code{ifstream} and
+@code{ofstream}, just as @code{iostream} combines @code{istream} and
+@code{ostream}.
+
+@c FIXME-future: say something about fstream constructor, maybe.
+
+@findex fstreambase
+@cindex class @code{fstreambase}
+The class @code{fstreambase} underlies both @code{ifstream} and
+@code{ofstream}. They both inherit this additional method:
+
+@deftypefn Method void fstreambase::close ()
+Close the file associated with this object, and set @code{ios::fail} in
+this object to mark the event.
+@end deftypefn
+
+@node Strings
+@section Reading and writing in memory
+
+@c FIXME!! Per, there's a lot of guesswork here---please check carefully!
+
+@findex istrstream
+@cindex class @code{istrstream}
+@findex ostrstream
+@cindex class @code{ostrstream}
+@findex strstream
+@cindex class @code{strstream}
+@findex strstreambase
+@cindex class @code{strstreambase}
+@findex strstreambuf
+@cindex class @code{strstreambuf}
+The classes @code{istrstream}, @code{ostrstream}, and @code{strstream}
+provide some additional features for reading and writing strings in
+memory---both static strings, and dynamically allocated strings. The
+underlying class @code{strstreambase} provides some features common to
+all three; @code{strstreambuf} underlies that in turn.
+
+@c FIXME-future: Document strstreambuf methods one day, when we document
+@c streambuf more fully.
+
+@deftypefn Constructor {} istrstream::istrstream (const char* @var{str} @w{[, int} @var{size}])
+Associate the new input string class @code{istrstream} with an existing
+static string starting at @var{str}, of size @var{size}. If you do not
+specify @var{size}, the string is treated as a @code{NUL} terminated string.
+@end deftypefn
+
+@deftypefn Constructor {} ostrstream::ostrstream ()
+Create a new stream for output to a dynamically managed string, which
+will grow as needed.
+@end deftypefn
+
+@deftypefn Constructor {} ostrstream::ostrstream (char* @var{str}, int @var{size} [,int @var{mode}])
+A new stream for output to a statically defined string of length
+@var{size}, starting at @var{str}. You may optionally specify one of
+the modes described for @code{ifstream::ifstream}; if you do not specify
+one, the new stream is simply open for output, with mode @code{ios::out}.
+@end deftypefn
+
+@deftypefn Method int ostrstream::pcount ()
+Report the current length of the string associated with this @code{ostrstream}.
+@end deftypefn
+
+@deftypefn Method char* ostrstream::str ()
+A pointer to the string managed by this @code{ostrstream}. Implies
+@samp{ostrstream::freeze()}.
+
+Note that if you want the string to be nul-terminated,
+you must do that yourself (perhaps by writing ends to the stream).
+@end deftypefn
+
+@deftypefn Method void ostrstream::freeze ([int @var{n}])
+If @var{n} is nonzero (the default), declare that the string associated
+with this @code{ostrstream} is not to change dynamically; while frozen,
+it will not be reallocated if it needs more space, and it will not be
+deallocated when the @code{ostrstream} is destroyed. Use
+@samp{freeze(1)} if you refer to the string as a pointer after creating
+it via @code{ostrstream} facilities.
+
+@samp{freeze(0)} cancels this declaration, allowing a dynamically
+allocated string to be freed when its @code{ostrstream} is destroyed.
+
+If this @code{ostrstream} is already static---that is, if it was created
+to manage an existing statically allocated string---@code{freeze} is
+unnecessary, and has no effect.
+@end deftypefn
+
+@deftypefn Method int ostrstream::frozen ()
+Test whether @code{freeze(1)} is in effect for this string.
+@end deftypefn
+
+@deftypefn Method strstreambuf* strstreambase::rdbuf ()
+A pointer to the underlying @code{strstreambuf}.
+@end deftypefn
+
+@node Streambuf
+@chapter Using the @code{streambuf} Layer
+
+The @code{istream} and @code{ostream} classes are meant to handle
+conversion between objects in your program and their textual representation.
+
+By contrast, the underlying @code{streambuf} class is for transferring
+raw bytes between your program, and input sources or output sinks.
+Different @code{streambuf} subclasses connect to different kinds of
+sources and sinks.
+
+The @sc{gnu} implementation of @code{streambuf} is still evolving; we
+describe only some of the highlights.
+
+@menu
+* Areas:: Areas in a streambuf.
+* Overflow:: Simple output re-direction
+* Formatting:: C-style formatting for streambuf objects.
+* Stdiobuf:: Wrappers for C stdio.
+* Procbuf:: Reading/writing from/to a pipe
+* Backing Up:: Marking and returning to a position.
+* Indirectbuf:: Forwarding I/O activity.
+@end menu
+
+@node Areas
+@section Areas of a @code{streambuf}
+
+Streambuf buffer management is fairly sophisticated (this is a
+nice way to say ``complicated''). The standard protocol
+has the following ``areas'':
+
+@itemize @bullet
+@item
+@cindex put area
+The @dfn{put area} contains characters waiting for output.
+
+@item
+@cindex get area
+The @dfn{get area} contains characters available for reading.
+@end itemize
+
+The @sc{gnu} @code{streambuf} design extends this, but the details are
+still evolving.
+
+The following methods are used to manipulate these areas.
+These are all protected methods, which are intended to be
+used by virtual function in classes derived from @code{streambuf}.
+They are also all ANSI/ISO-standard, and the ugly names
+are traditional.
+(Note that if a pointer points to the 'end' of an area,
+it means that it points to the character after the area.)
+
+@deftypefn Method char* streambuf::pbase () const
+Returns a pointer to the start of the put area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::epptr () const
+Returns a pointer to the end of the put area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::pptr () const
+If @code{pptr() < epptr ()}, the @code{pptr()}
+returns a pointer to the current put position.
+(In that case, the next write will
+overwrite @code{*pptr()}, and increment @code{pptr()}.)
+Otherwise, there is no put position available
+(and the next character written will cause @code{streambuf::overflow}
+to be called).
+@end deftypefn
+
+@deftypefn Method void streambuf::pbump (int @var{N})
+Add @var{N} to the current put pointer.
+No error checking is done.
+@end deftypefn
+
+@deftypefn Method void streambuf::setp (char* @var{P}, char* @var{E})
+Sets the start of the put area to @var{P}, the end of the put area to @var{E},
+and the current put pointer to @var{P} (also).
+@end deftypefn
+
+@deftypefn Method char* streambuf::eback () const
+Returns a pointer to the start of the get area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::egptr () const
+Returns a pointer to the end of the get area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::gptr () const
+If @code{gptr() < egptr ()}, then @code{gptr()}
+returns a pointer to the current get position.
+(In that case the next read will read @code{*gptr()},
+and possibly increment @code{gptr()}.)
+Otherwise, there is no read position available
+(and the next read will cause @code{streambuf::underflow}
+to be called).
+@end deftypefn
+
+@deftypefn Method void streambuf:gbump (int @var{N})
+Add @var{N} to the current get pointer.
+No error checking is done.
+@end deftypefn
+
+@deftypefn Method void streambuf::setg (char* @var{B}, char* @var{P}, char* @var{E})
+Sets the start of the get area to @var{B}, the end of the get area to @var{E},
+and the current put pointer to @var{P}.
+@end deftypefn
+
+@node Overflow
+@section Simple output re-direction by redefining @code{overflow}
+
+Suppose you have a function @code{write_to_window} that
+writes characters to a @code{window} object. If you want to use the
+ostream function to write to it, here is one (portable) way to do it.
+This depends on the default buffering (if any).
+
+@cartouche
+@smallexample
+#include <iostream.h>
+/* Returns number of characters successfully written to @var{win}. */
+extern int write_to_window (window* win, char* text, int length);
+
+class windowbuf : public streambuf @{
+ window* win;
+ public:
+ windowbuf (window* w) @{ win = w; @}
+ int sync ();
+ int overflow (int ch);
+ // Defining xsputn is an optional optimization.
+ // (streamsize was recently added to ANSI C++, not portable yet.)
+ streamsize xsputn (char* text, streamsize n);
+@};
+
+int windowbuf::sync ()
+@{ streamsize n = pptr () - pbase ();
+ return (n && write_to_window (win, pbase (), n) != n) ? EOF : 0;
+@}
+
+int windowbuf::overflow (int ch)
+@{ streamsize n = pptr () - pbase ();
+ if (n && sync ())
+ return EOF;
+ if (ch != EOF)
+ @{
+ char cbuf[1];
+ cbuf[0] = ch;
+ if (write_to_window (win, cbuf, 1) != 1)
+ return EOF;
+ @}
+ pbump (-n); // Reset pptr().
+ return 0;
+@}
+
+streamsize windowbuf::xsputn (char* text, streamsize n)
+@{ return sync () == EOF ? 0 : write_to_window (win, text, n); @}
+
+int
+main (int argc, char**argv)
+@{
+ window *win = ...;
+ windowbuf wbuf(win);
+ ostream wstr(&wbuf);
+ wstr << "Hello world!\n";
+@}
+@end smallexample
+@end cartouche
+
+
+
+@node Formatting
+@section C-style formatting for @code{streambuf} objects
+
+The @sc{gnu} @code{streambuf} class supports @code{printf}-like
+formatting and scanning.
+
+@deftypefn Method int streambuf::form (const char *@var{format}, ...)
+Similar to @code{fprintf(@var{file}, @var{format}, ...)}.
+The @var{format} is a @code{printf}-style format control string, which is used
+to format the (variable number of) arguments, printing the result on
+the @code{this} streambuf. The result is the number of characters printed.
+@end deftypefn
+
+@deftypefn Method int streambuf::vform (const char *@var{format}, va_list @var{args})
+Similar to @code{vfprintf(@var{file}, @var{format}, @var{args})}.
+The @var{format} is a @code{printf}-style format control string, which is used
+to format the argument list @var{args}, printing the result on
+the @code{this} streambuf. The result is the number of characters printed.
+@end deftypefn
+
+@deftypefn Method int streambuf::scan (const char *@var{format}, ...)
+Similar to @code{fscanf(@var{file}, @var{format}, ...)}.
+The @var{format} is a @code{scanf}-style format control string, which is used
+to read the (variable number of) arguments from the @code{this} streambuf.
+The result is the number of items assigned, or @code{EOF} in case of
+input failure before any conversion.
+@end deftypefn
+
+@deftypefn Method int streambuf::vscan (const char *@var{format}, va_list @var{args})
+Like @code{streambuf::scan}, but takes a single @code{va_list} argument.
+@end deftypefn
+
+@node Stdiobuf
+@section Wrappers for C @code{stdio}
+
+A @dfn{stdiobuf} is a @code{streambuf} object that points to
+a @code{FILE} object (as defined by @code{stdio.h}).
+All @code{streambuf} operations on the @code{stdiobuf} are forwarded
+to the @code{FILE}. Thus the @code{stdiobuf} object provides a
+wrapper around a @code{FILE}, allowing use of @code{streambuf}
+operations on a @code{FILE}. This can be useful when mixing
+C code with C++ code.
+
+The pre-defined streams @code{cin}, @code{cout}, and @code{cerr} are
+normally implemented as @code{stdiobuf} objects that point to
+respectively @code{stdin}, @code{stdout}, and @code{stderr}. This is
+convenient, but it does cost some extra overhead.
+
+If you set things up to use the implementation of @code{stdio} provided
+with this library, then @code{cin}, @code{cout}, and @code{cerr} will be
+set up to to use @code{stdiobuf} objects, since you get their benefits
+for free. @xref{Stdio,,C Input and Output}.
+
+@ignore
+@c FIXME-future: setbuf is not yet documented, hence this para is not useful.
+Note that if you use @code{setbuf} to give a buffer to a @code{stdiobuf},
+that buffer will provide intermediate buffering in addition that
+whatever is done by the @code{FILE}.
+@end ignore
+
+@node Procbuf
+@section Reading/writing from/to a pipe
+
+The @dfn{procbuf} class is a @sc{gnu} extension. It is derived from
+@code{streambuf}. A @code{procbuf} can be @dfn{closed} (in which case
+it does nothing), or @dfn{open} (in which case it allows communicating
+through a pipe with some other program).
+
+@deftypefn Constructor {} procbuf::procbuf ()
+Creates a @code{procbuf} in a @dfn{closed} state.
+@end deftypefn
+
+@deftypefn Method procbuf* procbuf::open (const char *@var{command}, int @var{mode})
+Uses the shell (@file{/bin/sh}) to run a program specified by @var{command}.
+
+If @var{mode} is @samp{ios::in}, standard output from the program is sent
+to a pipe; you can read from the pipe by reading from the
+@code{procbuf}. (This is similar to @w{@samp{popen(@var{command}, "r")}}.)
+
+If @var{mode} is @samp{ios::out}, output written written to the
+@code{procbuf} is written to a pipe; the program is set up to read its
+standard input from (the other end of) the pipe. (This is similar to
+@w{@samp{popen(@var{command}, "w")}}.)
+
+The @code{procbuf} must start out in the @dfn{closed} state.
+Returns @samp{*this} on success, and @samp{NULL} on failure.
+@end deftypefn
+
+@deftypefn Constructor {} procbuf::procbuf (const char *@var{command}, int @var{mode})
+Calls @samp{procbuf::open (@var{command}, @var{mode})}.
+@end deftypefn
+
+@deftypefn Method procbuf* procbuf::close ()
+Waits for the program to finish executing,
+and then cleans up the resources used.
+Returns @samp{*this} on success, and @samp{NULL} on failure.
+@end deftypefn
+
+@deftypefn Destructor {} procbuf::~procbuf ()
+Calls @samp{procbuf::close}.
+@end deftypefn
+
+@node Backing Up
+@section Backing up
+
+The @sc{gnu} iostream library allows you to ask a @code{streambuf} to
+remember the current position. This allows you to go back to this
+position later, after reading further. You can back up arbitrary
+amounts, even on unbuffered files or multiple buffers' worth, as long as
+you tell the library in advance. This unbounded backup is very useful
+for scanning and parsing applications. This example shows a typical
+scenario:
+
+@cartouche
+@smallexample
+// Read either "dog", "hound", or "hounddog".
+// If "dog" is found, return 1.
+// If "hound" is found, return 2.
+// If "hounddog" is found, return 3.
+// If none of these are found, return -1.
+int my_scan(streambuf* sb)
+@{
+ streammarker fence(sb);
+ char buffer[20];
+ // Try reading "hounddog":
+ if (sb->sgetn(buffer, 8) == 8
+ && strncmp(buffer, "hounddog", 8) == 0)
+ return 3;
+ // No, no "hounddog": Back up to 'fence'
+ sb->seekmark(fence); //
+ // ... and try reading "dog":
+ if (sb->sgetn(buffer, 3) == 3
+ && strncmp(buffer, "dog", 3) == 0)
+ return 1;
+ // No, no "dog" either: Back up to 'fence'
+ sb->seekmark(fence); //
+ // ... and try reading "hound":
+ if (sb->sgetn(buffer, 5) == 5
+ && strncmp(buffer, "hound", 5) == 0)
+ return 2;
+ // No, no "hound" either: Back up and signal failure.
+ sb->seekmark(fence); // Backup to 'fence'
+ return -1;
+@}
+@end smallexample
+@end cartouche
+
+@deftypefn Constructor {} streammarker::streammarker (streambuf* @var{sbuf})
+Create a @code{streammarker} associated with @var{sbuf}
+that remembers the current position of the get pointer.
+@end deftypefn
+
+@deftypefn Method int streammarker::delta (streammarker& @var{mark2})
+Return the difference between the get positions corresponding
+to @code{*this} and @var{mark2} (which must point into the same
+@code{streambuffer} as @code{this}).
+@end deftypefn
+
+@deftypefn Method int streammarker::delta ()
+Return the position relative to the streambuffer's current get position.
+@end deftypefn
+
+@deftypefn Method int streambuf::seekmark (streammarker& @var{mark})
+Move the get pointer to where it (logically) was when @var{mark}
+was constructed.
+@end deftypefn
+
+@node Indirectbuf
+@section Forwarding I/O activity
+
+An @dfn{indirectbuf} is one that forwards all of its I/O requests
+to another streambuf.
+
+@ignore
+@c FIXME-future: get_stream and put_stream are so far undocumented.
+All get-related requests are sent to get_stream().
+All put-related requests are sent to put_stream().
+@end ignore
+
+An @code{indirectbuf} can be used to implement Common Lisp
+synonym-streams and two-way-streams:
+
+@example
+class synonymbuf : public indirectbuf @{
+ Symbol *sym;
+ synonymbuf(Symbol *s) @{ sym = s; @}
+ virtual streambuf *lookup_stream(int mode) @{
+ return coerce_to_streambuf(lookup_value(sym)); @}
+@};
+@end example
+
+@node Stdio
+@chapter C Input and Output
+
+@code{libio} is distributed with a complete implementation of the ANSI C
+@code{stdio} facility. It is implemented using @code{streambuf}
+objects. @xref{Stdiobuf,,Wrappers for C @code{stdio}}.
+
+The @code{stdio} package is intended as a replacement for the whatever
+@code{stdio} is in your C library.
+@ignore
+@c FIXME-future: This is not useful unless we specify what problems.
+It can co-exist with C libraries that have alternate implementations of
+stdio, but there may be some problems.
+@end ignore
+Since @code{stdio} works best when you build @code{libc} to contain it, and
+that may be inconvenient, it is not installed by default.
+
+Extensions beyond @sc{ansi}:
+
+@itemize @bullet
+@item
+A stdio @code{FILE} is identical to a streambuf.
+Hence there is no need to worry about synchronizing C and C++
+input/output---they are by definition always synchronized.
+
+@item
+If you create a new streambuf sub-class (in C++), you can use it as a
+@code{FILE} from C. Thus the system is extensible using the standard
+@code{streambuf} protocol.
+
+@item
+You can arbitrarily mix reading and writing, without having to seek
+in between.
+
+@item
+Unbounded @code{ungetc()} buffer.
+@end itemize
+
+@ignore
+@c FIXME-future: Per says this is not ready to go public at v0.5
+@node Libio buffer management
+@chapter Libio buffer management
+
+The libio user functions present an abstract sequence of characters,
+that they read and write from. A number of buffers are used to go
+between the user program and the abstract sequence. These buffers are
+concrete arrays of characters that contain some sub-sequence of the
+abstract sequence.
+
+The libio buffer management protocol is fairly complex. Its design is
+based on the C++ @code{streambuf} protocol, so that the C++
+@code{streambuf} classes can be trivially implemented on top of the
+libio protocol.
+
+The @dfn{write area} contains characters waiting for output.
+
+The @dfn{read area} contains characters available for reading.
+
+The @dfn{reserve area} is available to virtual methods.
+Usually, the get and/or put areas are part of the reserve area.
+
+The @dfn{main get area} contains characters that have
+been read in from the character source, but not yet
+read by the application.
+
+The @dfn{backup area} contains previously read data that is being saved
+because of a user request, or that have been "unread" (put back).
+@end ignore
+
+@ignore
+@c Per says this design is not finished
+@node Streambuf internals
+@chapter Streambuf internals
+
+@menu
+* Buffer management::
+* Filebuf internals::
+@end menu
+
+@node Buffer management
+@section Buffer management
+
+@subsection Areas
+
+NOTE: This chapter is due for an update.
+
+Streambuf buffer management is fairly sophisticated (this is a
+nice way to say "complicated"). The standard protocol
+has the following "areas":
+
+@itemize @bullet
+@cindex put area
+@item
+The @dfn{put area} contains characters waiting for output.
+@cindex get area
+@item
+The @dfn{get area} contains characters available for reading.
+@cindex reserve area
+@item
+The @dfn{reserve area} is available to virtual methods.
+Usually, the get and/or put areas are part of the reserve area.
+@end itemize
+
+The @sc{gnu} @code{streambuf} design extends this by supporting two
+get areas:
+@itemize @bullet
+@cindex main get area
+@item
+The @dfn{main get area} contains characters that have
+been read in from the character source, but not yet
+read by the application.
+@cindex backup area
+@item
+The @dfn{backup area} contains previously read data that is being
+saved because of a user request, or that have been "unread" (putback).
+@end itemize
+
+The backup and the main get area are logically contiguous: That is,
+the first character of the main get area follows the last character
+of the backup area.
+
+The @dfn{current get area} is whichever one of the backup or
+main get areas that is currently being read from.
+The other of the two is the @dfn{non-current get area}.
+
+@subsection Pointers
+
+The following @code{char*} pointers define the various areas.
+
+@deftypefn Method char* streambuf::base ()
+The start of the reserve area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::ebuf ()
+The end of the reserve area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::Gbase ()
+The start of the main get area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::eGptr ()
+The end of the main get area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::Bbase ()
+The start of the backup area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::Bptr ()
+The start of the used part of the backup area.
+The area (@code{Bptr()} .. @code{eBptr()}) contains data that has been
+pushed back, while (@code{Bbase()} .. @code{eBptr()}) contains unused
+space available for future putbacks.
+@end deftypefn
+
+@deftypefn Method char* streambuf::eBptr ()
+The end of the backup area.
+@end deftypefn
+
+@deftypefn Method char* streambuf::Nbase ()
+The start of the non-current get area (either @code{main_gbase} or @code{backup_gbase}).
+@end deftypefn
+
+@deftypefn Method char* streambuf::eNptr ()
+The end of the non-current get area.
+@end deftypefn
+
+@node Filebuf internals
+@section Filebuf internals
+
+The @code{filebuf} is used a lot, so it is importamt that it be
+efficient. It is also supports rather complex semantics.
+so let us examine its implementation.
+
+@subsection Tied read and write pointers
+
+The streambuf model allows completely independent read and write pointers.
+However, a @code{filebuf} has only a single logical pointer used
+for both reads and writes. Since the @code{streambuf} protocol
+uses @code{gptr()} for reading and @code{pptr()} for writing,
+we map the logical file pointer into either @code{gptr()} or @code{pptr()}
+at different times.
+
+@itemize @bullet
+@item
+Reading is allowed when @code{gptr() < egptr()}, which we call get mode.
+
+@item
+Writing is allowed when @code{pptr() < epptr()}, which we call put mode.
+@end itemize
+
+@noindent
+A @code{filebuf} cannot be in get mode and put mode at the same time.
+
+We have up to two buffers:
+
+@itemize @bullet
+@item
+The backup area, defined by @code{Bbase()}, @code{Bptr()}, and @code{eBptr()}.
+This can be empty.
+
+@item
+The reserve area, which also contains the main get area.
+For an unbuffered file, the (@code{shortbuf()}..@code{shortbuf()+1}) is used,
+where @code{shortbuf()} points to a 1-byte buffer that is part of
+the @code{filebuf}.
+@end itemize
+
+@noindent
+The file system's idea of the current position is @code{eGptr()}.
+
+Characters that have been written into a buffer but not yet written
+out (flushed) to the file systems are those between @code{pbase()}
+and @code{pptr()}.
+
+The end of the valid data bytes is:
+@code{pptr() > eGptr() && pptr() < ebuf() ? pptr() : eGptr()}.
+
+If the @code{filebuf} is unbuffered or line buffered,
+the @code{eptr()} is @code{pbase()}. This forces a call
+to @code{overflow()} on each put of a character.
+The logical @code{epptr()} is @code{epptr() ? ebuf() : NULL}.
+(If the buffer is read-only, set @code{pbase()}, @code{pptr()},
+and @code{epptr()} to @code{NULL}. NOT!)
+@end ignore
+
+@node Index
+@unnumbered Index
+@printindex cp
+
+@contents
+@bye
diff --git a/gnu/dist/libio/iostreamP.h b/gnu/dist/libio/iostreamP.h
new file mode 100644
index 00000000000..c9c40cb6ba9
--- /dev/null
+++ b/gnu/dist/libio/iostreamP.h
@@ -0,0 +1,26 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "streambuf.h"
+#include "libioP.h"
diff --git a/gnu/dist/libio/iostrerror.c b/gnu/dist/libio/iostrerror.c
new file mode 100644
index 00000000000..348e0956d70
--- /dev/null
+++ b/gnu/dist/libio/iostrerror.c
@@ -0,0 +1,12 @@
+/* This should be replaced by whatever namespace-clean
+ version of strerror you have available. */
+
+#include "libioP.h"
+extern char *strerror __P ((int));
+
+char *
+_IO_strerror (errnum)
+ int errnum;
+{
+ return strerror(errnum);
+}
diff --git a/gnu/dist/libio/ioungetc.c b/gnu/dist/libio/ioungetc.c
new file mode 100644
index 00000000000..07f38e747bf
--- /dev/null
+++ b/gnu/dist/libio/ioungetc.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+int
+_IO_ungetc (c, fp)
+ int c;
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ if (c == EOF)
+ return EOF;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_sputbackc (fp, (unsigned char) c);
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_ungetc, ungetc)
+#endif
diff --git a/gnu/dist/libio/iovfprintf.c b/gnu/dist/libio/iovfprintf.c
new file mode 100644
index 00000000000..755334c2bf2
--- /dev/null
+++ b/gnu/dist/libio/iovfprintf.c
@@ -0,0 +1,890 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Actual printf innards.
+ *
+ * This code is large and complicated...
+ */
+
+#include <sys/types.h>
+#include "libioP.h"
+#include <string.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifndef _IO_USE_DTOA
+int __cvt_double __P((double number, register int prec, int flags, int *signp, int fmtch, char *startp, char *endp));
+#endif
+
+/*
+ * Define FLOATING_POINT to get floating point.
+ */
+#ifndef NO_FLOATING_POINT
+#define FLOATING_POINT
+#endif
+
+/* end of configuration stuff */
+
+
+/*
+ * Helper "class" for `fprintf to unbuffered': creates a
+ * temporary buffer. */
+
+struct helper_file
+{
+ struct _IO_FILE_plus _f;
+ _IO_FILE *_put_stream;
+};
+
+static int
+_IO_helper_overflow (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ _IO_FILE *target = ((struct helper_file*)fp)->_put_stream;
+ int used = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (used)
+ {
+ _IO_sputn(target, fp->_IO_write_base, used);
+ fp->_IO_write_ptr -= used;
+ }
+ return _IO_putc (c, fp);
+}
+
+static struct _IO_jump_t _IO_helper_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_default_finish),
+ JUMP_INIT(overflow, _IO_helper_overflow),
+ JUMP_INIT(underflow, _IO_default_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_default_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_default_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_default_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_default_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat)
+};
+
+static int
+helper_vfprintf (fp, fmt0, ap)
+ _IO_FILE *fp;
+ char const *fmt0;
+ _IO_va_list ap;
+{
+ char buf[_IO_BUFSIZ];
+ struct helper_file helper;
+ register _IO_FILE *hp = (_IO_FILE*)&helper;
+ int result, to_flush;
+
+ /* initialize helper */
+ helper._put_stream = fp;
+ hp->_IO_write_base = buf;
+ hp->_IO_write_ptr = buf;
+ hp->_IO_write_end = buf+_IO_BUFSIZ;
+ hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS;
+ _IO_JUMPS(hp) = &_IO_helper_jumps;
+
+ /* Now print to helper instead. */
+ result = _IO_vfprintf(hp, fmt0, ap);
+
+ /* Now flush anything from the helper to the fp. */
+ if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0)
+ {
+ if (_IO_sputn(fp, hp->_IO_write_base, to_flush) != to_flush)
+ return EOF;
+ }
+ return result;
+}
+
+#ifdef FLOATING_POINT
+
+#include "floatio.h"
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+#define DEFPREC 6
+extern double modf __P((double, double*));
+
+#else /* no FLOATING_POINT */
+
+#define BUF 40
+
+#endif /* FLOATING_POINT */
+
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) ((n) + '0')
+
+/*
+ * Flags used during conversion.
+ */
+#define LONGINT 0x01 /* long integer */
+#define LONGDBL 0x02 /* long double; unimplemented */
+#define SHORTINT 0x04 /* short integer */
+#define ALT 0x08 /* alternate form */
+#define LADJUST 0x10 /* left adjustment */
+#define ZEROPAD 0x20 /* zero (as opposed to blank) pad */
+#define HEXPREFIX 0x40 /* add 0x or 0X prefix */
+
+int
+_IO_vfprintf (fp, fmt0, ap)
+ _IO_FILE *fp;
+ char const *fmt0;
+ _IO_va_list ap;
+{
+ register const char *fmt; /* format string */
+ register int ch; /* character from fmt */
+ register int n; /* handy integer (short term usage) */
+ register char *cp; /* handy char pointer (short term usage) */
+ const char *fmark; /* for remembering a place in fmt */
+ register int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format (%.3d), or -1 */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+#ifdef FLOATING_POINT
+ int softsign; /* temporary negative sign for floats */
+ double _double; /* double precision arguments %[eEfgG] */
+#ifndef _IO_USE_DTOA
+ int fpprec; /* `extra' floating precision in [eEfgG] */
+#endif
+#endif
+ unsigned long _ulong; /* integer arguments %[diouxX] */
+ enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int dpad; /* extra 0 padding needed for integers */
+ int fieldsz; /* field size expanded by sign, dpad etc */
+ /* The initialization of 'size' is to suppress a warning that
+ 'size' might be used unitialized. It seems gcc can't
+ quite grok this spaghetti code ... */
+ int size = 0; /* size of converted field or string */
+ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
+ char ox[2]; /* space for 0x hex-prefix */
+
+ /*
+ * BEWARE, these `goto error' on error, and PAD uses `n'.
+ */
+#define PRINT(ptr, len) \
+ do { if (_IO_sputn(fp,ptr, len) != len) goto error; } while (0)
+#define PAD_SP(howmany) if (_IO_padn(fp, ' ', howmany) < (howmany)) goto error;
+#define PAD_0(howmany) if (_IO_padn(fp, '0', howmany) < (howmany)) goto error;
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ (flags&LONGINT ? va_arg(ap, long) : \
+ flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+ (long)va_arg(ap, int))
+#define UARG() \
+ (flags&LONGINT ? va_arg(ap, unsigned long) : \
+ flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
+ (unsigned long)va_arg(ap, unsigned int))
+
+ /* optimise stderr (and other unbuffered Unix files) */
+ if (fp->_IO_file_flags & _IO_UNBUFFERED)
+ return helper_vfprintf(fp, fmt0, ap);
+
+ fmt = fmt0;
+ ret = 0;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (fmark = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if ((n = fmt - fmark) != 0) {
+ PRINT(fmark, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
+ fpprec = 0;
+#endif
+ width = 0;
+ prec = -1;
+ sign = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ if ((width = va_arg(ap, int)) >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ flags &= ~ZEROPAD; /* '-' disables '0' */
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ n = va_arg(ap, int);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ }
+ prec = n < 0 ? -1 : n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ if (!(flags & LADJUST))
+ flags |= ZEROPAD; /* '-' disables '0' */
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ flags |= LONGINT;
+ goto rflag;
+ case 'c':
+ *(cp = buf) = va_arg(ap, int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ _ulong = SARG();
+ if ((long)_ulong < 0) {
+ _ulong = -_ulong;
+ sign = '-';
+ }
+ base = DEC;
+ goto number;
+#ifdef FLOATING_POINT
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ _double = va_arg(ap, double);
+#ifdef _IO_USE_DTOA
+ {
+ int fmt_flags = 0;
+ int fill = ' ';
+ if (flags & ALT)
+ fmt_flags |= _IO_SHOWPOINT;
+ if (flags & LADJUST)
+ fmt_flags |= _IO_LEFT;
+ else if (flags & ZEROPAD)
+ fmt_flags |= _IO_INTERNAL, fill = '0';
+ n = _IO_outfloat(_double, fp, ch, width,
+ prec < 0 ? DEFPREC : prec,
+ fmt_flags, sign, fill);
+ if (n < 0)
+ goto error;
+ ret += n;
+ }
+ /* CHECK ERROR! */
+ continue;
+#else
+ /*
+ * don't do unrealistic precision; just pad it with
+ * zeroes later, so buffer size stays rational.
+ */
+ if (prec > MAXFRACT) {
+ if ((ch != 'g' && ch != 'G') || (flags&ALT))
+ fpprec = prec - MAXFRACT;
+ prec = MAXFRACT;
+ } else if (prec == -1)
+ prec = DEFPREC;
+ /* __cvt_double may have to round up before the
+ "start" of its buffer, i.e.
+ ``intf("%.2f", (double)9.999);'';
+ if the first character is still NUL, it did.
+ softsign avoids negative 0 if _double < 0 but
+ no significant digits will be shown. */
+ cp = buf;
+ *cp = '\0';
+ size = __cvt_double(_double, prec, flags, &softsign,
+ ch, cp, buf + sizeof(buf));
+ if (softsign)
+ sign = '-';
+ if (*cp == '\0')
+ cp++;
+ break;
+#endif
+#endif /* FLOATING_POINT */
+ case 'n':
+ if (flags & LONGINT)
+ *va_arg(ap, long *) = ret;
+ else if (flags & SHORTINT)
+ *va_arg(ap, short *) = ret;
+ else
+ *va_arg(ap, int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ _ulong = UARG();
+ base = OCT;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ /* NOSTRICT */
+ _ulong = (unsigned long)va_arg(ap, void *);
+ base = HEX;
+ flags |= HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = va_arg(ap, char *)) == NULL)
+ cp = "(null)";
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = (char*)memchr(cp, 0, prec);
+
+ if (p != NULL) {
+ size = p - cp;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = strlen(cp);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ _ulong = UARG();
+ base = DEC;
+ goto nosign;
+ case 'X':
+ case 'x':
+ _ulong = UARG();
+ base = HEX;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT && _ulong != 0)
+ flags |= HEXPREFIX;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = buf + BUF;
+ if (_ulong != 0 || prec != 0) {
+ char *xdigs; /* digits for [xX] conversion */
+ /*
+ * unsigned mod is hard, and unsigned mod
+ * by a constant is easier than that by
+ * a variable; hence this switch.
+ */
+ switch (base) {
+ case OCT:
+ do {
+ *--cp = to_char(_ulong & 7);
+ _ulong >>= 3;
+ } while (_ulong);
+ /* handle octal leading 0 */
+ if (flags & ALT && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case DEC:
+ /* many numbers are 1 digit */
+ while (_ulong >= 10) {
+ *--cp = to_char(_ulong % 10);
+ _ulong /= 10;
+ }
+ *--cp = to_char(_ulong);
+ break;
+
+ case HEX:
+ if (ch == 'X')
+ xdigs = "0123456789ABCDEF";
+ else /* ch == 'x' || ch == 'p' */
+ xdigs = "0123456789abcdef";
+ do {
+ *--cp = xdigs[_ulong & 15];
+ _ulong >>= 4;
+ } while (_ulong);
+ break;
+
+ default:
+ cp = "bug in vform: bad base";
+ goto skipsize;
+ }
+ }
+ size = buf + BUF - cp;
+ skipsize:
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = buf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point,
+ * `cp' points to a string which (if not flags&LADJUST)
+ * should be padded out to `width' places. If
+ * flags&ZEROPAD, it should first be prefixed by any
+ * sign or other prefix; otherwise, it should be blank
+ * padded before the prefix is emitted. After any
+ * left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print
+ * the string proper, then emit zeroes required by any
+ * leftover floating precision; finally, if LADJUST,
+ * pad with blanks.
+ */
+
+ /*
+ * compute actual size, so we know how much to pad.
+ */
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
+ fieldsz = size + fpprec;
+#else
+ fieldsz = size;
+#endif
+ dpad = dprec - size;
+ if (dpad < 0)
+ dpad = 0;
+
+ if (sign)
+ fieldsz++;
+ else if (flags & HEXPREFIX)
+ fieldsz += 2;
+ fieldsz += dpad;
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD_SP(width - fieldsz);
+
+ /* prefix */
+ if (sign) {
+ PRINT(&sign, 1);
+ } else if (flags & HEXPREFIX) {
+ ox[0] = '0';
+ ox[1] = ch;
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD_0(width - fieldsz);
+
+ /* leading zeroes from decimal precision */
+ PAD_0(dpad);
+
+ /* the string or number proper */
+ PRINT(cp, size);
+
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
+ /* trailing f.p. zeroes */
+ PAD_0(fpprec);
+#endif
+
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD_SP(width - fieldsz);
+
+ /* finally, adjust ret */
+ ret += width > fieldsz ? width : fieldsz;
+
+ }
+done:
+ return ret;
+error:
+ return EOF;
+ /* NOTREACHED */
+}
+
+#if defined(FLOATING_POINT) && !defined(_IO_USE_DTOA)
+
+static char *exponent(register char *p, register int exp, int fmtch)
+{
+ register char *t;
+ char expbuf[MAXEXP];
+
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXP;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXP; *p++ = *t++);
+ }
+ else {
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return (p);
+}
+
+static char * round(double fract, int *exp,
+ register char *start, register char *end,
+ char ch, int *signp)
+{
+ double tmp;
+
+ if (fract)
+ (void)modf(fract * 10, &tmp);
+ else
+ tmp = to_digit(ch);
+ if (tmp > 4)
+ for (;; --end) {
+ if (*end == '.')
+ --end;
+ if (++*end <= '9')
+ break;
+ *end = '0';
+ if (end == start) {
+ if (exp) { /* e/E; increment exponent */
+ *end = '1';
+ ++*exp;
+ }
+ else { /* f; add extra digit */
+ *--end = '1';
+ --start;
+ }
+ break;
+ }
+ }
+ /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
+ else if (*signp == '-')
+ for (;; --end) {
+ if (*end == '.')
+ --end;
+ if (*end != '0')
+ break;
+ if (end == start)
+ *signp = 0;
+ }
+ return (start);
+}
+
+int __cvt_double(double number, register int prec, int flags, int *signp,
+ int fmtch, char *startp, char *endp)
+{
+ register char *p, *t;
+ register double fract;
+ int dotrim = 0, expcnt, gformat = 0;
+ double integer, tmp;
+
+ expcnt = 0;
+ if (number < 0) {
+ number = -number;
+ *signp = '-';
+ } else
+ *signp = 0;
+
+ fract = modf(number, &integer);
+
+ /* get an extra slot for rounding. */
+ t = ++startp;
+
+ /*
+ * get integer portion of number; put into the end of the buffer; the
+ * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
+ */
+ for (p = endp - 1; p >= startp && integer; ++expcnt) {
+ tmp = modf(integer / 10, &integer);
+ *p-- = to_char((int)((tmp + .01) * 10));
+ }
+ switch (fmtch) {
+ case 'f':
+ case 'F':
+ /* reverse integer into beginning of buffer */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point.
+ */
+ if (prec || flags&ALT)
+ *t++ = '.';
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, (int *)NULL, startp,
+ t - 1, (char)0, signp);
+ }
+ for (; prec--; *t++ = '0');
+ break;
+ case 'e':
+ case 'E':
+eformat: if (expcnt) {
+ *t++ = *++p;
+ if (prec || flags&ALT)
+ *t++ = '.';
+ /* if requires more precision and some integer left */
+ for (; prec && ++p < endp; --prec)
+ *t++ = *p;
+ /*
+ * if done precision and more of the integer component,
+ * round using it; adjust fract so we don't re-round
+ * later.
+ */
+ if (!prec && ++p < endp) {
+ fract = 0;
+ startp = round((double)0, &expcnt, startp,
+ t - 1, *p, signp);
+ }
+ /* adjust expcnt for digit in front of decimal */
+ --expcnt;
+ }
+ /* until first fractional digit, decrement exponent */
+ else if (fract) {
+ /* adjust expcnt for digit in front of decimal */
+ for (expcnt = -1;; --expcnt) {
+ fract = modf(fract * 10, &tmp);
+ if (tmp)
+ break;
+ }
+ *t++ = to_char((int)tmp);
+ if (prec || flags&ALT)
+ *t++ = '.';
+ }
+ else {
+ *t++ = '0';
+ if (prec || flags&ALT)
+ *t++ = '.';
+ }
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, &expcnt, startp,
+ t - 1, (char)0, signp);
+ }
+ /* if requires more precision */
+ for (; prec--; *t++ = '0');
+
+ /* unless alternate flag, trim any g/G format trailing 0's */
+ if (gformat && !(flags&ALT)) {
+ while (t > startp && *--t == '0');
+ if (*t == '.')
+ --t;
+ ++t;
+ }
+ t = exponent(t, expcnt, fmtch);
+ break;
+ case 'g':
+ case 'G':
+ /* a precision of 0 is treated as a precision of 1. */
+ if (!prec)
+ ++prec;
+ /*
+ * ``The style used depends on the value converted; style e
+ * will be used only if the exponent resulting from the
+ * conversion is less than -4 or greater than the precision.''
+ * -- ANSI X3J11
+ */
+ if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
+ /*
+ * g/G format counts "significant digits, not digits of
+ * precision; for the e/E format, this just causes an
+ * off-by-one problem, i.e. g/G considers the digit
+ * before the decimal point significant and e/E doesn't
+ * count it as precision.
+ */
+ --prec;
+ fmtch -= 2; /* G->E, g->e */
+ gformat = 1;
+ goto eformat;
+ }
+ /*
+ * reverse integer into beginning of buffer,
+ * note, decrement precision
+ */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p, --prec);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point. If no digits yet, add in leading 0.
+ */
+ if (prec || flags&ALT) {
+ dotrim = 1;
+ *t++ = '.';
+ }
+ else
+ dotrim = 0;
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec) {
+ /* If no integer part, don't count initial
+ * zeros as significant digits. */
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while(!tmp && !expcnt);
+ while (--prec && fract) {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ }
+ }
+ if (fract)
+ startp = round(fract, (int *)NULL, startp,
+ t - 1, (char)0, signp);
+ }
+ /* alternate format, adds 0's for precision, else trim 0's */
+ if (flags&ALT)
+ for (; prec--; *t++ = '0');
+ else if (dotrim) {
+ while (t > startp && *--t == '0');
+ if (*t != '.')
+ ++t;
+ }
+ }
+ return (t - startp);
+}
+
+#endif /* defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) */
diff --git a/gnu/dist/libio/iovfscanf.c b/gnu/dist/libio/iovfscanf.c
new file mode 100644
index 00000000000..0631458f21e
--- /dev/null
+++ b/gnu/dist/libio/iovfscanf.c
@@ -0,0 +1,790 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Extensively hacked for GNU iostream by Per Bothner 1991, 1992, 1993.
+ Changes copyright Free Software Foundation 1992, 1993. */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+#include <libioP.h>
+#include <ctype.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifndef NO_FLOATING_POINT
+#define FLOATING_POINT
+#endif
+
+#ifdef FLOATING_POINT
+#include "floatio.h"
+#define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
+#else
+#define BUF 40
+#endif
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x01 /* l: long or double */
+#define LONGDBL 0x02 /* L: long double; unimplemented */
+#define SHORT 0x04 /* h: short */
+#define SUPPRESS 0x08 /* suppress assignment */
+#define POINTER 0x10 /* weird %p pointer (`fake hex') */
+#define NOSKIP 0x20 /* do not skip blanks */
+#define WIDTH 0x40 /* width */
+
+/*
+ * The following are used in numeric conversions only:
+ * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+
+#define DPTOK 0x100 /* (float) decimal point is still legal */
+#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
+
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* integer, i.e., strtol or strtoul */
+#define CT_FLOAT 4 /* floating, i.e., strtod */
+
+#define u_char unsigned char
+#define u_long unsigned long
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern u_long strtoul __P((const char*, char**, int));
+extern long strtol __P((const char*, char**, int));
+static const u_char *__sccl __P((char *tab, const u_char *fmt));
+#ifndef _IO_USE_DTOA
+extern double atof();
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* If errp != NULL, *errp|=1 if we see a premature EOF;
+ *errp|=2 if we an invalid character. */
+
+int
+_IO_vfscanf (fp, fmt0, ap, errp)
+ _IO_FILE *fp;
+ char const *fmt0;
+ _IO_va_list ap;
+ int *errp;
+{
+ register const u_char *fmt = (const u_char *)fmt0;
+ register int c; /* character from format, or conversion */
+ register _IO_ssize_t width; /* field width, or 0 */
+ register char *p; /* points into all kinds of strings */
+ register int n; /* handy integer */
+ register int flags = 0; /* flags as defined above */
+ register char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nread; /* number of characters consumed from fp */
+ /* Assignments to base and ccfn are just to suppress warnings from gcc.*/
+ int base = 0; /* base argument to strtol/strtoul */
+ typedef u_long (*strtoulfn) __P((const char*, char**, int));
+ strtoulfn ccfn = 0;
+ /* conversion function (strtol/strtoul) */
+ char ccltab[256]; /* character class table for %[...] */
+ char buf[BUF]; /* buffer for numeric conversions */
+ int seen_eof = 0;
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ nassigned = 0;
+ nread = 0;
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ goto done;
+ if (isspace(c)) {
+ for (;;) {
+ c = _IO_getc(fp);
+ if (c == EOF) {
+ seen_eof++;
+ break;
+ }
+ if (!isspace(c)) {
+ _IO_ungetc (c, fp);
+ break;
+ }
+ nread++;
+ }
+ continue;
+ }
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+ switch (c) {
+ case '%':
+literal:
+ n = _IO_getc(fp);
+ if (n == EOF)
+ goto eof_failure;
+ if (n != c) {
+ _IO_ungetc (n, fp);
+ goto match_failure;
+ }
+ nread++;
+ continue;
+
+ case '*':
+ if (flags) goto control_failure;
+ flags = SUPPRESS;
+ goto again;
+ case 'l':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= LONG;
+ goto again;
+ case 'L':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= WIDTH;
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ * Those marked `compat' are for 4.[123]BSD compatibility.
+ *
+ * (According to ANSI, E and X formats are supposed
+ * to the same as e and x. Sorry about that.)
+ */
+ case 'D': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'd':
+ c = CT_INT;
+ ccfn = (strtoulfn)strtol;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ ccfn = (strtoulfn)strtol;
+ base = 0;
+ break;
+
+ case 'O': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'o':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 10;
+ break;
+
+ case 'X':
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 16;
+ break;
+
+#ifdef FLOATING_POINT
+ case 'E': case 'F':
+ case 'e': case 'f': case 'g':
+ c = CT_FLOAT;
+ break;
+#endif
+
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ fmt = __sccl(ccltab, fmt);
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 16;
+ break;
+
+ case 'n':
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORT)
+ *va_arg(ap, short *) = nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+
+ /*
+ * Disgusting backwards compatibility hacks. XXX
+ */
+ case '\0': /* compat */
+ nassigned = EOF;
+ goto done;
+
+ default: /* compat */
+ if (isupper(c))
+ flags |= LONG;
+ c = CT_INT;
+ ccfn = (strtoulfn)strtol;
+ base = 10;
+ break;
+ }
+
+ /*
+ * We have a conversion that requires input.
+ */
+ if (_IO_peekc(fp) == EOF)
+ goto eof_failure;
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ n = (unsigned char)*fp->_IO_read_ptr;
+ while (isspace(n)) {
+ fp->_IO_read_ptr++;
+ nread++;
+ n = _IO_peekc(fp);
+ if (n == EOF)
+ goto eof_failure;
+ }
+ /* Note that there is at least one character in
+ the buffer, so conversions that do not set NOSKIP
+ can no longer result in an input failure. */
+ }
+
+ /*
+ * Do the conversion.
+ */
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0) /* FIXME! */
+ width = 1;
+ if (flags & SUPPRESS) {
+ _IO_size_t sum = 0;
+ for (;;) {
+ n = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (n < (int)width) {
+ sum += n;
+ width -= n;
+ fp->_IO_read_ptr += n;
+ if (__underflow(fp) == EOF)
+ if (sum == 0)
+ goto eof_failure;
+ else {
+ seen_eof++;
+ break;
+ }
+ } else {
+ sum += width;
+ fp->_IO_read_ptr += width;
+ break;
+ }
+ }
+ nread += sum;
+ } else {
+ _IO_size_t r =
+
+ _IO_XSGETN (fp, (char*)va_arg(ap, char*), width);
+ if (r != width)
+ goto eof_failure;
+ nread += r;
+ nassigned++;
+ }
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = ~0; /* `infinity' */
+ /* take only those things in the class */
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[(unsigned char)*fp->_IO_read_ptr]) {
+ n++, fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ if (n == 0)
+ goto eof_failure;
+ seen_eof++;
+ break;
+ }
+ }
+ if (n == 0)
+ goto match_failure;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (ccltab[(unsigned char)*fp->_IO_read_ptr]) {
+ *p++ = *fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ if (p == p0)
+ goto eof_failure;
+ seen_eof++;
+ break;
+ }
+ }
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ }
+ nread += n;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = ~0;
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace((unsigned char)*fp->_IO_read_ptr)) {
+ n++, fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break;
+ }
+ }
+ nread += n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace((unsigned char)*fp->_IO_read_ptr)) {
+ *p++ = *fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break;
+ }
+ }
+ *p = 0;
+ nread += p - p0;
+ nassigned++;
+ }
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by strtol/strtoul */
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = (unsigned char)*fp->_IO_read_ptr;
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto ok;
+ }
+ break;
+
+ /* x ok iff flag still set & 2nd char */
+ case 'x': case 'X':
+ if (flags & PFXOK && p == buf + 1) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = c;
+ fp->_IO_read_ptr++;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break; /* EOF */
+ }
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf)
+ (void) _IO_ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ c = ((u_char *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ (void) _IO_ungetc (c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ u_long res;
+
+ *p = 0;
+ res = (*ccfn)(buf, (char **)NULL, base);
+ if (flags & POINTER)
+ *va_arg(ap, void **) = (void *)res;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = res;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = res;
+ else
+ *va_arg(ap, int *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+
+#ifdef FLOATING_POINT
+ case CT_FLOAT:
+ /* scan a floating point number as if by strtod */
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+ flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
+ for (p = buf; width; width--) {
+ c = (unsigned char)*fp->_IO_read_ptr;
+ /*
+ * This code mimicks the integer conversion
+ * code, but is much simpler.
+ */
+ switch (c) {
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ flags &= ~(SIGNOK | NDIGITS);
+ goto fok;
+
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto fok;
+ }
+ break;
+ case '.':
+ if (flags & DPTOK) {
+ flags &= ~(SIGNOK | DPTOK);
+ goto fok;
+ }
+ break;
+ case 'e': case 'E':
+ /* no exponent without some digits */
+ if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
+ flags =
+ (flags & ~(EXPOK|DPTOK)) |
+ SIGNOK | NDIGITS;
+ goto fok;
+ }
+ break;
+ }
+ break;
+ fok:
+ *p++ = c;
+ fp->_IO_read_ptr++;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break; /* EOF */
+ }
+ }
+ /*
+ * If no digits, might be missing exponent digits
+ * (just give back the exponent) or might be missing
+ * regular digits, but had sign and/or decimal point.
+ */
+ if (flags & NDIGITS) {
+ if (flags & EXPOK) {
+ /* no digits at all */
+ while (p > buf)
+ _IO_ungetc (*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ /* just a bad exponent (e and maybe sign) */
+ c = *(u_char *)--p;
+ if (c != 'e' && c != 'E') {
+ (void) _IO_ungetc (c, fp);/* sign */
+ c = *(u_char *)--p;
+ }
+ (void) _IO_ungetc (c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ double res;
+ *p = 0;
+#ifdef _IO_USE_DTOA
+ res = _IO_strtod(buf, NULL);
+#else
+ res = atof(buf);
+#endif
+ if (flags & LONG)
+ *va_arg(ap, double *) = res;
+ else
+ *va_arg(ap, float *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+#endif /* FLOATING_POINT */
+ }
+ }
+eof_failure:
+ seen_eof++;
+input_failure:
+ if (nassigned == 0)
+ nassigned = -1;
+control_failure:
+match_failure:
+ if (errp)
+ *errp |= 2;
+done:
+ if (errp && seen_eof)
+ *errp |= 1;
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static const u_char *
+__sccl (tab, fmt)
+ char *tab;
+ const u_char *fmt;
+{
+ register int c, n, v;
+
+ /* first `clear' the whole table */
+ c = *fmt++; /* first char hat => negated scanset */
+ if (c == '^') {
+ v = 1; /* default => accept */
+ c = *fmt++; /* get new first char */
+ } else
+ v = 0; /* default => reject */
+ /* should probably use memset here */
+ for (n = 0; n < 256; n++)
+ tab[n] = v;
+ if (c == 0)
+ return (fmt - 1);/* format ended before closing ] */
+
+ /*
+ * Now set the entries corresponding to the actual scanset
+ * to the opposite of the above.
+ *
+ * The first character may be ']' (or '-') without being special;
+ * the last character may be '-'.
+ */
+ v = 1 - v;
+ for (;;) {
+ tab[c] = v; /* take character c */
+doswitch:
+ n = *fmt++; /* and examine the next */
+ switch (n) {
+
+ case 0: /* format ended too soon */
+ return (fmt - 1);
+
+ case '-':
+ /*
+ * A scanset of the form
+ * [01+-]
+ * is defined as `the digit 0, the digit 1,
+ * the character +, the character -', but
+ * the effect of a scanset such as
+ * [a-zA-Z0-9]
+ * is implementation defined. The V7 Unix
+ * scanf treats `a-z' as `the letters a through
+ * z', but treats `a-a' as `the letter a, the
+ * character -, and the letter a'.
+ *
+ * For compatibility, the `-' is not considerd
+ * to define a range if the character following
+ * it is either a close bracket (required by ANSI)
+ * or is not numerically greater than the character
+ * we just stored in the table (c).
+ */
+ n = *fmt;
+ if (n == ']' || n < c) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ do { /* fill in the range */
+ tab[++c] = v;
+ } while (c < n);
+#if 1 /* XXX another disgusting compatibility hack */
+ /*
+ * Alas, the V7 Unix scanf also treats formats
+ * such as [a-c-e] as `the letters a through e'.
+ * This too is permitted by the standard....
+ */
+ goto doswitch;
+#else
+ c = *fmt++;
+ if (c == 0)
+ return (fmt - 1);
+ if (c == ']')
+ return (fmt);
+#endif
+ break;
+
+ case ']': /* end of scanset */
+ return (fmt);
+
+ default: /* just another character */
+ c = n;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
diff --git a/gnu/dist/libio/iovsprintf.c b/gnu/dist/libio/iovsprintf.c
new file mode 100644
index 00000000000..7b82591974d
--- /dev/null
+++ b/gnu/dist/libio/iovsprintf.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+int
+_IO_vsprintf (string, format, args)
+ char *string;
+ const char *format;
+ _IO_va_list args;
+{
+ _IO_strfile sf;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ int ret;
+
+#ifdef _IO_MTSAFE_IO
+ sf._sbf._f._lock = &lock;
+#endif
+ _IO_init (&sf._sbf._f, 0);
+ _IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
+ _IO_str_init_static (&sf._sbf._f, string, -1, string);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, &sf);
+ _IO_flockfile (&sf._sbf._f);
+ ret = _IO_vfprintf (&sf._sbf._f, format, args);
+ _IO_putc_unlocked ('\0', &sf._sbf._f);
+ _IO_cleanup_region_end (1);
+ return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vsprintf, vsprintf)
+#else
+#ifdef __linux__
+#pragma weak vsprintf = _IO_vsprintf
+#endif
+#endif
diff --git a/gnu/dist/libio/iovsscanf.c b/gnu/dist/libio/iovsscanf.c
new file mode 100644
index 00000000000..beb0bc3a6b2
--- /dev/null
+++ b/gnu/dist/libio/iovsscanf.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+int
+_IO_vsscanf (string, format, args)
+ const char *string;
+ const char *format;
+ _IO_va_list args;
+{
+ int ret;
+ _IO_strfile sf;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+ sf._sbf._f._lock = &lock;
+#endif
+ _IO_init (&sf._sbf._f, 0);
+ _IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
+ _IO_str_init_static (&sf._sbf._f, (char*)string, 0, NULL);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, &sf);
+ _IO_flockfile (&sf._sbf._f);
+ ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
+ _IO_cleanup_region_end (1);
+ return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vsscanf, __vsscanf)
+weak_alias (_IO_vsscanf, vsscanf)
+#else
+#ifdef __linux__
+#pragma weak vsscanf = _IO_vsscanf
+#endif
+#endif
diff --git a/gnu/dist/libio/isgetline.cc b/gnu/dist/libio/isgetline.cc
new file mode 100644
index 00000000000..2a2cd0f58a7
--- /dev/null
+++ b/gnu/dist/libio/isgetline.cc
@@ -0,0 +1,143 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+#include "iostream.h"
+#include <string.h>
+
+istream& istream::getline(char* buf, int len, char delim)
+{
+ _gcount = 0;
+ if (len <= 0)
+ {
+ set(ios::failbit);
+ return *this;
+ }
+ int ch;
+ if (ipfx1())
+ {
+ streambuf *sb = rdbuf();
+ _gcount = _IO_getline_info(sb, buf, len - 1, delim, -1, &ch);
+ if (ch != EOF)
+ ch = sb->sbumpc();
+ if (ch == EOF)
+ set (_gcount == 0 ? (ios::failbit|ios::eofbit) : ios::eofbit);
+ else if (ch != (unsigned char) delim)
+ {
+ set(ios::failbit);
+ sb->sungetc(); // Leave delimiter unread.
+ }
+ }
+ else
+ ch = EOF;
+ buf[_gcount] = '\0';
+ if (ch == (unsigned char)delim)
+ _gcount++; // The delimiter is counted in the gcount().
+ return *this;
+}
+
+istream& istream::get(char* buf, int len, char delim)
+{
+ _gcount = 0;
+ if (len <= 0)
+ {
+ set(ios::failbit);
+ return *this;
+ }
+ if (ipfx1())
+ {
+ streambuf *sbuf = rdbuf();
+ int ch;
+ long count = _IO_getline_info(sbuf, buf, len - 1, delim, -1, &ch);
+ if (_gcount == 0 && ch == EOF)
+ set(ios::failbit|ios::eofbit);
+ else
+ _gcount = count;
+ }
+ buf[_gcount] = '\0';
+ return *this;
+}
+
+
+// from Doug Schmidt
+
+#define CHUNK_SIZE 512
+
+/* Reads an arbitrarily long input line terminated by a user-specified
+ TERMINATOR. Super-nifty trick using recursion avoids unnecessary calls
+ to NEW! */
+
+char *_sb_readline (streambuf *sb, long& total, char terminator)
+{
+ char buf[CHUNK_SIZE];
+ char *ptr;
+ int ch;
+
+ _IO_size_t count = _IO_getline_info(sb, buf, CHUNK_SIZE, terminator,
+ -1, &ch);
+ if (ch != EOF)
+ ch = sb->sbumpc();
+ long old_total = total;
+ total += count;
+ if (ch != EOF && ch != terminator) {
+ total++; // Include ch in total.
+ ptr = _sb_readline(sb, total, terminator);
+ if (ptr) {
+ memcpy(ptr + old_total, buf, count);
+ ptr[old_total+count] = ch;
+ }
+ return ptr;
+ }
+
+ ptr = new char[total+1];
+ if (ptr != NULL) {
+ ptr[total] = '\0';
+ memcpy(ptr + total - count, buf, count);
+ }
+ return ptr;
+}
+
+/* Reads an arbitrarily long input line terminated by TERMINATOR.
+ This routine allocates its own memory, so the user should
+ only supply the address of a (char *). */
+
+istream& istream::gets(char **s, char delim /* = '\n' */)
+{
+ if (ipfx1()) {
+ long size = 0;
+ streambuf *sb = rdbuf();
+ *s = _sb_readline (sb, size, delim);
+ _gcount = *s ? size : 0;
+ if (sb->_flags & _IO_EOF_SEEN) {
+ set(ios::eofbit);
+ if (_gcount == 0)
+ set(ios::failbit);
+ }
+ }
+ else {
+ _gcount = 0;
+ *s = NULL;
+ }
+ return *this;
+}
diff --git a/gnu/dist/libio/isgetsb.cc b/gnu/dist/libio/isgetsb.cc
new file mode 100644
index 00000000000..55617e649a0
--- /dev/null
+++ b/gnu/dist/libio/isgetsb.cc
@@ -0,0 +1,59 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "iostream.h"
+#include <string.h>
+
+istream& istream::get(streambuf& sb, char delim /* = '\n' */)
+{
+ _gcount = 0;
+ if (ipfx1())
+ {
+ register streambuf* isb = rdbuf();
+ for (;;)
+ {
+ streamsize len = isb->_IO_read_end - isb->_IO_read_ptr;
+ if (len <= 0)
+ if (__underflow(isb) == EOF)
+ break;
+ else
+ len = isb->_IO_read_end - isb->_IO_read_ptr;
+ char *delimp = (char*)memchr((void*)isb->_IO_read_ptr, delim, len);
+ if (delimp != NULL)
+ len = delimp - isb->_IO_read_ptr;
+ int written = sb.sputn(isb->_IO_read_ptr, len);
+ isb->_IO_read_ptr += written;
+ _gcount += written;
+ if (written != len)
+ {
+ set(ios::failbit);
+ break;
+ }
+ if (delimp != NULL)
+ break;
+ }
+ }
+ return *this;
+}
diff --git a/gnu/dist/libio/isscan.cc b/gnu/dist/libio/isscan.cc
new file mode 100644
index 00000000000..64d4bc682f8
--- /dev/null
+++ b/gnu/dist/libio/isscan.cc
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <iostream.h>
+#include <stdarg.h>
+
+istream& istream::scan(const char *format ...)
+{
+ if (ipfx0()) {
+ va_list ap;
+ va_start(ap, format);
+ _strbuf->vscan(format, ap, this);
+ va_end(ap);
+ }
+ return *this;
+}
+
+istream& istream::vscan(const char *format, _IO_va_list args)
+{
+ if (ipfx0())
+ _strbuf->vscan(format, args, this);
+ return *this;
+}
diff --git a/gnu/dist/libio/istream.h b/gnu/dist/libio/istream.h
new file mode 100644
index 00000000000..f54ec1de9a1
--- /dev/null
+++ b/gnu/dist/libio/istream.h
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <stream.h>
diff --git a/gnu/dist/libio/libio.h b/gnu/dist/libio/libio.h
new file mode 100644
index 00000000000..e652b46ca16
--- /dev/null
+++ b/gnu/dist/libio/libio.h
@@ -0,0 +1,356 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+ Written by Per Bothner <bothner@cygnus.com>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#ifndef _IO_STDIO_H
+#define _IO_STDIO_H
+
+#include <_G_config.h>
+#define _IO_pos_t _G_fpos_t /* obsolete */
+#define _IO_fpos_t _G_fpos_t
+#define _IO_size_t _G_size_t
+#define _IO_ssize_t _G_ssize_t
+#define _IO_off_t _G_off_t
+#define _IO_pid_t _G_pid_t
+#define _IO_uid_t _G_uid_t
+#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT
+#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE
+#define _IO_BUFSIZ _G_BUFSIZ
+#define _IO_va_list _G_va_list
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+#define _IO_fpos64_t _G_fpos64_t
+#define _IO_off64_t _G_off64_t
+#endif
+
+#ifdef _G_NEED_STDARG_H
+/* This define avoids name pollution if we're using GNU stdarg.h */
+# define __need___va_list
+# include <stdarg.h>
+# ifdef __GNUC_VA_LIST
+# undef _IO_va_list
+# define _IO_va_list __gnuc_va_list
+# endif /* __GNUC_VA_LIST */
+#endif
+
+#ifndef __P
+# if _G_HAVE_SYS_CDEFS
+# include <sys/cdefs.h>
+# else
+# ifdef __STDC__
+# define __P(protos) protos
+# else
+# define __P(protos) ()
+# endif
+# endif
+#endif /*!__P*/
+
+/* For backward compatibility */
+#ifndef _PARAMS
+# define _PARAMS(protos) __P(protos)
+#endif /*!_PARAMS*/
+
+#ifndef __STDC__
+# define const
+#endif
+#define _IO_UNIFIED_JUMPTABLES 1
+#if !_G_HAVE_PRINTF_FP
+# define _IO_USE_DTOA 1
+#endif
+
+#ifndef EOF
+# define EOF (-1)
+#endif
+#ifndef NULL
+# if defined __GNUG__ && \
+ (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+# define NULL (__null)
+# else
+# if !defined(__cplusplus)
+# define NULL ((void*)0)
+# else
+# define NULL (0)
+# endif
+# endif
+#endif
+
+#define _IOS_INPUT 1
+#define _IOS_OUTPUT 2
+#define _IOS_ATEND 4
+#define _IOS_APPEND 8
+#define _IOS_TRUNC 16
+#define _IOS_NOCREATE 32
+#define _IOS_NOREPLACE 64
+#define _IOS_BIN 128
+
+/* Magic numbers and bits for the _flags field.
+ The magic numbers use the high-order bits of _flags;
+ the remaining bits are available for variable flags.
+ Note: The magic numbers must all be negative if stdio
+ emulation is desired. */
+
+#define _IO_MAGIC 0xFBAD0000 /* Magic number */
+#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
+#define _IO_MAGIC_MASK 0xFFFF0000
+#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */
+#define _IO_UNBUFFERED 2
+#define _IO_NO_READS 4 /* Reading not allowed */
+#define _IO_NO_WRITES 8 /* Writing not allowd */
+#define _IO_EOF_SEEN 0x10
+#define _IO_ERR_SEEN 0x20
+#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */
+#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/
+#define _IO_IN_BACKUP 0x100
+#define _IO_LINE_BUF 0x200
+#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */
+#define _IO_CURRENTLY_PUTTING 0x800
+#define _IO_IS_APPENDING 0x1000
+#define _IO_IS_FILEBUF 0x2000
+#define _IO_BAD_SEEN 0x4000
+
+/* These are "formatting flags" matching the iostream fmtflags enum values. */
+#define _IO_SKIPWS 01
+#define _IO_LEFT 02
+#define _IO_RIGHT 04
+#define _IO_INTERNAL 010
+#define _IO_DEC 020
+#define _IO_OCT 040
+#define _IO_HEX 0100
+#define _IO_SHOWBASE 0200
+#define _IO_SHOWPOINT 0400
+#define _IO_UPPERCASE 01000
+#define _IO_SHOWPOS 02000
+#define _IO_SCIENTIFIC 04000
+#define _IO_FIXED 010000
+#define _IO_UNITBUF 020000
+#define _IO_STDIO 040000
+#define _IO_DONT_CLOSE 0100000
+#define _IO_BOOLALPHA 0200000
+
+
+struct _IO_jump_t; struct _IO_FILE;
+
+/* Handle lock. */
+#ifdef _IO_MTSAFE_IO
+# if defined __GLIBC__ && __GLIBC__ >= 2
+# if __GLIBC_MINOR__ > 0
+# include <bits/stdio-lock.h>
+# else
+# include <stdio-lock.h>
+# endif
+# define _IO_LOCK_T _IO_lock_t *
+# else
+/*# include <comthread.h>*/
+# endif
+#else
+# if defined(__GLIBC__) && __GLIBC__ >= 2
+ typedef void _IO_lock_t;
+# define _IO_LOCK_T void *
+# else
+# ifdef __linux__
+ struct _IO_lock_t { void *ptr; short int field1; short int field2; };
+# define _IO_LOCK_T struct _IO_lock_t
+# else
+ typedef void _IO_lock_t;
+# endif
+# endif
+#endif
+
+
+/* A streammarker remembers a position in a buffer. */
+
+struct _IO_marker {
+ struct _IO_marker *_next;
+ struct _IO_FILE *_sbuf;
+ /* If _pos >= 0
+ it points to _buf->Gbase()+_pos. FIXME comment */
+ /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */
+ int _pos;
+#if 0
+ void set_streampos(streampos sp) { _spos = sp; }
+ void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); }
+ public:
+ streammarker(streambuf *sb);
+ ~streammarker();
+ int saving() { return _spos == -2; }
+ int delta(streammarker&);
+ int delta();
+#endif
+};
+
+struct _IO_FILE {
+ int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
+#define _IO_file_flags _flags
+
+ /* The following pointers correspond to the C++ streambuf protocol. */
+ /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
+ char* _IO_read_ptr; /* Current read pointer */
+ char* _IO_read_end; /* End of get area. */
+ char* _IO_read_base; /* Start of putback+get area. */
+ char* _IO_write_base; /* Start of put area. */
+ char* _IO_write_ptr; /* Current put pointer. */
+ char* _IO_write_end; /* End of put area. */
+ char* _IO_buf_base; /* Start of reserve area. */
+ char* _IO_buf_end; /* End of reserve area. */
+ /* The following fields are used to support backing up and undo. */
+ char *_IO_save_base; /* Pointer to start of non-current get area. */
+ char *_IO_backup_base; /* Pointer to first valid character of backup area */
+ char *_IO_save_end; /* Pointer to end of non-current get area. */
+
+ struct _IO_marker *_markers;
+
+ struct _IO_FILE *_chain;
+
+ int _fileno;
+ int _blksize;
+#ifdef _G_IO_IO_FILE_VERSION
+ _IO_off_t _old_offset;
+#else
+ _IO_off_t _offset;
+#endif
+
+#define __HAVE_COLUMN /* temporary */
+ /* 1+column number of pbase(); 0 is unknown. */
+ unsigned short _cur_column;
+ char _unused;
+ char _shortbuf[1];
+
+ /* char* _save_gptr; char* _save_egptr; */
+
+#ifdef _IO_LOCK_T
+ _IO_LOCK_T _lock;
+#endif
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+ _IO_off64_t _offset;
+ int _unused2[16]; /* Make sure we don't get into trouble again. */
+#endif
+};
+
+#ifndef __cplusplus
+typedef struct _IO_FILE _IO_FILE;
+#endif
+
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+#define _IO_stdin_ _IO_2_1_stdin_
+#define _IO_stdout_ _IO_2_1_stdout_
+#define _IO_stderr_ _IO_2_1_stderr_
+#endif
+
+struct _IO_FILE_plus;
+extern struct _IO_FILE_plus _IO_stdin_, _IO_stdout_, _IO_stderr_;
+#define _IO_stdin ((_IO_FILE*)(&_IO_stdin_))
+#define _IO_stdout ((_IO_FILE*)(&_IO_stdout_))
+#define _IO_stderr ((_IO_FILE*)(&_IO_stderr_))
+
+
+/* Define the user-visible type, with user-friendly member names. */
+typedef struct
+{
+ _IO_ssize_t (*read) __P ((struct _IO_FILE *, void *, _IO_ssize_t));
+ _IO_ssize_t (*write) __P ((struct _IO_FILE *, const void *, _IO_ssize_t));
+ _IO_fpos_t (*seek) __P ((struct _IO_FILE *, _IO_off_t, int));
+ int (*close) __P ((struct _IO_FILE *));
+} _IO_cookie_io_functions_t;
+
+/* Special file type for fopencookie function. */
+struct _IO_cookie_file
+{
+ struct _IO_FILE file;
+ const void *vtable;
+ void *cookie;
+ _IO_cookie_io_functions_t io_functions;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int __underflow __P ((_IO_FILE *));
+extern int __uflow __P ((_IO_FILE *));
+extern int __overflow __P ((_IO_FILE *, int));
+
+#define _IO_getc_unlocked(_fp) \
+ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow (_fp) \
+ : *(unsigned char *) (_fp)->_IO_read_ptr++)
+#define _IO_peekc_unlocked(_fp) \
+ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \
+ && __underflow (_fp) == EOF ? EOF \
+ : *(unsigned char *) (_fp)->_IO_read_ptr)
+
+#define _IO_putc_unlocked(_ch, _fp) \
+ (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \
+ ? __overflow (_fp, (unsigned char) (_ch)) \
+ : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))
+
+#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
+#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+
+extern int _IO_getc __P ((_IO_FILE *__fp));
+extern int _IO_putc __P ((int __c, _IO_FILE *__fp));
+extern int _IO_feof __P ((_IO_FILE *__fp));
+extern int _IO_ferror __P ((_IO_FILE *__fp));
+
+extern int _IO_peekc_locked __P ((_IO_FILE *__fp));
+
+/* This one is for Emacs. */
+#define _IO_PENDING_OUTPUT_COUNT(_fp) \
+ ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)
+
+extern void _IO_flockfile __P ((_IO_FILE *));
+extern void _IO_funlockfile __P ((_IO_FILE *));
+extern int _IO_ftrylockfile __P ((_IO_FILE *));
+
+#ifdef _IO_MTSAFE_IO
+# define _IO_peekc(_fp) _IO_peekc_locked (_fp)
+#else
+# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)
+# define _IO_flockfile(_fp) /**/
+# define _IO_funlockfile(_fp) /**/
+# define _IO_ftrylockfile(_fp) /**/
+# define _IO_cleanup_region_start(_fct, _fp) /**/
+# define _IO_cleanup_region_end(_Doit) /**/
+#endif /* !_IO_MTSAFE_IO */
+
+
+extern int _IO_vfscanf __P ((_IO_FILE *, const char *, _IO_va_list, int *));
+extern int _IO_vfprintf __P ((_IO_FILE *, const char *, _IO_va_list));
+extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t));
+extern _IO_size_t _IO_sgetn __P ((_IO_FILE *, void *, _IO_size_t));
+
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int));
+#else
+extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
+#endif
+
+extern void _IO_free_backup_area __P ((_IO_FILE *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IO_STDIO_H */
diff --git a/gnu/dist/libio/libioP.h b/gnu/dist/libio/libioP.h
new file mode 100644
index 00000000000..8f39e0ef67c
--- /dev/null
+++ b/gnu/dist/libio/libioP.h
@@ -0,0 +1,641 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+#if defined __GLIBC__ && __GLIBC__ >= 2
+# if __GLIBC_MINOR__ > 0
+# include <bits/libc-lock.h>
+# else
+# include <libc-lock.h>
+# endif
+#else
+/*# include <comthread.h>*/
+#endif
+
+#include "iolibio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _IO_seek_set 0
+#define _IO_seek_cur 1
+#define _IO_seek_end 2
+
+/* THE JUMPTABLE FUNCTIONS.
+
+ * The _IO_FILE type is used to implement the FILE type in GNU libc,
+ * as well as the streambuf class in GNU iostreams for C++.
+ * These are all the same, just used differently.
+ * An _IO_FILE (or FILE) object is allows followed by a pointer to
+ * a jump table (of pointers to functions). The pointer is accessed
+ * with the _IO_JUMPS macro. The jump table has a eccentric format,
+ * so as to be compatible with the layout of a C++ virtual function table.
+ * (as implemented by g++). When a pointer to a streambuf object is
+ * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just
+ * happens to point to the virtual function table of the streambuf.
+ * Thus the _IO_JUMPS function table used for C stdio/libio does
+ * double duty as the virtual function table for C++ streambuf.
+ *
+ * The entries in the _IO_JUMPS function table (and hence also the
+ * virtual functions of a streambuf) are described below.
+ * The first parameter of each function entry is the _IO_FILE/streambuf
+ * object being acted on (i.e. the 'this' parameter).
+ */
+
+#define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable
+#ifdef _G_USING_THUNKS
+# define JUMP_FIELD(TYPE, NAME) TYPE NAME
+# define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC (THIS)
+# define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC (THIS, X1)
+# define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC (THIS, X1, X2)
+# define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC (THIS, X1,X2, X3)
+# define JUMP_INIT(NAME, VALUE) VALUE
+# define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0)
+#else
+/* These macros will change when we re-implement vtables to use "thunks"! */
+# define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME
+# define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC.pfn (THIS)
+# define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1)
+# define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1, X2)
+# define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1,X2,X3)
+# define JUMP_INIT(NAME, VALUE) {0, 0, VALUE}
+# define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0)
+#endif
+
+/* The 'finish' function does any final cleaning up of an _IO_FILE object.
+ It does not delete (free) it, but does everything else to finalize it/
+ It matches the streambuf::~streambuf virtual destructor. */
+typedef void (*_IO_finish_t) __P ((_IO_FILE *, int)); /* finalize */
+#define _IO_FINISH(FP) JUMP1 (__finish, FP, 0)
+
+/* The 'overflow' hook flushes the buffer.
+ The second argument is a character, or EOF.
+ It matches the streambuf::overflow virtual function. */
+typedef int (*_IO_overflow_t) __P ((_IO_FILE *, int));
+#define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH)
+
+/* The 'underflow' hook tries to fills the get buffer.
+ It returns the next character (as an unsigned char) or EOF. The next
+ character remains in the get buffer, and the get position is not changed.
+ It matches the streambuf::underflow virtual function. */
+typedef int (*_IO_underflow_t) __P ((_IO_FILE *));
+#define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP)
+
+/* The 'uflow' hook returns the next character in the input stream
+ (cast to unsigned char), and increments the read position;
+ EOF is returned on failure.
+ It matches the streambuf::uflow virtual function, which is not in the
+ cfront implementation, but was added to C++ by the ANSI/ISO committee. */
+#define _IO_UFLOW(FP) JUMP0 (__uflow, FP)
+
+/* The 'pbackfail' hook handles backing up.
+ It matches the streambuf::pbackfail virtual function. */
+typedef int (*_IO_pbackfail_t) __P ((_IO_FILE *, int));
+#define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH)
+
+/* The 'xsputn' hook writes upto N characters from buffer DATA.
+ Returns the number of character actually written.
+ It matches the streambuf::xsputn virtual function. */
+typedef _IO_size_t (*_IO_xsputn_t) __P ((_IO_FILE *FP, const void *DATA,
+ _IO_size_t N));
+#define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N)
+
+/* The 'xsgetn' hook reads upto N characters into buffer DATA.
+ Returns the number of character actually read.
+ It matches the streambuf::xsgetn virtual function. */
+typedef _IO_size_t (*_IO_xsgetn_t) __P ((_IO_FILE *FP, void *DATA,
+ _IO_size_t N));
+#define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N)
+
+/* The 'seekoff' hook moves the stream position to a new position
+ relative to the start of the file (if DIR==0), the current position
+ (MODE==1), or the end of the file (MODE==2).
+ It matches the streambuf::seekoff virtual function.
+ It is also used for the ANSI fseek function. */
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+typedef _IO_fpos64_t (*_IO_seekoff_t) __P ((_IO_FILE *FP, _IO_off64_t OFF,
+ int DIR, int MODE));
+#else
+typedef _IO_fpos_t (*_IO_seekoff_t) __P ((_IO_FILE *FP, _IO_off_t OFF,
+ int DIR, int MODE));
+#endif
+#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE)
+
+/* The 'seekpos' hook also moves the stream position,
+ but to an absolute position given by a fpos_t (seekpos).
+ It matches the streambuf::seekpos virtual function.
+ It is also used for the ANSI fgetpos and fsetpos functions. */
+/* The _IO_seek_cur and _IO_seek_end options are not allowed. */
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+typedef _IO_fpos64_t (*_IO_seekpos_t) __P ((_IO_FILE *, _IO_fpos64_t, int));
+#else
+typedef _IO_fpos_t (*_IO_seekpos_t) __P ((_IO_FILE *, _IO_fpos_t, int));
+#endif
+#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS)
+
+/* The 'setbuf' hook gives a buffer to the file.
+ It matches the streambuf::setbuf virtual function. */
+typedef _IO_FILE* (*_IO_setbuf_t) __P ((_IO_FILE *, char *, _IO_ssize_t));
+#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH)
+
+/* The 'sync' hook attempts to synchronize the internal data structures
+ of the file with the external state.
+ It matches the streambuf::sync virtual function. */
+typedef int (*_IO_sync_t) __P ((_IO_FILE *));
+#define _IO_SYNC(FP) JUMP0 (__sync, FP)
+
+/* The 'doallocate' hook is used to tell the file to allocate a buffer.
+ It matches the streambuf::doallocate virtual function, which is not
+ in the ANSI/ISO C++ standard, but is part traditional implementations. */
+typedef int (*_IO_doallocate_t) __P ((_IO_FILE *));
+#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP)
+
+/* The following four hooks (sysread, syswrite, sysclose, sysseek, and
+ sysstat) are low-level hooks specific to this implementation.
+ There is no correspondence in the ANSI/ISO C++ standard library.
+ The hooks basically correspond to the Unix system functions
+ (read, write, close, lseek, and stat) except that a _IO_FILE*
+ parameter is used instead of a integer file descriptor; the default
+ implementation used for normal files just calls those functions.
+ The advantage of overriding these functions instead of the higher-level
+ ones (underflow, overflow etc) is that you can leave all the buffering
+ higher-level functions. */
+
+/* The 'sysread' hook is used to read data from the external file into
+ an existing buffer. It generalizes the Unix read(2) function.
+ It matches the streambuf::sys_read virtual function, which is
+ specific to this implementation. */
+typedef _IO_ssize_t (*_IO_read_t) __P ((_IO_FILE *, void *, _IO_ssize_t));
+#define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN)
+
+/* The 'syswrite' hook is used to write data from an existing buffer
+ to an external file. It generalizes the Unix write(2) function.
+ It matches the streambuf::sys_write virtual function, which is
+ specific to this implementation. */
+typedef _IO_ssize_t (*_IO_write_t) __P ((_IO_FILE *,const void *,_IO_ssize_t));
+#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN)
+
+/* The 'sysseek' hook is used to re-position an external file.
+ It generalizes the Unix lseek(2) function.
+ It matches the streambuf::sys_seek virtual function, which is
+ specific to this implementation. */
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+typedef _IO_fpos64_t (*_IO_seek_t) __P ((_IO_FILE *, _IO_off64_t, int));
+#else
+typedef _IO_fpos_t (*_IO_seek_t) __P ((_IO_FILE *, _IO_off_t, int));
+#endif
+#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE)
+
+/* The 'sysclose' hook is used to finalize (close, finish up) an
+ external file. It generalizes the Unix close(2) function.
+ It matches the streambuf::sys_close virtual function, which is
+ specific to this implementation. */
+typedef int (*_IO_close_t) __P ((_IO_FILE *)); /* finalize */
+#define _IO_SYSCLOSE(FP) JUMP0 (__close, FP)
+
+/* The 'sysstat' hook is used to get information about an external file
+ into a struct stat buffer. It generalizes the Unix fstat(2) call.
+ It matches the streambuf::sys_stat virtual function, which is
+ specific to this implementation. */
+typedef int (*_IO_stat_t) __P ((_IO_FILE *, void *));
+#define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF)
+
+#if _G_IO_IO_FILE_VERSION == 0x20001
+/* The 'showmany' hook can be used to get an image how much input is
+ available. In many cases the answer will be 0 which means unknown
+ but some cases one can provide real information. */
+typedef int (*_IO_showmanyc_t) __P ((_IO_FILE *));
+#define _IO_SHOWMANYC(FP) JUMP0 (__showmanyc, FP)
+
+/* The 'imbue' hook is used to get information about the currently
+ installed locales. */
+typedef void (*_IO_imbue_t) __P ((_IO_FILE *, void *));
+#define _IO_IMBUE(FP, LOCALE) JUMP1 (__imbue, FP, LOCALE)
+#endif
+
+
+#define _IO_CHAR_TYPE char /* unsigned char ? */
+#define _IO_INT_TYPE int
+
+struct _IO_jump_t
+{
+ JUMP_FIELD(_G_size_t, __dummy);
+#ifdef _G_USING_THUNKS
+ JUMP_FIELD(_G_size_t, __dummy2);
+#endif
+ JUMP_FIELD(_IO_finish_t, __finish);
+ JUMP_FIELD(_IO_overflow_t, __overflow);
+ JUMP_FIELD(_IO_underflow_t, __underflow);
+ JUMP_FIELD(_IO_underflow_t, __uflow);
+ JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
+ /* showmany */
+ JUMP_FIELD(_IO_xsputn_t, __xsputn);
+ JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
+ JUMP_FIELD(_IO_seekoff_t, __seekoff);
+ JUMP_FIELD(_IO_seekpos_t, __seekpos);
+ JUMP_FIELD(_IO_setbuf_t, __setbuf);
+ JUMP_FIELD(_IO_sync_t, __sync);
+ JUMP_FIELD(_IO_doallocate_t, __doallocate);
+ JUMP_FIELD(_IO_read_t, __read);
+ JUMP_FIELD(_IO_write_t, __write);
+ JUMP_FIELD(_IO_seek_t, __seek);
+ JUMP_FIELD(_IO_close_t, __close);
+ JUMP_FIELD(_IO_stat_t, __stat);
+#if _G_IO_IO_FILE_VERSION == 0x20001
+ JUMP_FIELD(_IO_showmanyc_t, __showmanyc);
+ JUMP_FIELD(_IO_imbue_t, __imbue);
+#endif
+#if 0
+ get_column;
+ set_column;
+#endif
+};
+
+/* We always allocate an extra word following an _IO_FILE.
+ This contains a pointer to the function jump table used.
+ This is for compatibility with C++ streambuf; the word can
+ be used to smash to a pointer to a virtual function table. */
+
+struct _IO_FILE_plus
+{
+ _IO_FILE file;
+ const struct _IO_jump_t *vtable;
+};
+
+/* Generic functions */
+
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int));
+#else
+extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
+#endif
+
+extern void _IO_switch_to_main_get_area __P ((_IO_FILE *));
+extern void _IO_switch_to_backup_area __P ((_IO_FILE *));
+extern int _IO_switch_to_get_mode __P ((_IO_FILE *));
+extern void _IO_init __P ((_IO_FILE *, int));
+extern int _IO_sputbackc __P ((_IO_FILE *, int));
+extern int _IO_sungetc __P ((_IO_FILE *));
+extern void _IO_un_link __P ((_IO_FILE *));
+extern void _IO_link_in __P ((_IO_FILE *));
+extern void _IO_doallocbuf __P ((_IO_FILE *));
+extern void _IO_unsave_markers __P ((_IO_FILE *));
+extern void _IO_setb __P ((_IO_FILE *, char *, char *, int));
+extern unsigned _IO_adjust_column __P ((unsigned, const char *, int));
+#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n)
+
+/* Marker-related function. */
+
+extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *));
+extern void _IO_remove_marker __P ((struct _IO_marker *));
+extern int _IO_marker_difference __P ((struct _IO_marker *,
+ struct _IO_marker *));
+extern int _IO_marker_delta __P ((struct _IO_marker *));
+extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int));
+
+/* Default jumptable functions. */
+
+extern int _IO_default_underflow __P ((_IO_FILE *));
+extern int _IO_default_uflow __P ((_IO_FILE *));
+extern int _IO_default_doallocate __P ((_IO_FILE *));
+extern void _IO_default_finish __P ((_IO_FILE *, int));
+extern int _IO_default_pbackfail __P ((_IO_FILE *, int));
+extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
+extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *,
+ _IO_size_t));
+extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_fpos64_t _IO_default_seekoff __P ((_IO_FILE *,
+ _IO_off64_t, int, int));
+extern _IO_fpos64_t _IO_default_seekpos __P ((_IO_FILE *,
+ _IO_fpos64_t, int));
+#else
+extern _IO_fpos_t _IO_default_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_default_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
+#endif
+extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *,
+ _IO_ssize_t));
+extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t));
+extern int _IO_default_stat __P ((_IO_FILE *, void *));
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_fpos64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int));
+#else
+extern _IO_fpos_t _IO_default_seek __P ((_IO_FILE *, _IO_off_t, int));
+#endif
+extern int _IO_default_sync __P ((_IO_FILE *));
+#define _IO_default_close ((_IO_close_t) _IO_default_sync)
+
+extern struct _IO_jump_t _IO_file_jumps;
+extern struct _IO_jump_t _IO_streambuf_jumps;
+extern struct _IO_jump_t _IO_proc_jumps;
+extern struct _IO_jump_t _IO_str_jumps;
+extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
+extern int _IO_flush_all __P ((void));
+extern void _IO_cleanup __P ((void));
+extern void _IO_flush_all_linebuffered __P ((void));
+
+#define _IO_do_flush(_f) \
+ _IO_do_write(_f, (_f)->_IO_write_base, \
+ (_f)->_IO_write_ptr-(_f)->_IO_write_base)
+#define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING)
+#define _IO_mask_flags(fp, f, mask) \
+ ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
+#define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\
+ (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg))
+#define _IO_setp(__fp, __p, __ep) \
+ ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep))
+#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
+#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
+#define _IO_have_markers(fp) ((fp)->_markers != NULL)
+#define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
+
+/* Jumptable functions for files. */
+
+extern int _IO_file_doallocate __P ((_IO_FILE *));
+extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_fpos64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_fpos64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int));
+#else
+extern _IO_fpos_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_file_seek __P ((_IO_FILE *, _IO_off_t, int));
+#endif
+extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
+extern int _IO_file_stat __P ((_IO_FILE *, void *));
+extern int _IO_file_close __P ((_IO_FILE *));
+extern int _IO_file_underflow __P ((_IO_FILE *));
+extern int _IO_file_overflow __P ((_IO_FILE *, int));
+#define _IO_file_is_open(__fp) ((__fp)->_fileno >= 0)
+extern void _IO_file_init __P ((_IO_FILE *));
+extern _IO_FILE* _IO_file_attach __P ((_IO_FILE *, int));
+extern _IO_FILE* _IO_file_open __P ((_IO_FILE *, const char *, int, int,
+ int, int));
+#if _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *,
+ int));
+#else
+extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *));
+#endif
+extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *,
+ _IO_ssize_t));
+extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t));
+extern int _IO_file_sync __P ((_IO_FILE *));
+extern int _IO_file_close_it __P ((_IO_FILE *));
+extern void _IO_file_finish __P ((_IO_FILE *, int));
+
+/* Jumptable functions for proc_files. */
+extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *));
+extern int _IO_proc_close __P ((_IO_FILE *));
+
+/* Jumptable functions for strfiles. */
+extern int _IO_str_underflow __P ((_IO_FILE *));
+extern int _IO_str_overflow __P ((_IO_FILE *, int));
+extern int _IO_str_pbackfail __P ((_IO_FILE *, int));
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+extern _IO_fpos64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+#else
+extern _IO_fpos_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+#endif
+extern void _IO_str_finish __P ((_IO_FILE *, int));
+
+/* Other strfile functions */
+extern void _IO_str_init_static __P ((_IO_FILE *, char *, int, char *));
+extern void _IO_str_init_readonly __P ((_IO_FILE *, const char *, int));
+extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *));
+
+extern int _IO_vasprintf __P ((char **result_ptr, __const char *format,
+ _IO_va_list args));
+extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg));
+extern int _IO_vsnprintf __P ((char *string, _IO_size_t maxlen,
+ __const char *format, _IO_va_list args));
+
+
+extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int));
+extern _IO_size_t _IO_getline_info __P ((_IO_FILE *,char *, _IO_size_t,
+ int, int, int *));
+extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *));
+extern double _IO_strtod __P ((const char *, char **));
+extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits,
+ int *__decpt, int *__sign, char **__rve));
+extern int _IO_outfloat __P ((double __value, _IO_FILE *__sb, int __type,
+ int __width, int __precision, int __flags,
+ int __sign_mode, int __fill));
+
+extern _IO_FILE *_IO_list_all;
+extern void (*_IO_cleanup_registration_needed) __P ((void));
+
+#ifndef EOF
+# define EOF (-1)
+#endif
+#ifndef NULL
+# if defined __GNUG__ && \
+ (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+# define NULL (__null)
+# else
+# if !defined(__cplusplus)
+# define NULL ((void*)0)
+# else
+# define NULL (0)
+# endif
+# endif
+#endif
+
+#if _G_HAVE_MMAP
+
+# include <unistd.h>
+# include <fcntl.h>
+# include <sys/mman.h>
+# include <sys/param.h>
+
+# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+
+# if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE)
+# undef _G_HAVE_MMAP
+# define _G_HAVE_MMAP 0
+# endif
+
+#endif /* _G_HAVE_MMAP */
+
+#if _G_HAVE_MMAP
+
+# ifdef _LIBC
+/* When using this code in the GNU libc we must not pollute the name space. */
+# define mmap __mmap
+# define munmap __munmap
+# endif
+
+# define ROUND_TO_PAGE(_S) \
+ (((_S) + EXEC_PAGESIZE - 1) & ~(EXEC_PAGESIZE - 1))
+
+# define FREE_BUF(_B, _S) \
+ munmap ((_B), ROUND_TO_PAGE (_S))
+# define ALLOC_BUF(_B, _S, _R) \
+ do { \
+ (_B) = (char *) mmap (0, ROUND_TO_PAGE (_S), \
+ PROT_READ | PROT_WRITE, \
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
+ if ((_B) == (char *) -1) \
+ return (_R); \
+ } while (0)
+
+#else /* _G_HAVE_MMAP */
+
+# define FREE_BUF(_B, _S) \
+ free(_B)
+# define ALLOC_BUF(_B, _S, _R) \
+ do { \
+ (_B) = (char*)malloc(_S); \
+ if ((_B) == NULL) \
+ return (_R); \
+ } while (0)
+
+#endif /* _G_HAVE_MMAP */
+
+#ifndef OS_FSTAT
+# define OS_FSTAT fstat
+#endif
+struct stat;
+extern _IO_ssize_t _IO_read __P ((int, void *, _IO_size_t));
+extern _IO_ssize_t _IO_write __P ((int, const void *, _IO_size_t));
+extern _IO_off_t _IO_lseek __P ((int, _IO_off_t, int));
+extern int _IO_close __P ((int));
+extern int _IO_fstat __P ((int, struct stat *));
+extern int _IO_vscanf __P ((const char *, _IO_va_list));
+
+/* Operations on _IO_fpos_t.
+ Normally, these are trivial, but we provide hooks for configurations
+ where an _IO_fpos_t is a struct.
+ Note that _IO_off_t must be an integral type. */
+
+/* _IO_pos_BAD is an _IO_fpos_t value indicating error, unknown, or EOF. */
+#ifndef _IO_pos_BAD
+# if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+# define _IO_pos_BAD ((_IO_fpos64_t) -1)
+# else
+# define _IO_pos_BAD ((_IO_fpos_t) -1)
+# endif
+#endif
+/* _IO_pos_as_off converts an _IO_fpos_t value to an _IO_off_t value. */
+#ifndef _IO_pos_as_off
+# if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+# define _IO_pos_as_off(__pos) ((_IO_off64_t) (__pos))
+# else
+# define _IO_pos_as_off(__pos) ((_IO_off_t) (__pos))
+# endif
+#endif
+/* _IO_pos_adjust adjust an _IO_fpos_t by some number of bytes. */
+#ifndef _IO_pos_adjust
+# define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta))
+#endif
+/* _IO_pos_0 is an _IO_fpos_t value indicating beginning of file. */
+#ifndef _IO_pos_0
+# if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+# define _IO_pos_0 ((_IO_fpos64_t) 0)
+# else
+# define _IO_pos_0 ((_IO_fpos_t) 0)
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef _IO_MTSAFE_IO
+/* check following! */
+# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
+ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
+ 0, 0, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
+#else
+/* check following! */
+# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
+ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD }
+#endif
+
+/* VTABLE_LABEL defines NAME as of the CLASS class.
+ CNLENGTH is strlen(#CLASS). */
+#ifdef __GNUC__
+# if _G_VTABLE_LABEL_HAS_LENGTH
+# define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+ extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS);
+# else
+# define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+ extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS);
+# endif
+#endif /* __GNUC__ */
+
+#if !defined(builtinbuf_vtable) && defined(__cplusplus)
+# ifdef __GNUC__
+VTABLE_LABEL(builtinbuf_vtable, builtinbuf, 10)
+# else
+# if _G_VTABLE_LABEL_HAS_LENGTH
+# define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf
+# else
+# define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf
+# endif
+# endif
+#endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */
+
+#if defined(__STDC__) || defined(__cplusplus)
+# define _IO_va_start(args, last) va_start(args, last)
+#else
+# define _IO_va_start(args, last) va_start(args)
+#endif
+
+extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf;
+
+#if 1
+# define COERCE_FILE(FILE) /* Nothing */
+#else
+/* This is part of the kludge for binary compatibility with old stdio. */
+# define COERCE_FILE(FILE) \
+ (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \
+ && (FILE) = *(FILE**)&((int*)fp)[1])
+#endif
+
+#ifdef EINVAL
+# define MAYBE_SET_EINVAL __set_errno (EINVAL)
+#else
+# define MAYBE_SET_EINVAL /* nothing */
+#endif
+
+#ifdef IO_DEBUG
+# define CHECK_FILE(FILE, RET) \
+ if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \
+ else { COERCE_FILE(FILE); \
+ if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \
+ { MAYBE_SET_EINVAL; return RET; }}
+#else
+# define CHECK_FILE(FILE, RET) COERCE_FILE (FILE)
+#endif
diff --git a/gnu/dist/libio/osform.cc b/gnu/dist/libio/osform.cc
new file mode 100644
index 00000000000..f08f2efaa39
--- /dev/null
+++ b/gnu/dist/libio/osform.cc
@@ -0,0 +1,66 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <iostream.h>
+#include <stdarg.h>
+
+ostream& ostream::form(const char *format ...)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ va_list ap;
+ va_start(ap, format);
+ _IO_vfprintf(rdbuf(), format, ap);
+ va_end(ap);
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+ostream& ostream::vform(const char *format, _IO_va_list args)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ _IO_vfprintf(rdbuf(), format, args);
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(const void *p)
+{
+ if (opfx()) {
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _strbuf);
+ form("%p", p);
+ osfx();
+ _IO_cleanup_region_end (0);
+ }
+ return *this;
+}
diff --git a/gnu/dist/libio/ostream.h b/gnu/dist/libio/ostream.h
new file mode 100644
index 00000000000..f54ec1de9a1
--- /dev/null
+++ b/gnu/dist/libio/ostream.h
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <stream.h>
diff --git a/gnu/dist/libio/outfloat.c b/gnu/dist/libio/outfloat.c
new file mode 100644
index 00000000000..5cbb6c92598
--- /dev/null
+++ b/gnu/dist/libio/outfloat.c
@@ -0,0 +1,211 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef _IO_USE_DTOA
+/* Format floating-point number and print them.
+ Return number of chars printed, or EOF on error.
+
+ sign_mode == '+' : print "-" or "+"
+ sign_mode == ' ' : print "-" or " "
+ sign_mode == '\0' : print "-' or ""
+*/
+
+int
+_IO_outfloat (value, sb, type, width, precision, flags, sign_mode, fill)
+ double value;
+ _IO_FILE *sb;
+ int type;
+ int width;
+ int precision;
+ int flags;
+ int sign_mode;
+ int fill;
+{
+ int count = 0;
+#define PUT(x) do {if (_IO_putc(x, sb) < 0) goto error; count++;} while (0)
+#define PUTN(p, n) \
+ do {int _n=n; count+=_n; if (_IO_sputn(sb, p,_n) != _n) goto error;} while(0)
+#define PADN(fill, n) \
+ do {int _n = n; count+=_n; if (_IO_padn(sb, fill, _n) != _n) goto error;} while (0)
+ int pad_kind = flags & (_IO_LEFT|_IO_RIGHT|_IO_INTERNAL);
+ int skip_zeroes = 0;
+ int show_dot = (flags & _IO_SHOWPOINT) != 0;
+ int decpt;
+ int sign;
+ int mode;
+ int exponent_size;
+ int print_sign;
+ int trailing_zeroes, useful_digits;
+ int padding, unpadded_width;
+ char *p;
+ char *exponent_start;
+ register int i;
+#define EBUF_SIZE 12
+#define EBUF_END &ebuf[EBUF_SIZE]
+ char ebuf[EBUF_SIZE];
+ char *end;
+ int exp = 0;
+ switch (type)
+ {
+ case 'f':
+ mode = 3;
+ break;
+ case 'e':
+ case 'E':
+ exp = type;
+ mode = 2;
+ if (precision != 999)
+ precision++; /* Add one to include digit before decimal point. */
+ break;
+ case 'g':
+ case 'G':
+ exp = type == 'g' ? 'e' : 'E';
+ if (precision == 0) precision = 1;
+ if (!(flags & _IO_SHOWPOINT))
+ skip_zeroes = 1;
+ type = 'g';
+ mode = 2;
+ break;
+ }
+ /* Do the actual convension */
+ if (precision == 999 && mode != 3)
+ mode = 0;
+ p = _IO_dtoa(value, mode, precision, &decpt, &sign, &end);
+ useful_digits = end-p;
+ exponent_start = EBUF_END;
+ if (mode == 0)
+ precision = useful_digits;
+ /* Check if we need to emit an exponent. */
+ if (mode != 3 && decpt != 9999)
+ {
+ i = decpt - 1;
+ if ((type != 'g' && type != 'F') || i < -4 || i >= precision)
+ {
+ /* Print the exponent into ebuf.
+ We write ebuf in reverse order (right-to-left). */
+ char sign;
+ if (i >= 0)
+ sign = '+';
+ else
+ sign = '-', i = -i;
+ /* Note: ANSI requires at least 2 exponent digits. */
+ do {
+ *--exponent_start = (i % 10) + '0';
+ i /= 10;
+ } while (i >= 10);
+ *--exponent_start = i + '0';
+ *--exponent_start = sign;
+ *--exponent_start = exp;
+ }
+ }
+ exponent_size = EBUF_END - exponent_start;
+ if (mode == 1)
+ precision = 1;
+ /* If we print an exponent, always show just one digit before point. */
+ if (exponent_size)
+ decpt = 1;
+ if (decpt == 9999)
+ { /* Infinity or NaN */
+ decpt = useful_digits;
+ precision = 0;
+ show_dot = 0;
+ }
+
+ /* dtoa truncates trailing zeroes. Set the variable trailing_zeroes to
+ the number of 0's we have to add (after the decimal point). */
+ if (skip_zeroes)
+ trailing_zeroes = 0;
+ else if (type == 'f')
+ trailing_zeroes = useful_digits <= decpt ? precision
+ : precision-(useful_digits-decpt);
+ else if (exponent_size) /* 'e' 'E' or 'g' format using exponential notation*/
+ trailing_zeroes = precision - useful_digits;
+ else /* 'g' format not using exponential notation. */
+ trailing_zeroes = useful_digits <= decpt ? precision - decpt
+ : precision-useful_digits;
+ if (trailing_zeroes < 0) trailing_zeroes = 0;
+
+ if (trailing_zeroes != 0 || useful_digits > decpt)
+ show_dot = 1;
+ if (sign_mode == 0)
+ print_sign = sign ? '-' : 0;
+ else if (sign_mode == '+')
+ print_sign = sign ? '-' : '+';
+ else /* if (sign_mode == ' ') */
+ print_sign = sign ? '-' : ' ';
+
+ /* Calculate the width (before padding). */
+ unpadded_width =
+ (print_sign != 0) + trailing_zeroes + exponent_size + show_dot
+ + useful_digits
+ + (decpt > useful_digits ? decpt - useful_digits
+ : decpt > 0 ? 0 : 1 - decpt);
+
+ padding = width > unpadded_width ? width - unpadded_width : 0;
+ if (padding > 0 && pad_kind != _IO_LEFT && pad_kind != _IO_INTERNAL)
+ PADN(fill, padding); /* Default (right) adjust */
+ if (print_sign)
+ PUT(print_sign);
+ if (pad_kind == _IO_INTERNAL && padding > 0)
+ PADN(fill, padding);
+ if (decpt > 0)
+ {
+ if (useful_digits >= decpt)
+ PUTN(p, decpt);
+ else
+ {
+ PUTN(p, useful_digits);
+ PADN('0', decpt-useful_digits);
+ }
+ if (show_dot)
+ {
+ PUT('.');
+ /* Print digits after the decimal point. */
+ if (useful_digits > decpt)
+ PUTN(p + decpt, useful_digits-decpt);
+ }
+ }
+ else
+ {
+ PUT('0');
+ if (show_dot)
+ {
+ PUT('.');
+ PADN('0', -decpt);
+ /* Print digits after the decimal point. */
+ PUTN(p, useful_digits);
+ }
+ }
+ PADN('0', trailing_zeroes);
+ if (exponent_size)
+ PUTN(exponent_start, exponent_size);
+ if (pad_kind == _IO_LEFT && padding > 0) /* Left adjustment*/
+ PADN(fill, padding);
+ return count;
+ error:
+ return EOF;
+}
+#endif
diff --git a/gnu/dist/libio/parsestream.cc b/gnu/dist/libio/parsestream.cc
new file mode 100644
index 00000000000..e430e602c8d
--- /dev/null
+++ b/gnu/dist/libio/parsestream.cc
@@ -0,0 +1,317 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "libioP.h"
+#include "parsestream.h"
+#include <stdlib.h>
+
+streambuf* parsebuf::setbuf(char*, int)
+{
+ return NULL;
+}
+
+int parsebuf::tell_in_line()
+{
+ return 0;
+}
+
+int parsebuf::pbackfail(int c)
+{
+ if (c == EOF)
+ return 0;
+ if (seekoff(-1, ios::cur) == EOF)
+ return EOF;
+ return (unsigned char)c;
+}
+
+char* parsebuf::current_line() { return NULL; }
+
+streampos parsebuf::seekoff(streamoff offset, _seek_dir dir, int)
+{
+ // Make offset relative to line start.
+ switch (dir) {
+ case ios::beg:
+ offset -= pos_at_line_start;
+ break;
+ case ios::cur:
+ offset += tell_in_line();
+ break;
+ default:
+ return EOF;
+ }
+ if (offset < -1)
+ return EOF;
+ if (offset > _line_length + 1)
+ return EOF;
+ return seek_in_line(offset) + pos_at_line_start;
+}
+
+// string_parsebuf invariants:
+// The reserve ares (base() .. ebuf()) is always the entire string.
+// The get area (eback() .. egptr()) is the extended current line
+// (i.e. with the '\n' at either end, if these exist).
+
+string_parsebuf::string_parsebuf(char *buf, int len,
+ int delete_at_close /* = 0*/)
+: parsebuf()
+{
+ setb(buf, buf+len, delete_at_close);
+ register char *ptr = buf;
+ while (ptr < ebuf() && *ptr != '\n') ptr++;
+ _line_length = ptr - buf;
+ setg(buf, buf, ptr);
+}
+
+int string_parsebuf::underflow()
+{
+ register char* ptr = egptr(); // Point to end of current_line
+ do {
+ int i = right() - ptr;
+ if (i <= 0)
+ return EOF;
+ ptr++; i--; // Skip '\n'.
+ char *line_start = ptr;
+ while (ptr < right() && *ptr == '\n') ptr++;
+ setg(line_start-1, line_start, ptr + (ptr < right()));
+ pos_at_line_start = line_start - left();
+ _line_length = ptr - line_start;
+ __line_number++;
+ } while (gptr() == ptr);
+ return *gptr();
+}
+
+char* string_parsebuf::current_line()
+{
+ char *ptr = eback();
+ if (__line_number > 0)
+ ptr++; // Skip '\n' at end of previous line.
+ return ptr;
+}
+
+int string_parsebuf::tell_in_line()
+{
+ int offset = gptr() - eback();
+ if (__line_number > 0)
+ offset--;
+ return offset;
+}
+
+int string_parsebuf::seek_in_line(int i)
+{
+ int delta = i - tell_in_line();
+ gbump(delta); // FIXME: Needs error (bounds) checking!
+ return i;
+}
+
+static const char NewLine[1] = { '\n' };
+
+general_parsebuf::general_parsebuf(streambuf *buf, int delete_arg_buf)
+ : parsebuf()
+{
+ delete_buf = delete_arg_buf;
+ sbuf = buf;
+ int buf_size = 128;
+ char* buffer = (char*)malloc(buf_size);
+ setb(buffer, buffer+buf_size, 1);
+// setg(buffer, buffer, buffer);
+}
+
+general_parsebuf::~general_parsebuf()
+{
+ if (delete_buf)
+ delete sbuf;
+}
+
+int general_parsebuf::underflow()
+{
+ register char *ptr = base();
+ int has_newline = eback() < gptr() && gptr()[-1] == '\n';
+ if (has_newline)
+ *ptr++ = '\n';
+ register streambuf *sb = sbuf;
+ register int ch;
+ for (;;) {
+ ch = sb->sbumpc();
+ if (ch == EOF)
+ break;
+ if (ptr == ebuf()) {
+ int old_size = ebuf() - base();
+ char *new_buffer = new char[old_size * 2];
+ memcpy(new_buffer, base(), old_size);
+ setb(new_buffer, new_buffer + 2 * old_size, 1);
+ ptr = new_buffer + old_size;
+ }
+ *ptr++ = ch;
+ if (ch == '\n')
+ break;
+ }
+ char *cur_pos = base() + has_newline;
+ pos_at_line_start += _line_length + 1;
+ _line_length = ptr - cur_pos;
+ if (ch != EOF || _line_length > 0)
+ __line_number++;
+ setg(base(), cur_pos, ptr);
+ return ptr == cur_pos ? EOF : cur_pos[0];
+}
+
+char* general_parsebuf::current_line()
+{
+ char* ret = base();
+ if (__line_number > 1)
+ ret++; // Move past '\n' from end of previous line.
+ return ret;
+}
+
+int general_parsebuf::tell_in_line()
+{
+ int off = gptr() - base();
+ if (__line_number > 1)
+ off--; // Subtract 1 for '\n' from end of previous line.
+ return off;
+}
+
+int general_parsebuf::seek_in_line(int i)
+{
+ if (__line_number == 0)
+ (void)general_parsebuf::underflow();
+ if (__line_number > 1)
+ i++; // Add 1 for '\n' from end of previous line.
+ if (i < 0) i = 0;
+ int len = egptr() - eback();
+ if (i > len) i = len;
+ setg(base(), base() + i, egptr());
+ return i;
+}
+
+func_parsebuf::func_parsebuf(CharReader func, void *argm) : parsebuf()
+{
+ read_func = func;
+ arg = argm;
+ buf_start = NULL;
+ buf_end = NULL;
+ setb((char*)NewLine, (char*)NewLine+1, 0);
+ setg((char*)NewLine, (char*)NewLine+1, (char*)NewLine+1);
+ backed_up_to_newline = 0;
+}
+
+int func_parsebuf::tell_in_line()
+{
+ if (buf_start == NULL)
+ return 0;
+ if (egptr() != (char*)NewLine+1)
+ // Get buffer was line buffer.
+ return gptr() - buf_start;
+ if (backed_up_to_newline)
+ return -1; // Get buffer is '\n' preceding current line.
+ // Get buffer is '\n' following current line.
+ return (buf_end - buf_start) + (gptr() - (char*)NewLine);
+}
+
+char* func_parsebuf::current_line()
+{
+ return buf_start;
+}
+
+int func_parsebuf::seek_in_line(int i)
+{
+ if (i < 0) {
+ // Back up to preceding '\n'.
+ if (i < -1) i = -1;
+ backed_up_to_newline = 1;
+ setg((char*)NewLine, (char*)NewLine+(i+1), (char*)NewLine+1);
+ return i;
+ }
+ backed_up_to_newline = 0;
+ int line_length = buf_end-buf_start;
+ if (i <= line_length) {
+ setg(buf_start, buf_start+i, buf_end);
+ return i;
+ }
+ i -= line_length;
+ if (i > 0) i = 1;
+ setg((char*)NewLine, (char*)NewLine+i, (char*)NewLine+1);
+ return line_length + i;
+}
+
+int func_parsebuf::underflow()
+{
+ retry:
+ if (gptr() < egptr())
+ return *gptr();
+ if (gptr() != (char*)NewLine+1) {
+ // Get buffer was line buffer. Move to following '\n'.
+ setg((char*)NewLine, (char*)NewLine, (char*)NewLine+1);
+ return *gptr();
+ }
+ if (backed_up_to_newline)
+ // Get buffer was '\n' preceding current line. Move to current line.
+ backed_up_to_newline = 0;
+ else {
+ // Get buffer was '\n' following current line. Read new line.
+ if (buf_start) free(buf_start);
+ char *str = (*read_func)(arg);
+ buf_start = str;
+ if (str == NULL)
+ return EOF;
+ // Initially, _line_length == -1, so pos_at_line_start becomes 0.
+ pos_at_line_start += _line_length + 1;
+ _line_length = strlen(str);
+ buf_end = str + _line_length;
+ __line_number++;
+ }
+ setg(buf_start, buf_start, buf_end);
+ goto retry;
+}
+
+#if 0
+size_t parsebuf::line_length()
+{
+ if (current_line_length == (size_t)(-1)) // Initial value;
+ (void)sgetc();
+ return current_line_length;
+}
+#endif
+
+int parsebuf::seek_in_line(int i)
+{
+#if 1
+ abort();
+ return i; // Suppress warnings.
+#else
+ if (i > 0) {
+ size_t len = line_length();
+ if ((unsigned)i > len) i = len;
+ }
+ else if (i < -1) i = -1;
+ int new_pos = seekoff(pos_at_line_start + i, ios::beg);
+ if (new_pos == EOF)
+ return tell_in_line();
+ else return new_pos - pos_at_line_start;
+#endif
+}
diff --git a/gnu/dist/libio/parsestream.h b/gnu/dist/libio/parsestream.h
new file mode 100644
index 00000000000..326ab87a809
--- /dev/null
+++ b/gnu/dist/libio/parsestream.h
@@ -0,0 +1,156 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef PARSESTREAM_H
+#define PARSESTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include "streambuf.h"
+
+extern "C++" {
+// A parsebuf is a streambuf optimized for scanning text files.
+// It keeps track of line and column numbers.
+// It is guaranteed to remember the entire current line,
+// as well the '\n'-s on either side of it (if they exist).
+// You can arbitrarily seek (or unget) within this extended line.
+// Other backward seeks are not supported.
+// Normal read semantics are supported (and hence istream operators like >>).
+
+class parsebuf : public streambuf {
+ protected:
+ _IO_fpos_t pos_at_line_start;
+ long _line_length;
+ unsigned long __line_number;
+ char *buf_start;
+ char *buf_end;
+
+ public:
+ parsebuf *chain;
+
+ // Return column number (raw - don't handle tabs etc).
+ // Retult can be -1, meaning: at '\n' before current line.
+ virtual int tell_in_line();
+
+ // seek to (raw) column I in current line.
+ // Result is new (raw) column position - differs from I if unable to seek.
+ // Seek to -1 tries to seek to before previous LF.
+ virtual int seek_in_line(int i);
+
+ // Note: there is no "current line" initially, until something is read.
+
+ // Current line number, starting with 0.
+ // If tell_in_line()==-1, then line number of next line.
+ int line_number() { return __line_number; }
+
+ // Length of current line, not counting either '\n'.
+ int line_length() { return _line_length; }
+ // Current line - not a copy, so file ops may trash it.
+ virtual char* current_line();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streambuf* setbuf(char* p, int len);
+ protected:
+ parsebuf() { chain= NULL;
+ __line_number = 0; pos_at_line_start = 0; _line_length = -1; }
+ virtual int pbackfail(int c);
+};
+
+// A string_parsebuf is a parsebuf whose source is a fixed string.
+
+class string_parsebuf : public parsebuf {
+ public:
+ int do_delete;
+ string_parsebuf(char *str, int len, int delete_at_close=0);
+ virtual int underflow();
+ virtual char* current_line();
+ virtual int seek_in_line(int i);
+ virtual int tell_in_line();
+ char *left() const { return base(); }
+ char *right() const { return ebuf(); }
+// streampos seekoff(streamoff, _seek_dir, int);
+};
+
+// A func_parsebuf calls a given function to get new input.
+// Each call returns an entire NUL-terminated line (without the '\n').
+// That line has been allocated with malloc(), not new.
+// The interface is tailored to the GNU readline library.
+// Example:
+// char* DoReadLine(void* arg)
+// {
+// char *line = readline((char*)arg); /* 'arg' is used as prompt. */
+// if line == NULL) { putc('\n', stderr); return NULL; }
+// if (line[0] != '\0') add_history(line);
+// return line;
+// }
+// char PromptBuffer[100] = "> ";
+// func_parsebuf my_stream(DoReadLine, PromptBuffer);
+
+typedef char *(*CharReader)(void *arg);
+class istream;
+
+class func_parsebuf : public parsebuf {
+ public:
+ void *arg;
+ CharReader read_func;
+ int backed_up_to_newline;
+ func_parsebuf(CharReader func, void *argm = NULL);
+ int underflow();
+ virtual int tell_in_line();
+ virtual int seek_in_line(int i);
+ virtual char* current_line();
+};
+
+// A general_parsebuf is a parsebuf which gets its input from some
+// other streambuf. It explicitly buffers up an entire line.
+
+class general_parsebuf : public parsebuf {
+ public:
+ streambuf *sbuf;
+ int delete_buf; // Delete sbuf when destroying this.
+ general_parsebuf(streambuf *buf, int delete_arg_buf = 0);
+ int underflow();
+ virtual int tell_in_line();
+ virtual int seek_in_line(int i);
+ ~general_parsebuf();
+ virtual char* current_line();
+};
+
+#if 0
+class parsestream : public istream {
+ streammarker marks[2];
+ short _first; // of the two marks; either 0 or 1
+ int _lineno;
+ int first() { return _first; }
+ int second() { return 1-_first; }
+ int line_length() { marks[second].delta(marks[first]); }
+ int line_length() { marks[second].delta(marks[first]); }
+ int seek_in_line(int i);
+ int tell_in_line();
+ int line_number();
+};
+#endif
+} // extern "C++"
+#endif /*!defined(PARSESTREAM_H)*/
diff --git a/gnu/dist/libio/peekc.c b/gnu/dist/libio/peekc.c
new file mode 100644
index 00000000000..0b3b5140c26
--- /dev/null
+++ b/gnu/dist/libio/peekc.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef _IO_peekc
+
+int
+_IO_peekc_locked (fp)
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_peekc_unlocked (fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/pfstream.cc b/gnu/dist/libio/pfstream.cc
new file mode 100644
index 00000000000..3fa93c958f8
--- /dev/null
+++ b/gnu/dist/libio/pfstream.cc
@@ -0,0 +1,92 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "libioP.h"
+#include <pfstream.h>
+#include <procbuf.h>
+
+ipfstream::ipfstream(const char *name, int mode, int prot)
+{
+ const char* p;
+
+ // Look for '| command' (as used by ftp).
+ for (p = name; *p == ' ' || *p == '\t'; p++) ;
+ if (*p == '|') {
+ procbuf *pbuf = new procbuf();
+ init(pbuf);
+ if (!pbuf->open(p+1, mode))
+ set(ios::badbit);
+ return;
+ }
+
+ // Look for 'command |'
+ while (*p) p++; // Point to last
+ while (p[-1] == ' ' || p[-1] == '\t' || p[-1] == '\n') p--;
+ if (p[-1] == '|') {
+ // Must remove the final '|'.
+ p--;
+#if !defined (__GNUC__) || defined (__STRICT_ANSI__)
+ char *command = new char[p-name+1];
+#else
+ char command[p-name+1];
+#endif
+ memcpy(command, name, p-name);
+ command[p-name] = '\0';
+
+ procbuf *pbuf = new procbuf();
+ if (pbuf->open(command, mode))
+ set(ios::badbit);
+#if !defined (__GNUC__) || defined (__STRICT_ANSI__)
+ delete command;
+#endif
+ return;
+ }
+
+ init(new filebuf());
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+opfstream::opfstream(const char *name, int mode, int prot)
+{
+ const char *p;
+ // Look for '| command'.
+ for (p = name; *p == ' ' || *p == '\t'; p++) ;
+ if (*p == '|') {
+ procbuf *pbuf = new procbuf();
+ init(pbuf);
+ if (!pbuf->open(p+1, mode))
+ set(ios::badbit);
+ }
+ else {
+ init(new filebuf());
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+ }
+}
diff --git a/gnu/dist/libio/pfstream.h b/gnu/dist/libio/pfstream.h
new file mode 100644
index 00000000000..3c5458baaa9
--- /dev/null
+++ b/gnu/dist/libio/pfstream.h
@@ -0,0 +1,59 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _PFSTREAM_H
+#define _PFSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <fstream.h>
+
+extern "C++" {
+// ipfstream foo("NAME") is like: ifstream foo("NAME"). However,
+// if NAME starts *or ends* with a '|', the remainder of NAME is
+// evaluated as a shell command (using a procbuf), and all input
+// read from foo is whatever that shell writes to its standard output.
+// E.g. ipfstream foo("|zcat foo.Z") or ipfstream foo("zcat foo.Z|")
+// (These two forms are equivalent.)
+
+class ipfstream : public ifstream {
+ public:
+ ipfstream(const char *name, int mode=ios::in, int prot=0664);
+};
+
+// opfstream foo("NAME") is like: ofstream foo("NAME").
+// However, if NAME starts with a '|', the remainder of NAME is
+// evaluated as a shell command (using a procbuf), and all output
+// written to foo is piped to the standard input of that shell.
+// E.g. opfstream foo("|more");
+
+class opfstream : public ofstream {
+ public:
+ opfstream(const char *name, int mode=ios::out, int prot=0664);
+};
+} // extern "C++"
+#endif /*!_PFSTREAM_H*/
+
diff --git a/gnu/dist/libio/procbuf.cc b/gnu/dist/libio/procbuf.cc
new file mode 100644
index 00000000000..1c79ce4ce0f
--- /dev/null
+++ b/gnu/dist/libio/procbuf.cc
@@ -0,0 +1,55 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#define _POSIX_SOURCE
+#include "libioP.h"
+#include "procbuf.h"
+
+procbuf::procbuf(const char *command, int mode) : filebuf()
+{
+ _IO_proc_open(this, command, (mode & ios::in) ? "r" : "w");
+}
+
+procbuf *procbuf::open(const char *command, int mode)
+{
+ return (procbuf*)_IO_proc_open(this, command, (mode & ios::in) ? "r" : "w");
+}
+
+/* #define USE_SIGMASK */
+
+int procbuf::sys_close()
+{
+ return _IO_proc_close(this);
+}
+
+procbuf::~procbuf()
+{
+ close();
+}
diff --git a/gnu/dist/libio/procbuf.h b/gnu/dist/libio/procbuf.h
new file mode 100644
index 00000000000..b361a6a7c84
--- /dev/null
+++ b/gnu/dist/libio/procbuf.h
@@ -0,0 +1,50 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _PROCBUF_H
+#define _PROCBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <streambuf.h>
+
+extern "C++" {
+class procbuf : public filebuf {
+ /* Following fields must match those in struct _IO_proc_file */
+ _IO_pid_t _pid;
+ procbuf *_next;
+ public:
+ procbuf() : filebuf() { }
+ procbuf(const char *command, int mode);
+ procbuf* open(const char *command, int mode);
+ procbuf *close() { return (procbuf*)filebuf::close(); }
+ virtual int sys_close();
+ ~procbuf();
+};
+} // extern "C++"
+
+#endif /* !_PROCBUF_H */
diff --git a/gnu/dist/libio/sbform.cc b/gnu/dist/libio/sbform.cc
new file mode 100644
index 00000000000..c17bd08db15
--- /dev/null
+++ b/gnu/dist/libio/sbform.cc
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "streambuf.h"
+#include <stdarg.h>
+
+int streambuf::vform(char const *fmt0, _IO_va_list ap)
+{
+ return _IO_vfprintf(this, fmt0, ap);
+}
+int streambuf::form(char const *format ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int count = _IO_vfprintf(this, format, ap);
+ va_end(ap);
+ return count;
+}
diff --git a/gnu/dist/libio/sbgetline.cc b/gnu/dist/libio/sbgetline.cc
new file mode 100644
index 00000000000..0475114c629
--- /dev/null
+++ b/gnu/dist/libio/sbgetline.cc
@@ -0,0 +1,31 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "streambuf.h"
+
+long streambuf::sgetline(char* buf, _IO_size_t n, char delim, int extract_delim)
+{
+ return _IO_getline_info(this, buf, n, delim, extract_delim, (int *) 0);
+}
diff --git a/gnu/dist/libio/sbscan.cc b/gnu/dist/libio/sbscan.cc
new file mode 100644
index 00000000000..c0ec35c53db
--- /dev/null
+++ b/gnu/dist/libio/sbscan.cc
@@ -0,0 +1,45 @@
+
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "streambuf.h"
+#include <stdarg.h>
+
+int streambuf::vscan(char const *fmt0, _IO_va_list ap, ios* stream /* = NULL*/)
+{
+ int errcode = 0;
+ int count = _IO_vfscanf(this, fmt0, ap, &errcode);
+ if (stream)
+ stream->setstate((ios::iostate)errcode);
+ return count;
+}
+int streambuf::scan(char const *format ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int count = _IO_vfscanf(this, format, ap, NULL);
+ va_end(ap);
+ return count;
+}
diff --git a/gnu/dist/libio/stdfiles.c b/gnu/dist/libio/stdfiles.c
new file mode 100644
index 00000000000..8453e33c34c
--- /dev/null
+++ b/gnu/dist/libio/stdfiles.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+
+/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
+ for C code. Compare stdstreams.cc.
+ (The difference is that here the vtable field is set to 0,
+ so the objects defined are not valid C++ objects. On the other
+ hand, we don't need a C++ compiler to build this file.) */
+
+#include "libioP.h"
+
+#ifdef _IO_MTSAFE_IO
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
+ struct _IO_FILE_plus NAME \
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}
+#else
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ struct _IO_FILE_plus NAME \
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}
+#endif
+
+DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
+DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS);
+DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_.file,
+ _IO_NO_READS+_IO_UNBUFFERED);
+
+_IO_FILE *_IO_list_all = &_IO_stderr_.file;
diff --git a/gnu/dist/libio/stdio/ChangeLog b/gnu/dist/libio/stdio/ChangeLog
new file mode 100644
index 00000000000..f98baec0955
--- /dev/null
+++ b/gnu/dist/libio/stdio/ChangeLog
@@ -0,0 +1,133 @@
+1997-09-04 16:11 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (STDIO_OBJECTS): Lose feof.o and ferror.o. Add getc.o
+ and putc.o.
+ (stmp-libio, stmp-libiostream, stmp-io, stmp-streamlib): New rules.
+
+ (iostream.list): Depend upon stmp-stdio. Add the entries
+ from stdio.list to iostream.list.
+ (stmp-stdio): New name for what was the stdio/stdio.list rule.
+ All it now does is cd down into stdio and build stdio.list.
+
+ * clearerr.c: Add copyright and lock stream before use.
+ * feof.c: Likewise.
+ * ferror.c: Likewise.
+ * fgetc.c: Likewise.
+ * fputc.c: Likewise.
+ * freopen.c: Likewise.
+ * fseek.c: Likewise.
+ * getc.c: Likewise.
+ * getchar.c: Likewise.
+ * putc.c: Likewise.
+ * putchar.c: Likewise.
+ * rewind.c: Likewise.
+
+ * setbuf.c: Update copyright.
+ * setlinebuf.c: Likewise.
+ * vscanf.c: Likewise.
+
+ * fileno.c: Define alias fileno_unlocked. Update copyright.
+
+ * clearerr_u.c: New file. Implement clearerr_unlocked function.
+ * feof_u.c: New file. Implement feof_unlocked function.
+ * ferror_u.c: New file. Implement ferror_unlocked function.
+ * fputc_u.c: New file. Implement fputc_unlocked function.
+ * getc_u.c: New file. Implement getc_unclocked function.
+ * getchar_u.c: New file. Implement getchar_unclocked function.
+ * putc_u.c: New file. Implement putc_unclocked function.
+ * putchar_u.c: New file. Implement putchar_unclocked function.
+
+ * vsnprintf.c: Rewrite according to ISO C 9X draft.
+
+Thu May 1 11:03:45 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * stdio.h (TMP_MAX): Wrap it with #ifndef for now, since it can
+ get defined by <limits.h> (e.g., HP/UX and AIX).
+
+Wed Mar 12 08:51:37 1997 Gavin Koch <gavin@cygnus.com>
+
+ * stdio.h: Use _IO_va_list rather than _G_va_list.
+
+Wed Jun 14 21:41:50 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * configure.in (LIBDIR): Set.
+ (MOSTLYCLEAN): Remove pic and stamp-picdir.
+ (stdio_objects): Also compile pic version.
+
+ * Makefile.in (STDIO_OBJECTS): Remove getdelim.o.
+
+Wed May 10 03:05:53 1995 Jason Merrill <jason@python.cygnus.com>
+
+ * vsnprintf.c (vsnprintf): Update to use _IO_JUMPS.
+
+ * Makefile.in (STDIO_OBJECTS): Fix typo.
+
+Tue Oct 18 17:15:09 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * getline.c, snprintf.c, vsnprintf.c: New files, providing
+ functionality of the GNU C library.
+ * Makefile.in (STDIO_OBJECTS), configure.in: Add new files.
+ * stdio.h: Add new functions.
+
+Fri Oct 14 15:56:27 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdio.h: Added vfscanf, vscanf, vsscanf, #ifndef __STRICT_ANSI__.
+
+Tue Aug 23 16:17:25 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdio.h: Added comment, at hjl's request.
+
+Sun Aug 7 13:28:12 1994 H.J. Lu (hjl@nynexst.com)
+
+ * stdio.h (getc, getchar, putc, putchar): New declarations.
+ Move macros after the declarations.
+
+Fri Aug 5 18:27:21 1994 H.J. Lu (hjl@nynexst.com)
+
+ * clearerr.c, rewind.c, setfileno.c:
+ Add CHECK_FILE(fp, ) and remove COERCE_FILE(fp).
+ * feof.c, ferror.c, fgetc.c, fileno.c, fputc.c, getw.c, putw.c,
+ vfscanf.c: Add CHECK_FILE(fp, EOF) and remove COERCE_FILE(fp).
+ * freopen.c: Add CHECK_FILE(fp, NULL) and remove COERCE_FILE(fp).
+ * fseek.c, vfprintf.c:
+ Add CHECK_FILE(fp, -1) and remove COERCE_FILE(fp).
+
+Fri May 20 13:11:58 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * stdio.h: Rename _ARGS macro to __P for better gnlibc and
+ BSD compatibility.
+
+Fri Nov 26 13:26:35 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ Bunch of little changes, many from H.J. Lu <hjl@nynexst.com>.
+ * feof.c, setbuf.c, vprintf.c, vcanf.c: #include <stdio.h>,
+ for error checking.
+ * fileno.c: #include libioP.h, not just libio.h.
+ * fputc.c: Fix typo.
+ * fseek.c, rewind.c: Use #include "...", not <...> ,for local files.
+ * getc.c, getchar.c, putc.c, putchar.c: New files, providing
+ non-macro versions of the standard macros.
+ * getw.c, putw.c, setfileno.c, setlinebuf.c: New files.
+ * Makefile.in (STDIO_OBJECTS): Add new files.
+ * vfscanf.c: Add missing new 4th arg to _IO_vfscanf call.
+
+Thu Oct 14 16:12:07 1993 Karen Christiansen (karen@deneb.cygnus.com)
+
+ * configure.in: changed mv to mv -f
+
+Mon Oct 4 17:29:23 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * configure.in (stdio_renames): Add fgetpos, fsetpos, gets,
+ perror, setbuffer, ungetc.
+ * clearerr.c, ferror.c, fgetc.c, fileno.c, fputc.c, freopen.c,
+ fseek.c, popen.c, rewind.c, setbuf.c: New files.
+ * Makefile.in (STDIO_OBJECTS): Add new files.
+ * stdio.h: Use _IO_XXX instead of _G_XXX many places.
+ #include <libio.h> instead of <_stdio.h>, to get useful defs.
+
+Fri Aug 20 00:28:28 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * feof.c, vprintf.c, vscanf.c: Converted stub functions.
+ * configure.in (stdio_renamed): Removed feof.
+ Added sprintf sscanf vsscanf.
+ * ChangeLog.old: Copy of old libg++/iostream/stdio/ChangeLog.
diff --git a/gnu/dist/libio/stdio/Makefile.in b/gnu/dist/libio/stdio/Makefile.in
new file mode 100644
index 00000000000..680c8a497a4
--- /dev/null
+++ b/gnu/dist/libio/stdio/Makefile.in
@@ -0,0 +1,35 @@
+srcdir = .
+
+#### package, host, target, and site dependent Makefile fragments come in here.
+##
+
+# These are compiled from the corresponding ../ioFOO.c files.
+STDIO_RENAMED_OBJECTS = ... filled in by configure ...
+# These are the files that a libc would want.
+STDIO_OBJECTS = $(STDIO_RENAMED_OBJECTS) \
+ clearerr.o fdopen.o fgetc.o fileno.o \
+ fputc.o freopen.o fseek.o getchar.o getline.o getw.o \
+ popen.o putchar.o putw.o rewind.o \
+ setbuf.o setfileno.o setlinebuf.o snprintf.o \
+ vfprintf.o vfscanf.o vprintf.o vscanf.o vsnprintf.o
+
+CC_FOR_STDIO=$(CC)
+CINCLUDES = -I. -I$(srcdir) -I.. -I$(srcdir)/.. -D__USE_GNU
+
+nothing:
+
+stmp-libio: stdio.list stamp-io
+
+stamp-io:
+ $(AR) $(AR_FLAGS) ../libio.a $(STDIO_OBJECTS)
+ touch stmp-io
+
+stmp-libiostream: stdio.list stamp-streamlib
+
+stamp-streamlib:
+ $(AR) $(AR_FLAGS) ../libiostream.a $(STDIO_OBJECTS)
+ touch stmp-streamlib
+
+stdio.list: stamp-picdir $(STDIO_OBJECTS)
+ @echo "$(STDIO_OBJECTS)" >stdio.list
+
diff --git a/gnu/dist/libio/stdio/clearerr.c b/gnu/dist/libio/stdio/clearerr.c
new file mode 100644
index 00000000000..4776250ff8d
--- /dev/null
+++ b/gnu/dist/libio/stdio/clearerr.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+void
+clearerr (fp)
+ FILE *fp;
+{
+ CHECK_FILE (fp, /*nothing*/);
+ _IO_flockfile (fp);
+ _IO_clearerr (fp);
+ _IO_funlockfile (fp);
+}
diff --git a/gnu/dist/libio/stdio/clearerr_u.c b/gnu/dist/libio/stdio/clearerr_u.c
new file mode 100644
index 00000000000..2a1ba7070bb
--- /dev/null
+++ b/gnu/dist/libio/stdio/clearerr_u.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+void
+clearerr_unlocked (fp)
+ FILE *fp;
+{
+ CHECK_FILE (fp, /*nothing*/);
+ _IO_clearerr (fp);
+}
diff --git a/gnu/dist/libio/stdio/configure.in b/gnu/dist/libio/stdio/configure.in
new file mode 100644
index 00000000000..21e920acf47
--- /dev/null
+++ b/gnu/dist/libio/stdio/configure.in
@@ -0,0 +1,48 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=
+srctrigger=stdio.h
+srcname="libio/stdio"
+package_makefile_frag=../Make.pack
+
+# per-host:
+
+# per-target:
+
+LIBDIR=yes
+TO_TOPDIR=../../
+ALL=nothing
+MOSTLYCLEAN='*.o pic stamp-picdir core stdio.list'
+(. ${srcdir}/../config.shared) >${package_makefile_frag}
+
+# post-target:
+
+# Certain files that are used to build a C library (such as fprintf.o)
+# are compled from the same sources as the ioXXX versions (such as ioprintf.c).
+# These lines add the appropriate rules.
+# NOTE: We assume a C compiler that where -o with -c works.
+# But these files are not built by default anyway ...
+
+# TODO: remove rename tmpfile tmpnam
+
+stdio_renames="fclose fflush fgetpos fgets fopen fprintf fputs fread \
+ fscanf fsetpos ftell fwrite getdelim gets perror printf puts \
+ scanf setbuffer setvbuf sprintf sscanf ungetc vsprintf vsscanf"
+stdio_objects=""
+
+for file in $stdio_renames ; do
+ cat >>Makefile <<EOF
+$file.o: \$(srcdir)/../io$file.c
+ if [ -n "\$(PICFLAG)" ]; then \\
+ \$(CC_FOR_STDIO) \$(CFLAGS) \$(CINCLUDES) \$(PICFLAG) -c \\
+ \$(srcdir)/../io$file.c -D_IO_$file=$file -o pic/$file.o; \\
+ fi
+ \$(CC_FOR_STDIO) \$(CFLAGS) \$(CINCLUDES) -c \\
+ \$(srcdir)/../io$file.c -D_IO_$file=$file -o $file.o
+EOF
+ stdio_objects="$stdio_objects $file.o"
+done
+sed -e "/STDIO_RENAMED_OBJECTS =/s/=.*/=${stdio_objects}/" <Makefile >tmp
+mv -f tmp Makefile
diff --git a/gnu/dist/libio/stdio/fdopen.c b/gnu/dist/libio/stdio/fdopen.c
new file mode 100644
index 00000000000..83e026ec7f7
--- /dev/null
+++ b/gnu/dist/libio/stdio/fdopen.c
@@ -0,0 +1,9 @@
+#include "libioP.h"
+
+_IO_FILE *
+fdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ return _IO_fdopen (fd, mode);
+}
diff --git a/gnu/dist/libio/stdio/feof.c b/gnu/dist/libio/stdio/feof.c
new file mode 100644
index 00000000000..d06de044fba
--- /dev/null
+++ b/gnu/dist/libio/stdio/feof.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+_IO_feof (fp)
+ _IO_FILE* fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_flockfile (fp);
+ result = _IO_feof_unlocked (fp);
+ _IO_funlockfile (fp);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_feof, feof)
+#endif
diff --git a/gnu/dist/libio/stdio/feof_u.c b/gnu/dist/libio/stdio/feof_u.c
new file mode 100644
index 00000000000..4773599012d
--- /dev/null
+++ b/gnu/dist/libio/stdio/feof_u.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef feof_unlocked
+
+int
+feof_unlocked (fp)
+ _IO_FILE* fp;
+{
+ CHECK_FILE (fp, EOF);
+ return _IO_feof_unlocked (fp);
+}
diff --git a/gnu/dist/libio/stdio/ferror.c b/gnu/dist/libio/stdio/ferror.c
new file mode 100644
index 00000000000..855627ade66
--- /dev/null
+++ b/gnu/dist/libio/stdio/ferror.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+_IO_ferror (fp)
+ _IO_FILE* fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_flockfile (fp);
+ result = _IO_ferror_unlocked (fp);
+ _IO_funlockfile (fp);
+ return result;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_ferror, ferror)
+#endif
diff --git a/gnu/dist/libio/stdio/ferror_u.c b/gnu/dist/libio/stdio/ferror_u.c
new file mode 100644
index 00000000000..6e13e53ddc0
--- /dev/null
+++ b/gnu/dist/libio/stdio/ferror_u.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef ferror_unlocked
+
+int
+ferror_unlocked (fp)
+ _IO_FILE* fp;
+{
+ CHECK_FILE (fp, EOF);
+ return _IO_ferror_unlocked (fp);
+}
diff --git a/gnu/dist/libio/stdio/fgetc.c b/gnu/dist/libio/stdio/fgetc.c
new file mode 100644
index 00000000000..174e60fa3fd
--- /dev/null
+++ b/gnu/dist/libio/stdio/fgetc.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fgetc (fp)
+ FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_getc_unlocked (fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/stdio/fileno.c b/gnu/dist/libio/stdio/fileno.c
new file mode 100644
index 00000000000..7ff93e6a813
--- /dev/null
+++ b/gnu/dist/libio/stdio/fileno.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fileno (fp)
+ _IO_FILE* fp;
+{
+ CHECK_FILE (fp, EOF);
+
+ if (!(fp->_flags & _IO_IS_FILEBUF))
+ return EOF;
+
+ return _IO_fileno (fp);
+}
+
+#ifdef _IO_MTSAFE_IO
+#ifdef weak_alias
+/* The fileno implementation for libio does not require locking because
+ it only accesses once a single variable and this is already atomic
+ (at least at thread level). */
+
+weak_alias (fileno, fileno_unlocked)
+#endif
+#endif
diff --git a/gnu/dist/libio/stdio/fputc.c b/gnu/dist/libio/stdio/fputc.c
new file mode 100644
index 00000000000..22cdfab9a84
--- /dev/null
+++ b/gnu/dist/libio/stdio/fputc.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fputc (c, fp)
+ int c;
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_putc_unlocked (c, fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/stdio/fputc_u.c b/gnu/dist/libio/stdio/fputc_u.c
new file mode 100644
index 00000000000..48701e1d6cb
--- /dev/null
+++ b/gnu/dist/libio/stdio/fputc_u.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef fputc_unlocked
+
+int
+fputc_unlocked (c, fp)
+ int c;
+ _IO_FILE *fp;
+{
+ CHECK_FILE (fp, EOF);
+ return _IO_putc_unlocked (c, fp);
+}
diff --git a/gnu/dist/libio/stdio/freopen.c b/gnu/dist/libio/stdio/freopen.c
new file mode 100644
index 00000000000..ff57d6033dc
--- /dev/null
+++ b/gnu/dist/libio/stdio/freopen.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+FILE*
+freopen (filename, mode, fp)
+ const char* filename;
+ const char* mode;
+ FILE* fp;
+{
+ FILE *result;
+ CHECK_FILE (fp, NULL);
+ if (!(fp->_flags & _IO_IS_FILEBUF))
+ return NULL;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_freopen (filename, mode, fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/stdio/fseek.c b/gnu/dist/libio/stdio/fseek.c
new file mode 100644
index 00000000000..f2563d33f28
--- /dev/null
+++ b/gnu/dist/libio/stdio/fseek.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fseek (fp, offset, whence)
+ _IO_FILE* fp;
+ long int offset;
+ int whence;
+{
+ int result;
+ CHECK_FILE (fp, -1);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_fseek (fp, offset, whence);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/stdio/getc.c b/gnu/dist/libio/stdio/getc.c
new file mode 100644
index 00000000000..1dc53b5ed65
--- /dev/null
+++ b/gnu/dist/libio/stdio/getc.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef _IO_getc
+
+int
+_IO_getc (fp)
+ FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_getc_unlocked (fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#undef getc
+
+#ifdef weak_alias
+weak_alias (_IO_getc, getc)
+#endif
diff --git a/gnu/dist/libio/stdio/getc_u.c b/gnu/dist/libio/stdio/getc_u.c
new file mode 100644
index 00000000000..f0744274466
--- /dev/null
+++ b/gnu/dist/libio/stdio/getc_u.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef getc_unlocked
+
+int
+getc_unlocked (fp)
+ FILE *fp;
+{
+ CHECK_FILE (fp, EOF);
+ return _IO_getc_unlocked (fp);
+}
diff --git a/gnu/dist/libio/stdio/getchar.c b/gnu/dist/libio/stdio/getchar.c
new file mode 100644
index 00000000000..93194b3912d
--- /dev/null
+++ b/gnu/dist/libio/stdio/getchar.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef getchar
+
+int
+getchar ()
+{
+ int result;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, stdin);
+ _IO_flockfile (stdin);
+ result = _IO_getc_unlocked (stdin);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/stdio/getchar_u.c b/gnu/dist/libio/stdio/getchar_u.c
new file mode 100644
index 00000000000..bfbe56b30c0
--- /dev/null
+++ b/gnu/dist/libio/stdio/getchar_u.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef getchar_unlocked
+
+int
+getchar_unlocked ()
+{
+ return _IO_getc_unlocked (stdin);
+}
diff --git a/gnu/dist/libio/stdio/getline.c b/gnu/dist/libio/stdio/getline.c
new file mode 100644
index 00000000000..6f4b677086e
--- /dev/null
+++ b/gnu/dist/libio/stdio/getline.c
@@ -0,0 +1,13 @@
+#include "libioP.h"
+#include "stdio.h"
+
+/* NOTE: This geline function is different from _IO_getline. */
+
+_IO_ssize_t
+getline (lineptr, linelen, fp)
+ char** lineptr;
+ size_t* linelen;
+ FILE* fp;
+{
+ return _IO_getdelim (lineptr, linelen, '\n', fp);
+}
diff --git a/gnu/dist/libio/stdio/getw.c b/gnu/dist/libio/stdio/getw.c
new file mode 100644
index 00000000000..1dfafbc1d4f
--- /dev/null
+++ b/gnu/dist/libio/stdio/getw.c
@@ -0,0 +1,13 @@
+#include "libioP.h"
+#include "stdio.h"
+
+int
+getw(fp)
+ FILE *fp;
+{
+ int w;
+ _IO_size_t bytes_read;
+ CHECK_FILE(fp, EOF);
+ bytes_read = _IO_sgetn (fp, (char*)&w, sizeof(w));
+ return sizeof(w) == bytes_read ? w : EOF;
+}
diff --git a/gnu/dist/libio/stdio/obprintf.c b/gnu/dist/libio/stdio/obprintf.c
new file mode 100644
index 00000000000..6b959e455a8
--- /dev/null
+++ b/gnu/dist/libio/stdio/obprintf.c
@@ -0,0 +1,168 @@
+/* Print output of stream to given obstack.
+ Copyright (C) 1996, 1997 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;
+}
+#ifdef weak_alias
+weak_alias (_IO_obstack_vprintf, obstack_vprintf)
+#endif
+
+
+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;
+}
+#ifdef weak_alias
+weak_alias (_IO_obstack_printf, obstack_printf)
+#endif
diff --git a/gnu/dist/libio/stdio/popen.c b/gnu/dist/libio/stdio/popen.c
new file mode 100644
index 00000000000..9f9f3f72f58
--- /dev/null
+++ b/gnu/dist/libio/stdio/popen.c
@@ -0,0 +1,23 @@
+#include "libioP.h"
+#include "stdio.h"
+#include <errno.h>
+
+FILE *
+popen(command, mode)
+ const char *command; const char *mode;
+{
+ return _IO_popen(command, mode);
+}
+
+int
+pclose(fp)
+ FILE *fp;
+{
+#if 0
+ /* Does not actually test that stream was created by popen(). Instead,
+ it depends on the filebuf::sys_close() virtual to Do The Right Thing. */
+ if (fp is not a proc_file)
+ return -1;
+#endif
+ return _IO_fclose(fp);
+}
diff --git a/gnu/dist/libio/stdio/putc.c b/gnu/dist/libio/stdio/putc.c
new file mode 100644
index 00000000000..3c35c365f07
--- /dev/null
+++ b/gnu/dist/libio/stdio/putc.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef _IO_putc
+
+int
+_IO_putc (c, fp)
+ int c;
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_putc_unlocked (c, fp);
+ _IO_cleanup_region_end (1);
+ return result;
+}
+
+#undef putc
+
+#ifdef weak_alias
+weak_alias (_IO_putc, putc)
+#endif
diff --git a/gnu/dist/libio/stdio/putc_u.c b/gnu/dist/libio/stdio/putc_u.c
new file mode 100644
index 00000000000..b4d94e8912b
--- /dev/null
+++ b/gnu/dist/libio/stdio/putc_u.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef putc_unlocked
+
+int
+putc_unlocked (c, fp)
+ int c;
+ _IO_FILE *fp;
+{
+ CHECK_FILE (fp, EOF);
+ return _IO_putc_unlocked (c, fp);
+}
diff --git a/gnu/dist/libio/stdio/putchar.c b/gnu/dist/libio/stdio/putchar.c
new file mode 100644
index 00000000000..1e1dd137626
--- /dev/null
+++ b/gnu/dist/libio/stdio/putchar.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef putchar
+
+int
+putchar (c)
+ int c;
+{
+ int result;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _IO_stdout);
+ _IO_flockfile (_IO_stdout);
+ result = _IO_putc_unlocked (c, _IO_stdout);
+ _IO_cleanup_region_end (1);
+ return result;
+}
diff --git a/gnu/dist/libio/stdio/putchar_u.c b/gnu/dist/libio/stdio/putchar_u.c
new file mode 100644
index 00000000000..f8f387ac4ed
--- /dev/null
+++ b/gnu/dist/libio/stdio/putchar_u.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef putchar_unlocked
+
+int
+putchar_unlocked (c)
+ int c;
+{
+ CHECK_FILE (stdout, EOF);
+ return _IO_putc_unlocked (c, stdout);
+}
diff --git a/gnu/dist/libio/stdio/putw.c b/gnu/dist/libio/stdio/putw.c
new file mode 100644
index 00000000000..fd73261359c
--- /dev/null
+++ b/gnu/dist/libio/stdio/putw.c
@@ -0,0 +1,15 @@
+#include "libioP.h"
+#include "stdio.h"
+
+#undef putw
+
+int
+putw(w, fp)
+ int w;
+ FILE *fp;
+{
+ _IO_size_t written;
+ CHECK_FILE(fp, EOF);
+ written = _IO_sputn(fp, (const char *)&w, sizeof(w));
+ return written == sizeof(w) ? 0 : EOF;
+}
diff --git a/gnu/dist/libio/stdio/rewind.c b/gnu/dist/libio/stdio/rewind.c
new file mode 100644
index 00000000000..bce27575fd8
--- /dev/null
+++ b/gnu/dist/libio/stdio/rewind.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+void
+rewind (fp)
+ _IO_FILE *fp;
+{
+ CHECK_FILE (fp, );
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ _IO_rewind (fp);
+ _IO_cleanup_region_end (1);
+}
diff --git a/gnu/dist/libio/stdio/setbuf.c b/gnu/dist/libio/stdio/setbuf.c
new file mode 100644
index 00000000000..ac323a31b5b
--- /dev/null
+++ b/gnu/dist/libio/stdio/setbuf.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+void
+setbuf (fp, buf)
+ _IO_FILE *fp;
+ char *buf;
+{
+ _IO_setbuffer (fp, buf, _IO_BUFSIZ);
+}
diff --git a/gnu/dist/libio/stdio/setfileno.c b/gnu/dist/libio/stdio/setfileno.c
new file mode 100644
index 00000000000..f7ccc6fdd66
--- /dev/null
+++ b/gnu/dist/libio/stdio/setfileno.c
@@ -0,0 +1,17 @@
+/* Some known programs (xterm, pdksh?) non-portably change the _file
+ field of s struct _iobuf. This kludge allows the same "functionality".
+ This code is an undocumented feature for iostream/stdio. Use it at
+ your own risk. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+void
+setfileno(fp, fd)
+ _IO_FILE* fp;
+ int fd;
+{
+ CHECK_FILE(fp, );
+ if ((fp->_flags & _IO_IS_FILEBUF) != 0)
+ fp->_fileno = fd;
+}
diff --git a/gnu/dist/libio/stdio/setlinebuf.c b/gnu/dist/libio/stdio/setlinebuf.c
new file mode 100644
index 00000000000..e4e029faeac
--- /dev/null
+++ b/gnu/dist/libio/stdio/setlinebuf.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef setlinebuf
+
+void
+setlinebuf (stream)
+ _IO_FILE *stream;
+{
+ _IO_setvbuf (stream, NULL, 1, 0);
+}
diff --git a/gnu/dist/libio/stdio/snprintf.c b/gnu/dist/libio/stdio/snprintf.c
new file mode 100644
index 00000000000..5c70a444112
--- /dev/null
+++ b/gnu/dist/libio/stdio/snprintf.c
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+snprintf
+#ifdef __STDC__
+ (char *string, _IO_size_t maxlen, const char *format, ...)
+#else
+(string, maxlen, format, va_alist)
+ char *string;
+ _IO_size_t maxlen;
+ char *format;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = vsnprintf(string, maxlen, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/dist/libio/stdio/stdio.h b/gnu/dist/libio/stdio/stdio.h
new file mode 100644
index 00000000000..30065ac8714
--- /dev/null
+++ b/gnu/dist/libio/stdio/stdio.h
@@ -0,0 +1,219 @@
+/* This is part of the iostream/stdio library, providing -*- C -*- I/O.
+ Define ANSI C stdio on top of C++ iostreams.
+ Copyright (C) 1991, 1994 Free Software Foundation
+
+This 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.
+
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * ANSI Standard: 4.9 INPUT/OUTPUT <stdio.h>
+ */
+
+#ifndef _STDIO_H
+#define _STDIO_H
+#define _STDIO_USES_IOSTREAM
+
+#include <libio.h>
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL (void*)0
+#endif
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+ /* define size_t. Crud in case <sys/types.h> has defined it. */
+#if !defined(_SIZE_T) && !defined(_T_SIZE_) && !defined(_T_SIZE)
+#if !defined(__SIZE_T) && !defined(_SIZE_T_) && !defined(___int_size_t_h)
+#if !defined(_GCC_SIZE_T) && !defined(_SIZET_)
+#define _SIZE_T
+#define _T_SIZE_
+#define _T_SIZE
+#define __SIZE_T
+#define _SIZE_T_
+#define ___int_size_t_h
+#define _GCC_SIZE_T
+#define _SIZET_
+typedef _IO_size_t size_t;
+#endif
+#endif
+#endif
+
+typedef struct _IO_FILE FILE;
+typedef _IO_fpos_t fpos_t;
+
+#define FOPEN_MAX _G_FOPEN_MAX
+#define FILENAME_MAX _G_FILENAME_MAX
+#ifndef TMP_MAX
+#define TMP_MAX 999 /* Only limited by filename length */
+#endif
+
+#define L_ctermid 9
+#define L_cuserid 9
+#define P_tmpdir "/tmp"
+#define L_tmpnam 20
+
+/* For use by debuggers. These are linked in if printf or fprintf are used. */
+extern FILE *stdin, *stdout, *stderr; /* TODO */
+
+#define stdin _IO_stdin
+#define stdout _IO_stdout
+#define stderr _IO_stderr
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __P
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif /*!__P*/
+
+extern void clearerr __P((FILE*));
+extern int fclose __P((FILE*));
+extern int feof __P((FILE*));
+extern int ferror __P((FILE*));
+extern int fflush __P((FILE*));
+extern int fgetc __P((FILE *));
+extern int fgetpos __P((FILE* fp, fpos_t *pos));
+extern char* fgets __P((char*, int, FILE*));
+extern FILE* fopen __P((const char*, const char*));
+extern int fprintf __P((FILE*, const char* format, ...));
+extern int fputc __P((int, FILE*));
+extern int fputs __P((const char *str, FILE *fp));
+extern size_t fread __P((void*, size_t, size_t, FILE*));
+extern FILE* freopen __P((const char*, const char*, FILE*));
+extern int fscanf __P((FILE *fp, const char* format, ...));
+extern int fseek __P((FILE* fp, long int offset, int whence));
+extern int fsetpos __P((FILE* fp, const fpos_t *pos));
+extern long int ftell __P((FILE* fp));
+extern size_t fwrite __P((const void*, size_t, size_t, FILE*));
+extern int getc __P((FILE *));
+extern int getchar __P((void));
+extern char* gets __P((char*));
+extern void perror __P((const char *));
+extern int printf __P((const char* format, ...));
+extern int putc __P((int, FILE *));
+extern int putchar __P((int));
+extern int puts __P((const char *str));
+extern int remove __P((const char*));
+extern int rename __P((const char* _old, const char* _new));
+extern void rewind __P((FILE*));
+extern int scanf __P((const char* format, ...));
+extern void setbuf __P((FILE*, char*));
+extern void setlinebuf __P((FILE*));
+extern void setbuffer __P((FILE*, char*, int));
+extern int setvbuf __P((FILE*, char*, int mode, size_t size));
+extern int sprintf __P((char*, const char* format, ...));
+extern int sscanf __P((const char* string, const char* format, ...));
+extern FILE* tmpfile __P((void));
+extern char* tmpnam __P((char*));
+extern int ungetc __P((int c, FILE* fp));
+extern int vfprintf __P((FILE *fp, char const *fmt0, _IO_va_list));
+extern int vprintf __P((char const *fmt, _IO_va_list));
+extern int vsprintf __P((char* string, const char* format, _IO_va_list));
+
+#ifndef __STRICT_ANSI__
+extern int vfscanf __P((FILE*, const char *, _IO_va_list));
+extern int vscanf __P((const char *, _IO_va_list));
+extern int vsscanf __P((const char *, const char *, _IO_va_list));
+#endif
+
+#if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)
+extern FILE *fdopen __P((int, const char *));
+extern int fileno __P((FILE*));
+extern FILE* popen __P((const char*, const char*));
+extern int pclose __P((FILE*));
+#endif
+
+#ifdef __USE_GNU
+extern _IO_ssize_t getdelim __P ((char **, size_t *, int, FILE*));
+extern _IO_ssize_t getline __P ((char **, size_t *, FILE *));
+
+extern int snprintf __P ((char *, size_t, const char *, ...));
+extern int vsnprintf __P ((char *, size_t, const char *, _IO_va_list));
+#endif
+
+extern int __underflow __P((struct _IO_FILE*));
+extern int __overflow __P((struct _IO_FILE*, int));
+
+/* Handle locking of streams. */
+#if defined _REENTRANT || defined _THREAD_SAFE
+extern void clearerr_locked __P ((FILE *));
+extern void clearerr_unlocked __P ((FILE *));
+extern int feof_locked __P ((FILE *));
+extern int feof_unlocked __P ((FILE *));
+extern int ferror_locked __P ((FILE*));
+extern int ferror_unlocked __P ((FILE*));
+extern int fileno_locked __P ((FILE *));
+extern int fileno_unlocked __P ((FILE *));
+extern void flockfile __P ((FILE *));
+extern void funlockfile __P ((FILE *));
+extern int ftrylockfile __P ((FILE *));
+extern int fclose_unlocked __P ((FILE *));
+extern int fflush_locked __P ((FILE *));
+extern int fflush_unlocked __P ((FILE *));
+extern size_t fread_unlocked __P ((void *, size_t, size_t, FILE *));
+extern size_t fwrite_unlocked __P ((const void *, size_t, size_t, FILE *));
+
+extern int fputc_locked __P ((int, FILE*));
+extern int fputc_unlocked __P ((int, FILE*));
+extern int getc_locked __P ((FILE *));
+extern int getc_unlocked __P ((FILE *));
+extern int getchar_locked __P ((void));
+extern int getchar_unlocked __P ((void));
+extern int putc_locked __P ((int, FILE *));
+extern int putc_unlocked __P ((int, FILE *));
+extern int putchar_locked __P ((int));
+extern int putchar_unlocked __P ((int));
+
+# define getc_unlocked(fp) _IO_getc_unlocked (fp)
+# define getc_locked(fp) _IO_getc (fp)
+# define getchar_unlocked() _IO_getc_unlocked (stdin)
+# define getchar_locked() _IO_getc (stdin)
+# define putchar_unlocked(c) _IO_putc_unlocked (c, stdout)
+# define putchar_locked(c) _IO_putc (c, stdout)
+#endif /* __USE_REENTRANT */
+
+#define getc(fp) _IO_getc(fp)
+#define putc(c, fp) _IO_putc(c, fp)
+#define putchar(c) _IO_putc(c, stdout)
+#define getchar() _IO_getc(stdin)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*!_STDIO_H*/
diff --git a/gnu/dist/libio/stdio/vasprintf.c b/gnu/dist/libio/stdio/vasprintf.c
new file mode 100644
index 00000000000..15513d0fca7
--- /dev/null
+++ b/gnu/dist/libio/stdio/vasprintf.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <malloc.h>
+#include "libioP.h"
+#include "stdio.h"
+#include "strfile.h"
+
+int
+_IO_vasprintf (result_ptr, format, args)
+ char **result_ptr;
+ const char *format;
+ _IO_va_list args;
+{
+ /* Initial size of the buffer to be used. Will be doubled each time an
+ overflow occurs. */
+ const _IO_size_t init_string_size = 100;
+ char *string;
+ _IO_strfile sf;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ int ret;
+ string = (char *) malloc (init_string_size);
+ if (string == NULL)
+ return -1;
+#ifdef _IO_MTSAFE_IO
+ sf._sbf._f._lock = &lock;
+#endif
+ _IO_init ((_IO_FILE *) &sf, 0);
+ _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps;
+ _IO_str_init_static ((_IO_FILE *) &sf, string, init_string_size, string);
+ sf._sbf._f._flags &= ~_IO_USER_BUF;
+ sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+ sf._s._free_buffer = (_IO_free_type) free;
+ ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args);
+ if (ret < 0)
+ return ret;
+ *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base,
+ (sf._sbf._f._IO_write_ptr
+ - sf._sbf._f._IO_write_base) +1);
+ if (*result_ptr == NULL)
+ *result_ptr = sf._sbf._f._IO_buf_base;
+ (*result_ptr)[sf._sbf._f._IO_write_ptr-sf._sbf._f._IO_write_base] = '\0';
+ return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vasprintf, vasprintf)
+#endif
diff --git a/gnu/dist/libio/stdio/vfprintf.c b/gnu/dist/libio/stdio/vfprintf.c
new file mode 100644
index 00000000000..fca62094452
--- /dev/null
+++ b/gnu/dist/libio/stdio/vfprintf.c
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+int
+vfprintf(fp, format, args)
+ register _IO_FILE* fp;
+ char const *format;
+ _IO_va_list args;
+{
+ CHECK_FILE(fp, -1);
+ return _IO_vfprintf(fp, format, args);
+}
diff --git a/gnu/dist/libio/stdio/vfscanf.c b/gnu/dist/libio/stdio/vfscanf.c
new file mode 100644
index 00000000000..1759ee5ee01
--- /dev/null
+++ b/gnu/dist/libio/stdio/vfscanf.c
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+vfscanf(fp, format, args)
+ register _IO_FILE* fp;
+ const char *format;
+ _IO_va_list args;
+{
+ CHECK_FILE(fp, EOF);
+ return _IO_vfscanf(fp, format, args, NULL);
+}
diff --git a/gnu/dist/libio/stdio/vprintf.c b/gnu/dist/libio/stdio/vprintf.c
new file mode 100644
index 00000000000..784f0d9b8df
--- /dev/null
+++ b/gnu/dist/libio/stdio/vprintf.c
@@ -0,0 +1,33 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int vprintf(format, args)
+ const char* format;
+ _IO_va_list args;
+{
+ return _IO_vfprintf(_IO_stdout, format, args);
+}
diff --git a/gnu/dist/libio/stdio/vscanf.c b/gnu/dist/libio/stdio/vscanf.c
new file mode 100644
index 00000000000..8b92ae270e6
--- /dev/null
+++ b/gnu/dist/libio/stdio/vscanf.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef vscanf
+
+int
+_IO_vscanf (format, args)
+ const char *format;
+ _IO_va_list args;
+{
+ return _IO_vfscanf (_IO_stdin, format, args, NULL);
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vscanf, vscanf)
+#endif
diff --git a/gnu/dist/libio/stdio/vsnprintf.c b/gnu/dist/libio/stdio/vsnprintf.c
new file mode 100644
index 00000000000..3f35af299ab
--- /dev/null
+++ b/gnu/dist/libio/stdio/vsnprintf.c
@@ -0,0 +1,136 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+
+typedef struct
+{
+ _IO_strfile f;
+ /* This is used for the characters which do not fit in the buffer
+ provided by the user. */
+ char overflow_buf[64];
+} _IO_strnfile;
+
+
+static int _IO_strn_overflow __P ((_IO_FILE *fp, int c));
+
+static int
+_IO_strn_overflow (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ /* When we come to here this means the user supplied buffer is
+ filled. But since we must return the number of characters which
+ would have been written in total we must provide a buffer for
+ further use. We can do this by writing on and on in the overflow
+ buffer in the _IO_strnfile structure. */
+ _IO_strnfile *snf = (_IO_strnfile *) fp;
+
+ if (fp->_IO_buf_base != snf->overflow_buf)
+ {
+ /* Terminate the string. We know that there is room for at
+ least one more character since we initialized the stream with
+ a size to make this possible. */
+ *fp->_IO_write_ptr = '\0';
+
+ _IO_setb (fp, snf->overflow_buf,
+ snf->overflow_buf + sizeof (snf->overflow_buf), 0);
+
+ fp->_IO_write_base = snf->overflow_buf;
+ fp->_IO_read_base = snf->overflow_buf;
+ fp->_IO_read_ptr = snf->overflow_buf;
+ fp->_IO_read_end = snf->overflow_buf + sizeof (snf->overflow_buf);
+ }
+
+ fp->_IO_write_ptr = snf->overflow_buf;
+ fp->_IO_write_end = snf->overflow_buf;
+
+ /* Since we are not really interested in storing the characters
+ which do not fit in the buffer we simply ignore it. */
+ return c;
+}
+
+
+static struct _IO_jump_t _IO_strn_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_str_finish),
+ JUMP_INIT(overflow, _IO_strn_overflow),
+ JUMP_INIT(underflow, _IO_str_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_str_pbackfail),
+ JUMP_INIT(xsputn, _IO_default_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_str_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_default_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_default_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat)
+};
+
+
+int
+_IO_vsnprintf (string, maxlen, format, args)
+ char *string;
+ _IO_size_t maxlen;
+ const char *format;
+ _IO_va_list args;
+{
+ _IO_strnfile sf;
+ int ret;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+ sf.f._sbf._f._lock = &lock;
+#endif
+
+ /* We need to handle the special case where MAXLEN is 0. Use the
+ overflow buffer right from the start. */
+ if (maxlen == 0)
+ {
+ string = sf.overflow_buf;
+ maxlen = sizeof (sf.overflow_buf);
+ }
+
+ _IO_init ((_IO_FILE *) &sf, 0);
+ _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_strn_jumps;
+ _IO_str_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string);
+ ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args);
+
+ if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
+ *sf.f._sbf._f._IO_write_ptr = '\0';
+ return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vsnprintf, __vsnprintf)
+weak_alias (_IO_vsnprintf, vsnprintf)
+#endif
diff --git a/gnu/dist/libio/stdiostream.cc b/gnu/dist/libio/stdiostream.cc
new file mode 100644
index 00000000000..80db5e59bfd
--- /dev/null
+++ b/gnu/dist/libio/stdiostream.cc
@@ -0,0 +1,159 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <stdiostream.h>
+#include "libioP.h"
+
+// A stdiobuf is "tied" to a FILE object (as used by the stdio package).
+// Thus a stdiobuf is always synchronized with the corresponding FILE,
+// though at the cost of some overhead. (If you use the implementation
+// of stdio supplied with this library, you don't need stdiobufs.)
+// This implementation inherits from filebuf, but implement the virtual
+// functions sys_read/..., using the stdio functions fread/... instead
+// of the low-level read/... system calls. This has the advantage that
+// we get all of the nice filebuf semantics automatically, though
+// with some overhead.
+
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+stdiobuf::stdiobuf(FILE *f) : filebuf(fileno(f))
+{
+ _file = f;
+ // Turn off buffer in stdiobuf. Instead, rely on buffering in (FILE).
+ // Thus the stdiobuf will be synchronized with the FILE.
+ setbuf(NULL, 0);
+}
+
+stdiobuf::~stdiobuf()
+{
+ /* Only needed if we're buffered. Not buffered is the default. */
+ _IO_do_flush((_IO_FILE*)this);
+}
+
+streamsize stdiobuf::sys_read(char* buf, streamsize size)
+{
+ // A minor optimization, but it makes a noticable difference.
+ // A bigger optimization would be to write stdiobuf::underflow,
+ // but that has some modularity disadvantages. Re-evaluate that
+ // after we have gotten rid of the double indirection. FIXME
+ if (size == 1)
+ {
+ register ch = getc(_file);
+ if (ch == EOF)
+ return 0;
+ *buf = (char)ch;
+ return 1;
+ }
+ else
+ return fread(buf, 1, size, _file);
+}
+
+streamsize stdiobuf::sys_write(const char *buf, streamsize n)
+{
+ _IO_ssize_t count = fwrite(buf, 1, n, _file);
+ if (_offset >= 0)
+ _offset += n;
+ return count;
+}
+
+streampos stdiobuf::sys_seek(streamoff offset, _seek_dir dir)
+{
+ // Normally, equivalent to: fdir=dir
+ int fdir =
+ (dir == ios::beg) ? SEEK_SET :
+ (dir == ios::cur) ? SEEK_CUR :
+ (dir == ios::end) ? SEEK_END :
+ dir;
+ return fseek(_file, offset, fdir);
+}
+
+int stdiobuf::sys_close()
+{
+ int status = fclose(_file);
+ _file = NULL;
+ return status;
+}
+
+int stdiobuf::sync()
+{
+ if (_IO_do_flush((_IO_FILE*)this))
+ return EOF;
+ if (!(xflags() & _IO_NO_WRITES))
+ if (fflush(_file))
+ return EOF;
+ return 0;
+}
+
+int stdiobuf::overflow(int c /* = EOF*/)
+{
+ if (filebuf::overflow(c) == EOF)
+ return EOF;
+ if (c != EOF)
+ return c;
+ return fflush(_file);
+}
+
+streamsize stdiobuf::xsputn(const char* s, streamsize n)
+{
+ if (buffered ())
+ {
+ // The filebuf implementation of sputn loses.
+ return streambuf::xsputn(s, n);
+ }
+ else
+ return fwrite (s, 1, n, _file);
+}
+
+void stdiobuf::buffered (int b)
+{
+ if (b)
+ {
+ if (_flags & _IO_UNBUFFERED)
+ { /* Was unbuffered, make it buffered. */
+ _flags &= ~_IO_UNBUFFERED;
+ }
+ }
+ else
+ {
+ if (!(_flags & _IO_UNBUFFERED))
+ { /* Was buffered, make it unbuffered. */
+ setbuf(NULL, 0);
+ }
+ }
+}
diff --git a/gnu/dist/libio/stdiostream.h b/gnu/dist/libio/stdiostream.h
new file mode 100644
index 00000000000..b973d7a39b6
--- /dev/null
+++ b/gnu/dist/libio/stdiostream.h
@@ -0,0 +1,79 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _STDIOSTREAM_H
+#define _STDIOSTREAM_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <iostream.h>
+#include <stdio.h>
+
+extern "C++" {
+class stdiobuf : public filebuf {
+ protected:
+ FILE *_file;
+ public:
+ FILE* stdiofile() const { return _file; }
+ stdiobuf(FILE *);
+ ~stdiobuf();
+ int buffered () const { return _flags & _IO_UNBUFFERED ? 0 : 1; }
+ void buffered (int);
+ virtual streamsize sys_read(char*, streamsize);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual int sys_close();
+ virtual int sync();
+ virtual int overflow(int c = EOF);
+ streamsize xsputn(const char* s, streamsize n);
+};
+
+class istdiostream : public istream
+{
+private:
+ stdiobuf _file;
+public:
+ istdiostream (FILE* __f) : istream(), _file(__f) { init(&_file); }
+ stdiobuf* rdbuf()/* const */ { return &_file; }
+ int buffered () const { return _file.buffered (); }
+ void buffered (int _i) { _file.buffered (_i); }
+};
+
+class ostdiostream : public ostream
+{
+private:
+ stdiobuf _file;
+public:
+ ostdiostream (FILE* __f) : ostream(), _file(__f) { init(&_file); }
+ stdiobuf* rdbuf() /* const */ { return &_file; }
+ int buffered () const { return _file.buffered (); }
+ void buffered (int _i) { _file.buffered (_i); }
+};
+} // extern "C++"
+
+#endif /* !_STDIOSTREAM_H */
diff --git a/gnu/dist/libio/stdstrbufs.cc b/gnu/dist/libio/stdstrbufs.cc
new file mode 100644
index 00000000000..48aa719df86
--- /dev/null
+++ b/gnu/dist/libio/stdstrbufs.cc
@@ -0,0 +1,126 @@
+/*
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+
+/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
+ for C++ code. Compare stdfiles.c.
+ (The difference is that here the vtable field is set to
+ point to builtinbuf's vtable, so the objects are effectively
+ of class builtinbuf.) */
+
+#include "libioP.h"
+#include <stdio.h>
+
+#if !defined(filebuf_vtable) && defined(__cplusplus)
+#ifdef __GNUC__
+extern char filebuf_vtable[]
+ asm (_G_VTABLE_LABEL_PREFIX
+#if _G_VTABLE_LABEL_HAS_LENGTH
+ "7"
+#endif
+ "filebuf");
+#else /* !__GNUC__ */
+#if _G_VTABLE_LABEL_HAS_LENGTH
+#define filebuf_vtable _G_VTABLE_LABEL_PREFIX_ID##7filebuf
+#else
+#define filebuf_vtable _G_VTABLE_LABEL_PREFIX_ID##filebuf
+#endif
+extern char filebuf_vtable[];
+#endif /* !__GNUC__ */
+#endif /* !defined(filebuf_vtable) && defined(__cplusplus) */
+
+#ifndef STD_VTABLE
+#define STD_VTABLE (const struct _IO_jump_t *)filebuf_vtable
+#endif
+
+#ifdef _IO_MTSAFE_IO
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
+ struct _IO_FILE_plus NAME \
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), STD_VTABLE}
+#else
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ struct _IO_FILE_plus NAME = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), STD_VTABLE}
+#endif
+
+DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
+DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS);
+DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_.file,
+ _IO_NO_READS+_IO_UNBUFFERED);
+
+#ifdef _STDIO_USES_IOSTREAM
+_IO_FILE *_IO_list_all = &_IO_stderr_.file;
+#else /* !_STDIO_USES_IOSTREAM */
+#include "stdiostream.h"
+
+struct _IO_fake_stdiobuf {
+ struct {
+ _IO_FILE file;
+ const void *vtable;
+ } s;
+ FILE *stdio_file;
+};
+
+/* Define stdiobuf_vtable as a name for the virtual function table
+ of the stdiobuf class. */
+#ifndef stdiobuf_vtable
+#ifdef __GNUC__
+extern struct _IO_jump_t stdiobuf_vtable
+ asm (_G_VTABLE_LABEL_PREFIX
+#if _G_VTABLE_LABEL_HAS_LENGTH
+ "8"
+#endif
+ "stdiobuf");
+#else /* !__GNUC__ */
+#if _G_VTABLE_LABEL_HAS_LENGTH
+#define stdiobuf_vtable _G_VTABLE_LABEL_PREFIX_ID##8stdiobuf
+#else
+#define stdiobuf_vtable _G_VTABLE_LABEL_PREFIX_ID##stdiobuf
+#endif
+extern struct _IO_jump_t stdiobuf_vtable;
+#endif /* !__GNUC__ */
+#endif /* !stdiobuf_vtable */
+
+#ifdef _IO_MTSAFE_IO
+#define DEF_STDIOFILE(NAME, FD, FILE, FLAGS, CHAIN) \
+ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
+ struct _IO_fake_stdiobuf NAME = \
+ {{{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+_IO_UNBUFFERED+FLAGS, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
+ 0, 0, 0, 0, { 0 }, _IO_stdfile_##FD##_lock},\
+ &stdiobuf_vtable}, FILE}
+#else
+#define DEF_STDIOFILE(NAME, FD, FILE, FLAGS, CHAIN) \
+ struct _IO_fake_stdiobuf NAME = \
+ {{{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+_IO_UNBUFFERED+FLAGS, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD}, \
+ &stdiobuf_vtable}, FILE}
+#endif
+
+DEF_STDIOFILE(_IO_stdin_buf, 0, stdin, _IO_NO_WRITES, &_IO_stderr_.file);
+DEF_STDIOFILE(_IO_stdout_buf, 1, stdout, _IO_NO_READS, &_IO_stdin_buf.s.file);
+DEF_STDIOFILE(_IO_stderr_buf, 2, stderr, _IO_NO_READS, &_IO_stdout_buf.s.file);
+
+_IO_FILE *_IO_list_all = &_IO_stderr_buf.s.file;
+#endif /* !_STDIO_USES_IOSTREAM */
diff --git a/gnu/dist/libio/stdstreams.cc b/gnu/dist/libio/stdstreams.cc
new file mode 100644
index 00000000000..a5889d738e2
--- /dev/null
+++ b/gnu/dist/libio/stdstreams.cc
@@ -0,0 +1,153 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include "libioP.h"
+#include "streambuf.h"
+#include <stdio.h>
+
+// The ANSI draft requires that operations on cin/cout/cerr can be
+// mixed with operations on stdin/stdout/stderr on a character by
+// character basis. This normally requires that the streambuf's
+// used by cin/cout/cerr be stdiostreams. However, if the stdio
+// implementation is the one that is built using this library,
+// then we don't need to, since in that case stdin/stdout/stderr
+// are identical to _IO_stdin/_IO_stdout/_IO_stderr.
+
+#include "libio.h"
+
+#ifdef _STDIO_USES_IOSTREAM
+#define CIN_SBUF _IO_stdin_
+#define COUT_SBUF _IO_stdout_
+#define CERR_SBUF _IO_stderr_
+static int use_stdiobuf = 0;
+#else
+#define CIN_SBUF _IO_stdin_buf
+#define COUT_SBUF _IO_stdout_buf
+#define CERR_SBUF _IO_stderr_buf
+static int use_stdiobuf = 1;
+#endif
+
+#define cin CIN
+#define cout COUT
+#define cerr CERR
+#define clog CLOG
+#include "iostream.h"
+#undef cin
+#undef cout
+#undef cerr
+#undef clog
+
+#ifdef __GNUG__
+#define PAD 0 /* g++ allows 0-length arrays. */
+#else
+#define PAD 1
+#endif
+struct _fake_istream {
+ struct myfields {
+#ifdef __GNUC__
+ _ios_fields *vb; /* pointer to virtual base class ios */
+ _IO_ssize_t _gcount;
+#else
+ /* This is supposedly correct for cfront. */
+ _IO_ssize_t _gcount;
+ void *vptr;
+ _ios_fields *vb; /* pointer to virtual base class ios */
+#endif
+ } mine;
+ _ios_fields base;
+ char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD];
+};
+struct _fake_ostream {
+ struct myfields {
+#ifndef __GNUC__
+ void *vptr;
+#endif
+ _ios_fields *vb; /* pointer to virtual base class ios */
+ } mine;
+ _ios_fields base;
+ char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD];
+};
+
+
+#ifdef _IO_NEW_STREAMS
+#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
+ (streambuf*)&SBUF, TIE, 0, ios::skipws|ios::dec|EXTRA_FLAGS, ' ',0,0,6
+#else
+#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
+ (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::dec|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
+#endif
+
+#ifdef __GNUC__
+#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS, ASM) \
+ _fake_ostream NAME ASM = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
+ _fake_istream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#else
+#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
+ _fake_ostream NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
+ _fake_istream NAME = {{0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS)}};
+#endif
+
+OSTREAM_DEF(cout, COUT_SBUF, NULL, 0, )
+OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf, )
+ISTREAM_DEF(cin, CIN_SBUF, (ostream*)&cout, 0)
+
+/* Only for (partial) compatibility with AT&T's library. */
+#if _G_CLOG_CONFLICT
+OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, __asm__ ("__IO_clog"))
+#else
+OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, )
+#endif
+
+// Switches between using _IO_std{in,out,err} and __std{in,out,err}_buf
+// for standard streams. This does not normally need to be called
+// explicitly, but is provided for AT&T compatibility.
+
+int ios::sync_with_stdio(int new_state)
+{
+#ifdef _STDIO_USES_IOSTREAM
+ // It is always synced.
+ return 0;
+#else
+ if (new_state == use_stdiobuf) // The usual case now.
+ return use_stdiobuf;
+ if (new_state) {
+ cin.base._strbuf = (streambuf*)&_IO_stdin_buf;
+ cout.base._strbuf = (streambuf*)&_IO_stdout_buf;
+ cerr.base._strbuf = (streambuf*)&_IO_stderr_buf;
+ clog.base._strbuf = (streambuf*)&_IO_stderr_buf;
+ } else {
+ cin.base._strbuf = (streambuf*)_IO_stdin;
+ cout.base._strbuf = (streambuf*)_IO_stdout;
+ cerr.base._strbuf = (streambuf*)_IO_stderr;
+ clog.base._strbuf = (streambuf*)_IO_stderr;
+ }
+ int old_state = use_stdiobuf;
+ use_stdiobuf = new_state;
+ return old_state;
+#endif
+}
diff --git a/gnu/dist/libio/stream.cc b/gnu/dist/libio/stream.cc
new file mode 100644
index 00000000000..3440a0c9bdb
--- /dev/null
+++ b/gnu/dist/libio/stream.cc
@@ -0,0 +1,170 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <stdarg.h>
+#include <string.h>
+#include "libioP.h"
+#include "stream.h"
+#include "strstream.h"
+
+static char Buffer[_IO_BUFSIZ];
+#define EndBuffer (Buffer+_IO_BUFSIZ)
+static char* next_chunk = Buffer; // Start of available part of Buffer.
+
+char* form(const char* format, ...)
+{
+ int space_left = EndBuffer - next_chunk;
+ // If less that 25% of the space is available start over.
+ if (space_left < (_IO_BUFSIZ>>2))
+ next_chunk = Buffer;
+ char* buf = next_chunk;
+
+ strstreambuf stream(buf, EndBuffer-buf-1, buf);
+ va_list ap;
+ va_start(ap, format);
+ int count = stream.vform(format, ap);
+ va_end(ap);
+ stream.sputc(0);
+ next_chunk = buf + stream.pcount();
+ return buf;
+}
+
+#define u_long unsigned long
+
+static char* itoa(unsigned long i, int size, int neg, int base)
+{
+ // Conservative estimate: If base==2, might need 8 characters
+ // for each input byte, but normally 3 is plenty.
+ int needed = size ? size
+ : (base >= 8 ? 3 : 8) * sizeof(unsigned long) + 2;
+ int space_left = EndBuffer - next_chunk;
+ if (space_left <= needed)
+ next_chunk = Buffer; // start over.
+
+ char* buf = next_chunk;
+
+ register char* ptr = buf+needed+1;
+ next_chunk = ptr;
+
+ if (needed < (2+neg) || ptr > EndBuffer)
+ return NULL;
+ *--ptr = 0;
+
+ if (i == 0)
+ *--ptr = '0';
+ while (i != 0 && ptr > buf) {
+ int ch = i % base;
+ i = i / base;
+ if (ch >= 10)
+ ch += 'a' - 10;
+ else
+ ch += '0';
+ *--ptr = ch;
+ }
+ if (neg)
+ *--ptr = '-';
+ if (size == 0)
+ return ptr;
+ while (ptr > buf)
+ *--ptr = ' ';
+ return buf;
+}
+
+char* dec(long i, int len /* = 0 */)
+{
+ if (i >= 0) return itoa((unsigned long)i, len, 0, 10);
+ else return itoa((unsigned long)(-i), len, 1, 10);
+}
+char* dec(int i, int len /* = 0 */)
+{
+ if (i >= 0) return itoa((unsigned long)i, len, 0, 10);
+ else return itoa((unsigned long)(-i), len, 1, 10);
+}
+char* dec(unsigned long i, int len /* = 0 */)
+{
+ return itoa(i, len, 0, 10);
+}
+char* dec(unsigned int i, int len /* = 0 */)
+{
+ return itoa(i, len, 0, 10);
+}
+
+char* hex(long i, int len /* = 0 */)
+{
+ return itoa((unsigned long)i, len, 0, 16);
+}
+char* hex(int i, int len /* = 0 */)
+{
+ return itoa((unsigned long)i, len, 0, 16);
+}
+char* hex(unsigned long i, int len /* = 0 */)
+{
+ return itoa(i, len, 0, 16);
+}
+char* hex(unsigned int i, int len /* = 0 */)
+{
+ return itoa(i, len, 0, 16);
+}
+
+char* oct(long i, int len /* = 0 */)
+{
+ return itoa((unsigned long)i, len, 0, 8);
+}
+char* oct(int i, int len /* = 0 */)
+{
+ return itoa((unsigned long)i, len, 0, 8);
+}
+char* oct(unsigned long i, int len /* = 0 */)
+{
+ return itoa(i, len, 0, 8);
+}
+char* oct(unsigned int i, int len /* = 0 */)
+{
+ return itoa(i, len, 0, 8);
+}
+
+static char *str(const char* s, int len, int width)
+{
+ if (width < len)
+ width = len;
+ int space_left = EndBuffer - next_chunk;
+ if (space_left <= width + 1)
+ next_chunk = Buffer; // start over.
+ char* buf = next_chunk;
+ memset (buf, ' ', width - len);
+ memcpy (buf + width - len, s, len);
+ buf[width] = 0;
+ return buf;
+}
+
+char* str(const char* s, int width)
+{
+ return str (s, strlen (s), width);
+}
+
+char* chr(char ch, int width)
+{
+ char c = ch;
+ return str (&c, 1, width);
+}
diff --git a/gnu/dist/libio/stream.h b/gnu/dist/libio/stream.h
new file mode 100644
index 00000000000..0859802ade6
--- /dev/null
+++ b/gnu/dist/libio/stream.h
@@ -0,0 +1,59 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _COMPAT_STREAM_H
+#define _COMPAT_STREAM_H
+
+// Compatibility with old library.
+// DO NOT USE THESE FUNCTIONS IN NEW CODE!
+// They are obsolete, non-standard, and non-reentrant.
+
+#define _STREAM_COMPAT
+#include <iostream.h>
+
+extern "C++" {
+extern char* form(const char*, ...);
+
+extern char* dec(long, int=0);
+extern char* dec(int, int=0);
+extern char* dec(unsigned long, int=0);
+extern char* dec(unsigned int, int=0);
+
+extern char* hex(long, int=0);
+extern char* hex(int, int=0);
+extern char* hex(unsigned long, int=0);
+extern char* hex(unsigned int, int=0);
+
+extern char* oct(long, int=0);
+extern char* oct(int, int=0);
+extern char* oct(unsigned long, int=0);
+extern char* oct(unsigned int, int=0);
+
+char* chr(char ch, int width = 0);
+char* str(const char* s, int width = 0);
+
+inline istream& WS(istream& str) { return ws(str); }
+} // extern "C++"
+
+#endif /* !_COMPAT_STREAM_H */
diff --git a/gnu/dist/libio/streambuf.cc b/gnu/dist/libio/streambuf.cc
new file mode 100644
index 00000000000..6be926b2372
--- /dev/null
+++ b/gnu/dist/libio/streambuf.cc
@@ -0,0 +1,364 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#define _STREAM_COMPAT
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "iostreamP.h"
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+void streambuf::_un_link() { _IO_un_link(this); }
+
+void streambuf::_link_in() { _IO_link_in(this); }
+
+int streambuf::switch_to_get_mode()
+{ return _IO_switch_to_get_mode(this); }
+
+void streambuf::free_backup_area()
+{ _IO_free_backup_area(this); }
+
+#if 0
+int streambuf::switch_to_put_mode()
+{ return _IO_:switch_to_put_mode(this); }
+#endif
+
+int __overflow(streambuf* sb, int c)
+{
+ return sb->overflow(c);
+}
+
+int streambuf::underflow()
+{ return EOF; }
+
+int streambuf::uflow()
+{ return _IO_default_uflow (this); }
+
+int streambuf::overflow(int /* = EOF */)
+{ return EOF; }
+
+streamsize streambuf::xsputn(register const char* s, streamsize n)
+{ return _IO_default_xsputn(this, s, n); }
+
+streamsize streambuf::xsgetn(char* s, streamsize n)
+{ return _IO_default_xsgetn(this, s, n); }
+
+int streambuf::ignore(int n)
+{
+ register int more = n;
+ for (;;) {
+ int count = _IO_read_end - _IO_read_ptr; // Data available.
+ if (count > 0) {
+ if (count > more)
+ count = more;
+ _IO_read_ptr += count;
+ more -= count;
+ }
+ if (more == 0 || __underflow(this) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+int streambuf::sync()
+{
+ return 0;
+}
+
+int streambuf::pbackfail(int c)
+{
+ return _IO_default_pbackfail(this, c);
+}
+
+streambuf* streambuf::setbuf(char* p, int len)
+{
+ if (sync() == EOF)
+ return NULL;
+ if (p == NULL || len == 0) {
+ unbuffered(1);
+ setb(_shortbuf, _shortbuf+1, 0);
+ }
+ else {
+ unbuffered(0);
+ setb(p, p+len, 0);
+ }
+ setp(0, 0);
+ setg(0, 0, 0);
+ return this;
+}
+
+streampos streambuf::seekpos(streampos pos, int mode)
+{
+ return seekoff(pos, ios::beg, mode);
+}
+
+streampos streambuf::sseekpos(streampos pos, int mode)
+{
+ return _IO_seekpos (this, pos, mode);
+}
+
+void streambuf::setb(char* b, char* eb, int a)
+{ _IO_setb(this, b, eb, a); }
+
+int streambuf::doallocate() { return _IO_default_doallocate(this); }
+
+void streambuf::doallocbuf() { _IO_doallocbuf(this); }
+
+#if !_IO_UNIFIED_JUMPTABLES
+/* The following are jump table entries that just call the virtual method */
+
+static int _IO_sb_overflow(_IO_FILE *fp, int c)
+{ return ((streambuf*)fp)->overflow(c); }
+static int _IO_sb_underflow(_IO_FILE *fp)
+{ return ((streambuf*)fp)->underflow(); }
+static _IO_size_t _IO_sb_xsputn(_IO_FILE *fp, const void *s, _IO_size_t n)
+{ return ((streambuf*)fp)->xsputn((const char*)s, n); }
+static _IO_size_t _IO_sb_xsgetn(_IO_FILE *fp, void *s, _IO_size_t n)
+{ return ((streambuf*)fp)->xsgetn((char*)s, n); }
+static int _IO_sb_close(_IO_FILE *fp)
+{ return ((streambuf*)fp)->sys_close(); }
+static int _IO_sb_stat(_IO_FILE *fp, void *b)
+{ return ((streambuf*)fp)->sys_stat(b); }
+static int _IO_sb_doallocate(_IO_FILE *fp)
+{ return ((streambuf*)fp)->doallocate(); }
+
+static _IO_pos_t _IO_sb_seekoff(_IO_FILE *fp, _IO_off_t pos, int dir, int mode)
+{
+ return ((streambuf*)fp)->seekoff(pos, (ios::seek_dir)dir, mode);
+}
+
+static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, int mode)
+{
+ return ((streambuf*)fp)->seekpos(pos, mode);
+}
+
+static int _IO_sb_pbackfail(_IO_FILE *fp, int ch)
+{ return ((streambuf*)fp)->pbackfail(ch); }
+static void _IO_sb_finish(_IO_FILE *fp, int)
+{ ((streambuf*)fp)->~streambuf(); }
+static _IO_ssize_t _IO_sb_read(_IO_FILE *fp, void *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->sys_read((char*)buf, n); }
+static _IO_ssize_t _IO_sb_write(_IO_FILE *fp, const void *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->sys_write((const char*)buf, n); }
+static int _IO_sb_sync(_IO_FILE *fp)
+{ return ((streambuf*)fp)->sync(); }
+static _IO_pos_t _IO_sb_seek(_IO_FILE *fp, _IO_off_t off, int dir)
+{ return ((streambuf*)fp)->sys_seek(off, (_seek_dir)dir); }
+static _IO_FILE* _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->setbuf(buf, n); }
+
+/* This callbacks in this jumptable just call the corresponding
+ virtual function, so that C functions can access (potentially user-defined)
+ streambuf-derived objects.
+ Contrast the builtinbuf class, which does the converse: Allow
+ C++ virtual calls to to be used on _IO_FILE objects that are builtin
+ (or defined by C code). */
+
+
+struct _IO_jump_t _IO_streambuf_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_sb_finish),
+ JUMP_INIT(overflow, _IO_sb_overflow),
+ JUMP_INIT(underflow, _IO_sb_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_sb_pbackfail),
+ JUMP_INIT(xsputn, _IO_sb_xsputn),
+ JUMP_INIT(xsgetn, _IO_sb_xsgetn),
+ JUMP_INIT(seekoff, _IO_sb_seekoff),
+ JUMP_INIT(seekpos, _IO_sb_seekpos),
+ JUMP_INIT(setbuf, _IO_sb_setbuf),
+ JUMP_INIT(sync, _IO_sb_sync),
+ JUMP_INIT(doallocate, _IO_sb_doallocate),
+ JUMP_INIT(read, _IO_sb_read),
+ JUMP_INIT(write, _IO_sb_write),
+ JUMP_INIT(seek, _IO_sb_seek),
+ JUMP_INIT(close, _IO_sb_close),
+ JUMP_INIT(stat, _IO_sb_stat)
+};
+#endif
+
+streambuf::streambuf(int flags)
+{
+#ifdef _IO_MTSAFE_IO
+ _lock = new _IO_lock_t;
+#endif
+ _IO_init(this, flags);
+#if !_IO_UNIFIED_JUMPTABLES
+ _jumps = &_IO_streambuf_jumps;
+#endif
+}
+
+streambuf::~streambuf()
+{
+ _IO_default_finish(this,0);
+#ifdef _IO_MTSAFE_IO
+ if (this != _IO_stdin && this != _IO_stdout && this != _IO_stderr)
+ delete _lock;
+#endif
+}
+
+streampos
+streambuf::seekoff(streamoff, _seek_dir, int /*=ios::in|ios::out*/)
+{
+ return EOF;
+}
+
+streampos
+streambuf::sseekoff(streamoff o , _seek_dir d, int m /*=ios::in|ios::out*/)
+{
+ return _IO_seekoff (this, o, d, m);
+}
+
+int streambuf::sputbackc(char c)
+{
+ return _IO_sputbackc(this, c);
+}
+
+int streambuf::sungetc()
+{
+ return _IO_sungetc(this);
+}
+
+#if 0 /* Work in progress */
+void streambuf::collumn(int c)
+{
+ if (c == -1)
+ _collumn = -1;
+ else
+ _collumn = c - (_IO_write_ptr - _IO_write_base);
+}
+#endif
+
+
+int streambuf::get_column()
+{
+ if (_cur_column)
+ return _IO_adjust_column(_cur_column - 1, pbase(), pptr() - pbase());
+ return -1;
+}
+
+int streambuf::set_column(int i)
+{
+ _cur_column = i+1;
+ return 0;
+}
+
+int streambuf::flush_all() { return _IO_flush_all (); }
+
+void streambuf::flush_all_linebuffered()
+{ _IO_flush_all_linebuffered(); }
+
+int streambuf::sys_stat(void *)
+{
+#ifdef EIO
+ errno = EIO;
+#endif
+ return -1;
+}
+
+streamsize streambuf::sys_read(char* /*buf*/, streamsize /*size*/)
+{
+ return 0;
+}
+
+streamsize streambuf::sys_write(const char* /*buf*/, streamsize /*size*/)
+{
+ return 0;
+}
+
+streampos streambuf::sys_seek(streamoff, _seek_dir)
+{
+ return EOF;
+}
+
+int streambuf::sys_close() { return 0; /* Suceess; do nothing */ }
+
+#if _G_IO_IO_FILE_VERSION == 0x20001
+int streambuf::showmanyc()
+{
+ return -1;
+}
+
+void streambuf::imbue(void *)
+{
+}
+#endif
+
+streammarker::streammarker(streambuf *sb)
+{
+ _IO_init_marker(this, sb);
+}
+
+streammarker::~streammarker()
+{
+ _IO_remove_marker(this);
+}
+
+#define BAD_DELTA EOF
+
+int streammarker::delta(streammarker& other_mark)
+{
+ return _IO_marker_difference(this, &other_mark);
+}
+
+int streammarker::delta()
+{
+ return _IO_marker_delta(this);
+}
+
+int streambuf::seekmark(streammarker& mark, int delta /* = 0 */)
+{
+ return _IO_seekmark(this, &mark, delta);
+}
+
+void streambuf::unsave_markers()
+{
+ _IO_unsave_markers(this);
+}
+
+int ios::readable() { return !(rdbuf()->_flags & _IO_NO_READS); }
+int ios::writable() { return !(rdbuf()->_flags & _IO_NO_WRITES); }
+int ios::is_open() { return rdbuf()
+ && (rdbuf()->_flags & _IO_NO_READS+_IO_NO_WRITES)
+ != _IO_NO_READS+_IO_NO_WRITES; }
+
+#if defined(linux)
+#define IO_CLEANUP
+#endif
+
+#ifdef IO_CLEANUP
+ IO_CLEANUP
+#else
+struct __io_defs {
+ ~__io_defs() { _IO_cleanup (); }
+};
+__io_defs io_defs__;
+#endif
diff --git a/gnu/dist/libio/streambuf.h b/gnu/dist/libio/streambuf.h
new file mode 100644
index 00000000000..bc734bc75b0
--- /dev/null
+++ b/gnu/dist/libio/streambuf.h
@@ -0,0 +1,488 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _STREAMBUF_H
+#define _STREAMBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* #define _G_IO_THROW */ /* Not implemented: ios::failure */
+
+#define _IO_NEW_STREAMS // new optimizated stream representation
+
+extern "C" {
+#include <libio.h>
+}
+//#include <_G_config.h>
+#ifdef _G_NEED_STDARG_H
+#include <stdarg.h>
+#endif
+#ifndef _IO_va_list
+#define _IO_va_list char *
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#ifdef __GNUG__
+#define NULL (__null)
+#else
+#define NULL (0)
+#endif
+#endif
+
+#ifndef _IO_wchar_t
+#if _G_IO_IO_FILE_VERSION == 0x20001
+#define _IO_wchar_t _G_wchar_t
+#else
+#define _IO_wchar_t short
+#endif
+#endif
+
+extern "C++" {
+class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */
+class ostream; class streambuf;
+
+// In case some header files defines these as macros.
+#undef open
+#undef close
+
+#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001
+typedef _IO_off64_t streamoff;
+typedef _IO_fpos64_t streampos;
+#else
+typedef _IO_off_t streamoff;
+typedef _IO_fpos_t streampos;
+#endif
+typedef _IO_ssize_t streamsize;
+
+typedef unsigned long __fmtflags;
+typedef unsigned char __iostate;
+
+struct _ios_fields
+{ // The data members of an ios.
+ streambuf *_strbuf;
+ ostream* _tie;
+ int _width;
+ __fmtflags _flags;
+ _IO_wchar_t _fill;
+ __iostate _state;
+ __iostate _exceptions;
+ int _precision;
+
+ void *_arrays; /* Support for ios::iword and ios::pword. */
+};
+
+#define _IOS_GOOD 0
+#define _IOS_EOF 1
+#define _IOS_FAIL 2
+#define _IOS_BAD 4
+
+#define _IO_INPUT 1
+#define _IO_OUTPUT 2
+#define _IO_ATEND 4
+#define _IO_APPEND 8
+#define _IO_TRUNC 16
+#define _IO_NOCREATE 32
+#define _IO_NOREPLACE 64
+#define _IO_BIN 128
+
+#ifdef _STREAM_COMPAT
+enum state_value {
+ _good = _IOS_GOOD,
+ _eof = _IOS_EOF,
+ _fail = _IOS_FAIL,
+ _bad = _IOS_BAD };
+enum open_mode {
+ input = _IO_INPUT,
+ output = _IO_OUTPUT,
+ atend = _IO_ATEND,
+ append = _IO_APPEND };
+#endif
+
+class ios : public _ios_fields {
+ ios& operator=(ios&); /* Not allowed! */
+ ios (const ios&); /* Not allowed! */
+ public:
+ typedef __fmtflags fmtflags;
+ typedef int iostate;
+ typedef int openmode;
+ typedef int streamsize;
+ enum io_state {
+ goodbit = _IOS_GOOD,
+ eofbit = _IOS_EOF,
+ failbit = _IOS_FAIL,
+ badbit = _IOS_BAD };
+ enum open_mode {
+ in = _IO_INPUT,
+ out = _IO_OUTPUT,
+ ate = _IO_ATEND,
+ app = _IO_APPEND,
+ trunc = _IO_TRUNC,
+ nocreate = _IO_NOCREATE,
+ noreplace = _IO_NOREPLACE,
+ bin = _IOS_BIN, // Deprecated - ANSI uses ios::binary.
+ binary = _IOS_BIN };
+ enum seek_dir { beg, cur, end};
+ typedef enum seek_dir seekdir;
+ // NOTE: If adding flags here, before to update ios::bitalloc().
+ enum { skipws=_IO_SKIPWS,
+ left=_IO_LEFT, right=_IO_RIGHT, internal=_IO_INTERNAL,
+ dec=_IO_DEC, oct=_IO_OCT, hex=_IO_HEX,
+ showbase=_IO_SHOWBASE, showpoint=_IO_SHOWPOINT,
+ uppercase=_IO_UPPERCASE, showpos=_IO_SHOWPOS,
+ scientific=_IO_SCIENTIFIC, fixed=_IO_FIXED,
+ unitbuf=_IO_UNITBUF, stdio=_IO_STDIO
+#ifndef _IO_NEW_STREAMS
+ , dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction
+#endif
+ };
+ enum { // Masks.
+ basefield=dec+oct+hex,
+ floatfield = scientific+fixed,
+ adjustfield = left+right+internal
+ };
+
+#ifdef _IO_THROW
+ class failure : public xmsg {
+ ios* _stream;
+ public:
+ failure(ios* stream) { _stream = stream; }
+ failure(string cause, ios* stream) { _stream = stream; }
+ ios* rdios() const { return _stream; }
+ };
+#endif
+
+ ostream* tie() const { return _tie; }
+ ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
+
+ // Methods to change the format state.
+ _IO_wchar_t fill() const { return _fill; }
+ _IO_wchar_t fill(_IO_wchar_t newf)
+ {_IO_wchar_t oldf = _fill; _fill = newf; return oldf;}
+ fmtflags flags() const { return _flags; }
+ fmtflags flags(fmtflags new_val) {
+ fmtflags old_val = _flags; _flags = new_val; return old_val; }
+ int precision() const { return _precision; }
+ int precision(int newp) {
+ unsigned short oldp = _precision; _precision = (unsigned short)newp;
+ return oldp; }
+ fmtflags setf(fmtflags val) {
+ fmtflags oldbits = _flags;
+ _flags |= val; return oldbits; }
+ fmtflags setf(fmtflags val, fmtflags mask) {
+ fmtflags oldbits = _flags;
+ _flags = (_flags & ~mask) | (val & mask); return oldbits; }
+ fmtflags unsetf(fmtflags mask) {
+ fmtflags oldbits = _flags;
+ _flags &= ~mask; return oldbits; }
+ int width() const { return _width; }
+ int width(int val) { int save = _width; _width = val; return save; }
+
+#ifdef _IO_THROW
+ void _throw_failure() const { throw new ios::failure(this); }
+#else
+ void _throw_failure() const { }
+#endif
+ void clear(iostate state = 0) {
+ _state = _strbuf ? state : state|badbit;
+ if (_state & _exceptions) _throw_failure(); }
+ void set(iostate flag) { _state |= flag;
+ if (_state & _exceptions) _throw_failure(); }
+ void setstate(iostate flag) { _state |= flag; // ANSI
+ if (_state & _exceptions) _throw_failure(); }
+ int good() const { return _state == 0; }
+ int eof() const { return _state & ios::eofbit; }
+ int fail() const { return _state & (ios::badbit|ios::failbit); }
+ int bad() const { return _state & ios::badbit; }
+ iostate rdstate() const { return _state; }
+ operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
+ int operator!() const { return fail(); }
+ iostate exceptions() const { return _exceptions; }
+ void exceptions(iostate enable) {
+ _exceptions = enable;
+ if (_state & _exceptions) _throw_failure(); }
+
+ streambuf* rdbuf() const { return _strbuf; }
+ streambuf* rdbuf(streambuf *_s) {
+ streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; }
+
+ static int sync_with_stdio(int on);
+ static void sync_with_stdio() { sync_with_stdio(1); }
+ static fmtflags bitalloc();
+ static int xalloc();
+ void*& pword(int);
+ void* pword(int) const;
+ long& iword(int);
+ long iword(int) const;
+
+#ifdef _STREAM_COMPAT
+ void unset(state_value flag) { _state &= ~flag; }
+ void close();
+ int is_open();
+ int readable();
+ int writable();
+#endif
+
+ // Used to initialize standard streams. Not needed in this implementation.
+ class Init {
+ public:
+ Init () { }
+ };
+
+ protected:
+ inline ios(streambuf* sb = 0, ostream* tie_to = 0);
+ inline virtual ~ios();
+ inline void init(streambuf* sb, ostream* tie = 0);
+};
+
+#if __GNUG__==1
+typedef int _seek_dir;
+#else
+typedef ios::seek_dir _seek_dir;
+#endif
+
+// 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.
+// Note: The magic numbers must all be negative if stdio
+// emulation is desired.
+
+// A streammarker remembers a position in a buffer.
+// You are guaranteed to be able to seek back to it if it is saving().
+class streammarker : private _IO_marker {
+ friend class streambuf;
+ void set_offset(int offset) { _pos = offset; }
+ public:
+ streammarker(streambuf *sb);
+ ~streammarker();
+ int saving() { return 1; }
+ int delta(streammarker&);
+ int delta();
+};
+
+struct streambuf : public _IO_FILE { // protected??
+ friend class ios;
+ friend class istream;
+ friend class ostream;
+ friend class streammarker;
+ const void *&_vtable() { return *(const void**)((_IO_FILE*)this + 1); }
+ protected:
+ static streambuf* _list_all; /* List of open streambufs. */
+ _IO_FILE*& xchain() { return _chain; }
+ void _un_link();
+ void _link_in();
+ char* gptr() const
+ { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_ptr; }
+ char* pptr() const { return _IO_write_ptr; }
+ char* egptr() const
+ { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_end : _IO_read_end; }
+ char* epptr() const { return _IO_write_end; }
+ char* pbase() const { return _IO_write_base; }
+ char* eback() const
+ { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_base;}
+ char* base() const { return _IO_buf_base; }
+ char* ebuf() const { return _IO_buf_end; }
+ int blen() const { return _IO_buf_end - _IO_buf_base; }
+ void xput_char(char c) { *_IO_write_ptr++ = c; }
+ int xflags() { return _IO_file_flags; }
+ int xflags(int f) {int fl = _IO_file_flags; _IO_file_flags = f; return fl;}
+ void xsetflags(int f) { _IO_file_flags |= f; }
+ void xsetflags(int f, int mask)
+ { _IO_file_flags = (_IO_file_flags & ~mask) | (f & mask); }
+ void gbump(int n)
+ { _IO_file_flags & _IO_IN_BACKUP ? (_IO_save_base+=n):(_IO_read_ptr+=n);}
+ void pbump(int n) { _IO_write_ptr += n; }
+ void setb(char* b, char* eb, int a=0);
+ void setp(char* p, char* ep)
+ { _IO_write_base=_IO_write_ptr=p; _IO_write_end=ep; }
+ void setg(char* eb, char* g, char *eg) {
+ if (_IO_file_flags & _IO_IN_BACKUP) _IO_free_backup_area(this);
+ _IO_read_base = eb; _IO_read_ptr = g; _IO_read_end = eg; }
+ char *shortbuf() { return _shortbuf; }
+
+ int in_backup() { return _flags & _IO_IN_BACKUP; }
+ // The start of the main get area: FIXME: wrong for write-mode filebuf?
+ char *Gbase() { return in_backup() ? _IO_save_base : _IO_read_base; }
+ // The end of the main get area:
+ char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; }
+ // The start of the backup area:
+ char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; }
+ char *Bptr() { return _IO_backup_base; }
+ // The end of the backup area:
+ char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; }
+ char *Nbase() { return _IO_save_base; }
+ char *eNptr() { return _IO_save_end; }
+ int have_backup() { return _IO_save_base != NULL; }
+ int have_markers() { return _markers != NULL; }
+ void free_backup_area();
+ void unsave_markers(); // Make all streammarkers !saving().
+ int put_mode() { return _flags & _IO_CURRENTLY_PUTTING; }
+ int switch_to_get_mode();
+
+ streambuf(int flags=0);
+ public:
+ static int flush_all();
+ static void flush_all_linebuffered(); // Flush all line buffered files.
+ virtual ~streambuf();
+ virtual int overflow(int c = EOF); // Leave public for now
+ virtual int underflow(); // Leave public for now
+ virtual int uflow(); // Leave public for now
+ virtual int pbackfail(int c);
+// virtual int showmany ();
+ virtual streamsize xsputn(const char* s, streamsize n);
+ virtual streamsize xsgetn(char* s, streamsize n);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+
+ streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out)
+ { return _IO_seekoff (this, o, d, mode); }
+ streampos pubseekpos(streampos pos, int mode = ios::in|ios::out)
+ { return _IO_seekpos (this, pos, mode); }
+ streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ streampos sseekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual streambuf* setbuf(char* p, int len);
+ virtual int sync();
+ virtual int doallocate();
+
+ int seekmark(streammarker& mark, int delta = 0);
+ int sputbackc(char c);
+ int sungetc();
+ int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; }
+ int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; }
+ void unbuffered(int i)
+ { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; }
+ void linebuffered(int i)
+ { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; }
+ int allocate() { // For AT&T compatibility
+ if (base() || unbuffered()) return 0;
+ else return doallocate(); }
+ // Allocate a buffer if needed; use _shortbuf if appropriate.
+ void allocbuf() { if (base() == NULL) doallocbuf(); }
+ void doallocbuf();
+ int in_avail() { return _IO_read_end - _IO_read_ptr; }
+ int out_waiting() { return _IO_write_ptr - _IO_write_base; }
+ streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); }
+ streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); }
+ streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); }
+ int ignore(int);
+ int get_column();
+ int set_column(int);
+ long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim);
+ int sputc(int c) { return _IO_putc(c, this); }
+ int sbumpc() { return _IO_getc(this); }
+ int sgetc() { return _IO_peekc(this); }
+ int snextc() {
+ if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF)
+ return EOF;
+ else return _IO_read_ptr++, sgetc(); }
+ void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; }
+ int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL);
+ int scan(char const *fmt0 ...);
+ int vform(char const *fmt0, _IO_va_list ap);
+ int form(char const *fmt0 ...);
+#if 0 /* Work in progress */
+ int column(); // Current column number (of put pointer). -1 is unknown.
+ void column(int c); // Set column number of put pointer to c.
+#endif
+ virtual streamsize sys_read(char* buf, streamsize size);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual int sys_close();
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+#if _G_IO_IO_FILE_VERSION == 0x20001
+ virtual int showmanyc();
+ virtual void imbue(void *);
+#endif
+};
+
+// A backupbuf is a streambuf with full backup and savepoints on reading.
+// All standard streambufs in the GNU iostream library are backupbufs.
+
+class filebuf : public streambuf {
+ protected:
+ void init();
+ public:
+ static const int openprot; // Non-ANSI AT&T-ism: Default open protection.
+ filebuf();
+ filebuf(int fd);
+ filebuf(int fd, char* p, int len);
+#if !_IO_UNIFIED_JUMPTABLES
+ static filebuf *__new();
+#endif
+ ~filebuf();
+ filebuf* attach(int fd);
+ filebuf* open(const char *filename, const char *mode);
+ filebuf* open(const char *filename, ios::openmode mode, int prot = 0664);
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ int is_open() const { return _fileno >= 0; }
+ int fd() const { return is_open() ? _fileno : EOF; }
+ filebuf* close();
+ virtual int doallocate();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streambuf* setbuf(char* p, int len);
+ streamsize xsputn(const char* s, streamsize n);
+ streamsize xsgetn(char* s, streamsize n);
+ virtual int sync();
+ protected: // See documentation in filebuf.C.
+// virtual int pbackfail(int c);
+ int is_reading() { return eback() != egptr(); }
+ char* cur_ptr() { return is_reading() ? gptr() : pptr(); }
+ /* System's idea of pointer */
+ char* file_ptr() { return eGptr(); }
+ // Low-level operations (Usually invoke system calls.)
+ virtual streamsize sys_read(char* buf, streamsize size);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+ virtual int sys_close();
+#if 0
+ virtual uflow;
+ virtual showmany;
+#endif
+};
+
+inline void ios::init(streambuf* sb, ostream* tie_to) {
+ _state = sb ? ios::goodbit : ios::badbit; _exceptions=0;
+ _strbuf=sb; _tie = tie_to; _width=0; _fill=' ';
+#ifdef _IO_NEW_STREAMS
+ _flags=ios::skipws|ios::dec;
+#else
+ _flags=ios::skipws|ios::dec|ios::dont_close;
+#endif
+ _precision=6; _arrays = 0; }
+
+inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); }
+
+inline ios::~ios() {
+#ifndef _IO_NEW_STREAMS
+ if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf();
+#endif
+ if (_arrays) delete [] _arrays;
+}
+} // extern "C++"
+#endif /* _STREAMBUF_H */
diff --git a/gnu/dist/libio/strfile.h b/gnu/dist/libio/strfile.h
new file mode 100644
index 00000000000..a0e47021f6e
--- /dev/null
+++ b/gnu/dist/libio/strfile.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libio.h>
+#ifdef TODO
+Merge into libio.h ?
+#endif
+
+typedef void *(*_IO_alloc_type) __P ((_IO_size_t));
+typedef void (*_IO_free_type) __P ((void*));
+
+struct _IO_str_fields
+{
+ _IO_alloc_type _allocate_buffer;
+ _IO_free_type _free_buffer;
+};
+
+/* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type,
+ but a 32 bit pointer type. In this case, we get 4 bytes of padding
+ after the vtable pointer. Putting them in a structure together solves
+ this problem. */
+
+struct _IO_streambuf
+{
+ struct _IO_FILE _f;
+ const void *_vtable;
+};
+
+typedef struct _IO_strfile_
+{
+ struct _IO_streambuf _sbf;
+ struct _IO_str_fields _s;
+} _IO_strfile;
+
+/* dynamic: set when the array object is allocated (or reallocated) as
+ necessary to hold a character sequence that can change in length. */
+#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0)
+
+/* frozen: set when the program has requested that the array object not
+ be altered, reallocated, or freed. */
+#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF)
diff --git a/gnu/dist/libio/strops.c b/gnu/dist/libio/strops.c
new file mode 100644
index 00000000000..a9f812e0451
--- /dev/null
+++ b/gnu/dist/libio/strops.c
@@ -0,0 +1,303 @@
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "strfile.h"
+#include "libioP.h"
+#include <string.h>
+
+#if 0
+/* The following definitions are for exposition only.
+ They map the terminology used in the ANSI/ISO C++ draft standard
+ to the implementation. */
+
+/* allocated: set when a dynamic array object has been allocated, and
+ hence should be freed by the destructor for the strstreambuf object. */
+#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
+
+/* constant: set when the array object has const elements,
+ so the output sequence cannot be written. */
+#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
+
+/* alsize: the suggested minimum size for a dynamic array object. */
+#define ALSIZE(FP) ??? /* not stored */
+
+/* palloc: points to the function to call to allocate a dynamic array object.*/
+#define PALLOC(FP) \
+ ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
+
+/* pfree: points to the function to call to free a dynamic array object. */
+#define PFREE(FP) \
+ ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
+
+#endif
+
+#ifdef TODO
+/* An "unbounded buffer" is when a buffer is supplied, but with no
+ specified length. An example is the buffer argument to sprintf.
+ */
+#endif
+
+void
+_IO_str_init_static (fp, ptr, size, pstart)
+ _IO_FILE *fp;
+ char *ptr;
+ int size;
+ char *pstart;
+{
+ if (size == 0)
+ size = strlen (ptr);
+ else if (size < 0)
+ {
+ /* If size is negative 'the characters are assumed to
+ continue indefinitely.' This is kind of messy ... */
+ int s;
+ size = 512;
+ /* Try increasing powers of 2, as long as we don't wrap around. */
+ for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+ size = s;
+ /* Try increasing size as much as we can without wrapping around. */
+ for (s = size >> 1; s > 0; s >>= 1)
+ {
+ if (ptr + size + s > ptr)
+ size += s;
+ }
+ }
+ _IO_setb (fp, ptr, ptr + size, 0);
+
+ fp->_IO_write_base = ptr;
+ fp->_IO_read_base = ptr;
+ fp->_IO_read_ptr = ptr;
+ if (pstart)
+ {
+ fp->_IO_write_ptr = pstart;
+ fp->_IO_write_end = ptr + size;
+ fp->_IO_read_end = pstart;
+ }
+ else
+ {
+ fp->_IO_write_ptr = ptr;
+ fp->_IO_write_end = ptr;
+ fp->_IO_read_end = ptr+size;
+ }
+ /* A null _allocate_buffer function flags the strfile as being static. */
+ (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
+}
+
+void
+_IO_str_init_readonly (fp, ptr, size)
+ _IO_FILE *fp;
+ const char *ptr;
+ int size;
+{
+ _IO_str_init_static (fp, (char *) ptr, size, NULL);
+ fp->_IO_file_flags |= _IO_NO_WRITES;
+}
+
+int
+_IO_str_overflow (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ int flush_only = c == EOF;
+ _IO_size_t pos;
+ if (fp->_flags & _IO_NO_WRITES)
+ return flush_only ? 0 : EOF;
+ if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ fp->_flags |= _IO_CURRENTLY_PUTTING;
+ fp->_IO_write_ptr = fp->_IO_read_ptr;
+ fp->_IO_read_ptr = fp->_IO_read_end;
+ }
+ pos = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
+ {
+ if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
+ return EOF;
+ else
+ {
+ char *new_buf;
+ char *old_buf = fp->_IO_buf_base;
+ _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
+ new_buf
+ = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
+ if (new_buf == NULL)
+ {
+ /* __ferror(fp) = 1; */
+ return EOF;
+ }
+ if (fp->_IO_buf_base)
+ {
+ memcpy (new_buf, old_buf, _IO_blen (fp));
+ (*((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
+ /* Make sure _IO_setb won't try to delete _IO_buf_base. */
+ fp->_IO_buf_base = NULL;
+ }
+#if 0
+ if (lenp == &LEN(fp)) /* use '\0'-filling */
+ memset (new_buf + pos, 0, blen() - pos);
+#endif
+ _IO_setb (fp, new_buf, new_buf + new_size, 1);
+ fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
+ fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
+ fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
+ fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
+
+ fp->_IO_write_base = new_buf;
+ fp->_IO_write_end = fp->_IO_buf_end;
+ }
+ }
+
+ if (!flush_only)
+ *fp->_IO_write_ptr++ = (unsigned char) c;
+ if (fp->_IO_write_ptr > fp->_IO_read_end)
+ fp->_IO_read_end = fp->_IO_write_ptr;
+ return c;
+}
+
+int
+_IO_str_underflow (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_IO_write_ptr > fp->_IO_read_end)
+ fp->_IO_read_end = fp->_IO_write_ptr;
+ if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ fp->_IO_read_ptr = fp->_IO_write_ptr;
+ fp->_IO_write_ptr = fp->_IO_write_end;
+ }
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *fp->_IO_read_ptr;
+ else
+ return EOF;
+}
+
+/* The size of the valid part of the buffer. */
+
+_IO_ssize_t
+_IO_str_count (fp)
+ _IO_FILE *fp;
+{
+ return ((fp->_IO_write_ptr > fp->_IO_read_end
+ ? fp->_IO_write_ptr : fp->_IO_read_end)
+ - fp->_IO_read_base);
+}
+
+_IO_pos_t
+_IO_str_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+ int mode;
+{
+ _IO_ssize_t cur_size = _IO_str_count (fp);
+ _IO_pos_t new_pos = EOF;
+
+ /* Move the get pointer, if requested. */
+ if (mode & _IOS_INPUT)
+ {
+ switch (dir)
+ {
+ case _IO_seek_end:
+ offset += cur_size;
+ break;
+ case _IO_seek_cur:
+ offset += fp->_IO_read_ptr - fp->_IO_read_base;
+ break;
+ default: /* case _IO_seek_set: */
+ break;
+ }
+ if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+ return EOF;
+ fp->_IO_read_ptr = fp->_IO_read_base + offset;
+ fp->_IO_read_end = fp->_IO_read_base + cur_size;
+ new_pos = offset;
+ }
+
+ /* Move the put pointer, if requested. */
+ if (mode & _IOS_OUTPUT)
+ {
+ switch (dir)
+ {
+ case _IO_seek_end:
+ offset += cur_size;
+ break;
+ case _IO_seek_cur:
+ offset += fp->_IO_write_ptr - fp->_IO_write_base;
+ break;
+ default: /* case _IO_seek_set: */
+ break;
+ }
+ if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+ return EOF;
+ fp->_IO_write_ptr = fp->_IO_write_base + offset;
+ new_pos = offset;
+ }
+ return new_pos;
+}
+
+int
+_IO_str_pbackfail (fp, c)
+ _IO_FILE *fp;
+ int c;
+{
+ if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
+ return EOF;
+ return _IO_default_pbackfail (fp, c);
+}
+
+void
+_IO_str_finish (fp, dummy)
+ _IO_FILE *fp;
+ int dummy;
+{
+ if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+ (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
+ fp->_IO_buf_base = NULL;
+
+ _IO_default_finish (fp, 0);
+}
+
+struct _IO_jump_t _IO_str_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_str_finish),
+ JUMP_INIT(overflow, _IO_str_overflow),
+ JUMP_INIT(underflow, _IO_str_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_str_pbackfail),
+ JUMP_INIT(xsputn, _IO_default_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_str_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_default_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_default_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat)
+};
diff --git a/gnu/dist/libio/strstream.cc b/gnu/dist/libio/strstream.cc
new file mode 100644
index 00000000000..a32e811c9d9
--- /dev/null
+++ b/gnu/dist/libio/strstream.cc
@@ -0,0 +1,116 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "iostreamP.h"
+#include "strstream.h"
+#include <string.h>
+
+static void* default_alloc(_IO_size_t size)
+{
+ return (void*)new char[size];
+}
+
+static void default_free(void* ptr)
+{
+ delete [] (char*)ptr;
+}
+
+istrstream::istrstream(const char *cp, int n)
+{
+ __my_sb.init_readonly (cp, n);
+}
+
+strstreambase::strstreambase(char *cp, int n, int mode)
+: __my_sb (cp, n,
+ (mode == ios::app || mode == ios::ate) ? cp + strlen(cp) : cp)
+{
+ init (&__my_sb);
+}
+
+char *strstreambuf::str()
+{
+ freeze(1);
+ return base();
+}
+
+_IO_ssize_t strstreambuf::pcount () { return _IO_write_ptr - _IO_write_base; }
+
+int strstreambuf::overflow(int c /* = EOF */)
+{
+ return _IO_str_overflow (this, c);
+}
+
+int strstreambuf::underflow()
+{
+ return _IO_str_underflow(this);
+}
+
+
+void strstreambuf::init_dynamic(_IO_alloc_type alloc, _IO_free_type free,
+ int initial_size)
+
+{
+ _s._allocate_buffer = alloc ? alloc : default_alloc;
+ _s._free_buffer = free ? free : default_free;
+ if (initial_size > 0)
+ {
+ char * buf = (char*)(*_s._allocate_buffer)(initial_size);
+ setb(buf, buf + initial_size, 1);
+ setp(buf, buf + initial_size);
+ setg(buf, buf, buf);
+ }
+}
+
+void strstreambuf::init_static(char *ptr, int size, char *pstart)
+{
+ _IO_str_init_static (this, ptr, size, pstart);
+}
+
+void strstreambuf::init_readonly (const char *ptr, int size)
+{
+ _IO_str_init_readonly (this, ptr, size);
+}
+
+strstreambuf::~strstreambuf()
+{
+ if (_IO_buf_base && !(_flags & _IO_USER_BUF))
+ (_s._free_buffer)(_IO_buf_base);
+ _IO_buf_base = NULL;
+}
+
+streampos strstreambuf::seekoff(streamoff off, _seek_dir dir,
+ int mode /*=ios::in|ios::out*/)
+{
+ return _IO_str_seekoff (this, off, dir, mode);
+}
+
+int strstreambuf::pbackfail(int c)
+{
+ return _IO_str_pbackfail (this, c);
+}
diff --git a/gnu/dist/libio/strstream.h b/gnu/dist/libio/strstream.h
new file mode 100644
index 00000000000..d549b454758
--- /dev/null
+++ b/gnu/dist/libio/strstream.h
@@ -0,0 +1,113 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef __STRSTREAM_H
+#define __STRSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <iostream.h>
+#include <strfile.h>
+
+extern "C++" {
+class strstreambuf : public streambuf
+{
+ struct _IO_str_fields _s;
+ friend class istrstream;
+
+ void init_dynamic(_IO_alloc_type alloc, _IO_free_type free,
+ int initial_size = 0);
+ void init_static(char *ptr, int size, char *pstart);
+ void init_readonly(const char *ptr, int size);
+ protected:
+ virtual int overflow(int = EOF);
+ virtual int underflow();
+ virtual int pbackfail(int c);
+ public:
+ virtual ~strstreambuf();
+ strstreambuf() { init_dynamic(0, 0); }
+ strstreambuf(int initial_size) { init_dynamic(0, 0, initial_size); }
+ strstreambuf(void *(*alloc)(_IO_size_t), void (*free)(void*))
+ { init_dynamic(alloc, free); }
+ strstreambuf(char *ptr, int size, char *pstart = NULL)
+ { init_static(ptr, size, pstart); }
+ strstreambuf(unsigned char *ptr, int size, unsigned char *pstart = NULL)
+ { init_static((char*)ptr, size, (char*)pstart); }
+ strstreambuf(const char *ptr, int size)
+ { init_readonly(ptr, size); }
+ strstreambuf(const unsigned char *ptr, int size)
+ { init_readonly((const char*)ptr, size); }
+ strstreambuf(signed char *ptr, int size, signed char *pstart = NULL)
+ { init_static((char*)ptr, size, (char*)pstart); }
+ strstreambuf(const signed char *ptr, int size)
+ { init_readonly((const char*)ptr, size); }
+ // Note: frozen() is always true if !_IO_STR_DYNAMIC(this).
+ int frozen() { return _flags & _IO_USER_BUF ? 1 : 0; }
+ void freeze(int n=1)
+ { if (_IO_STR_DYNAMIC(this))
+ { if (n) _flags |= _IO_USER_BUF; else _flags &= ~_IO_USER_BUF; } }
+ _IO_ssize_t pcount();
+ char *str();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+};
+
+class strstreambase : virtual public ios {
+ protected:
+ strstreambuf __my_sb;
+ public:
+ strstreambuf* rdbuf() { return &__my_sb; }
+ protected:
+ strstreambase() { init (&__my_sb); }
+ strstreambase(char *cp, int n, int mode=ios::out);
+};
+
+class istrstream : public strstreambase, public istream {
+ public:
+ istrstream(const char*, int=0);
+};
+
+class ostrstream : public strstreambase, public ostream {
+ public:
+ ostrstream() { }
+ ostrstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
+ _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
+ char *str() { return ((strstreambuf*)_strbuf)->str(); }
+ void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
+ int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
+};
+
+class strstream : public strstreambase, public iostream {
+ public:
+ strstream() { }
+ strstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
+ _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
+ char *str() { return ((strstreambuf*)_strbuf)->str(); }
+ void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
+ int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
+};
+} // extern "C++"
+
+#endif /*!__STRSTREAM_H*/