summaryrefslogtreecommitdiffstats
path: root/gnu/lib
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1994-08-08 05:52:55 +0000
committerphk <phk@FreeBSD.org>1994-08-08 05:52:55 +0000
commitc8beafaf61a7e1bf16aaef28f9112c7705f4f1f1 (patch)
tree45b379846d17cbe73053d37a6dc47dae07cdc33d /gnu/lib
parent4c5e434fdaef40513ed9bc2059aa202f7e1b9929 (diff)
downloadFreeBSD-src-c8beafaf61a7e1bf16aaef28f9112c7705f4f1f1.zip
FreeBSD-src-c8beafaf61a7e1bf16aaef28f9112c7705f4f1f1.tar.gz
I belive this should be makeable under 2.0. There may be outstanding
issues in these areas: .h's installed .hP's installed -lcurses interaction files needed in ~/legal for copyleft reasons.
Diffstat (limited to 'gnu/lib')
-rw-r--r--gnu/lib/libg++/Makefile18
-rw-r--r--gnu/lib/libg++/include/ACG.h68
-rw-r--r--gnu/lib/libg++/include/AllocRing.h62
-rw-r--r--gnu/lib/libg++/include/Binomial.h55
-rw-r--r--gnu/lib/libg++/include/BitSet.h374
-rw-r--r--gnu/lib/libg++/include/BitString.h761
-rw-r--r--gnu/lib/libg++/include/Complex.h276
-rw-r--r--gnu/lib/libg++/include/CursesW.h590
-rw-r--r--gnu/lib/libg++/include/DLList.h126
-rw-r--r--gnu/lib/libg++/include/DiscUnif.h72
-rw-r--r--gnu/lib/libg++/include/Erlang.h68
-rw-r--r--gnu/lib/libg++/include/Fix.h513
-rw-r--r--gnu/lib/libg++/include/Fix16.h648
-rw-r--r--gnu/lib/libg++/include/Fix24.h597
-rw-r--r--gnu/lib/libg++/include/Geom.h52
-rw-r--r--gnu/lib/libg++/include/GetOpt.h129
-rw-r--r--gnu/lib/libg++/include/HypGeom.h70
-rw-r--r--gnu/lib/libg++/include/Integer.h1119
-rw-r--r--gnu/lib/libg++/include/Integer.hP30
-rw-r--r--gnu/lib/libg++/include/LogNorm.h78
-rw-r--r--gnu/lib/libg++/include/MLCG.h87
-rw-r--r--gnu/lib/libg++/include/NegExp.h55
-rw-r--r--gnu/lib/libg++/include/Normal.h66
-rw-r--r--gnu/lib/libg++/include/Obstack.h216
-rw-r--r--gnu/lib/libg++/include/Pix.h5
-rw-r--r--gnu/lib/libg++/include/PlotFile.h121
-rw-r--r--gnu/lib/libg++/include/Poisson.h51
-rw-r--r--gnu/lib/libg++/include/RNG.h58
-rw-r--r--gnu/lib/libg++/include/Random.h54
-rw-r--r--gnu/lib/libg++/include/Rational.h288
-rw-r--r--gnu/lib/libg++/include/Regex.h76
-rw-r--r--gnu/lib/libg++/include/RndInt.h175
-rw-r--r--gnu/lib/libg++/include/SFile.h53
-rw-r--r--gnu/lib/libg++/include/SLList.h115
-rw-r--r--gnu/lib/libg++/include/SmplHist.h72
-rw-r--r--gnu/lib/libg++/include/SmplStat.h66
-rw-r--r--gnu/lib/libg++/include/String.h1328
-rw-r--r--gnu/lib/libg++/include/Uniform.h71
-rw-r--r--gnu/lib/libg++/include/Weibull.h74
-rw-r--r--gnu/lib/libg++/include/_G_config.h70
-rw-r--r--gnu/lib/libg++/include/ansidecl.h141
-rw-r--r--gnu/lib/libg++/include/bitdo1.h32
-rw-r--r--gnu/lib/libg++/include/bitdo2.h184
-rw-r--r--gnu/lib/libg++/include/bitprims.h125
-rw-r--r--gnu/lib/libg++/include/builtin.h159
-rw-r--r--gnu/lib/libg++/include/builtinbuf.h63
-rw-r--r--gnu/lib/libg++/include/compare.h91
-rw-r--r--gnu/lib/libg++/include/config.h1
-rw-r--r--gnu/lib/libg++/include/defines.h33
-rw-r--r--gnu/lib/libg++/include/editbuf.h183
-rw-r--r--gnu/lib/libg++/include/floatio.h51
-rw-r--r--gnu/lib/libg++/include/fstream.h81
-rw-r--r--gnu/lib/libg++/include/indstream.h74
-rw-r--r--gnu/lib/libg++/include/iolibio.h46
-rw-r--r--gnu/lib/libg++/include/iomanip.h159
-rw-r--r--gnu/lib/libg++/include/iostream.h227
-rw-r--r--gnu/lib/libg++/include/iostreamP.h34
-rw-r--r--gnu/lib/libg++/include/libiberty.h107
-rw-r--r--gnu/lib/libg++/include/libio.h254
-rw-r--r--gnu/lib/libg++/include/libioP.h308
-rw-r--r--gnu/lib/libg++/include/new.h27
-rw-r--r--gnu/lib/libg++/include/parsestream.h154
-rw-r--r--gnu/lib/libg++/include/pfstream.h57
-rw-r--r--gnu/lib/libg++/include/procbuf.h39
-rw-r--r--gnu/lib/libg++/include/regex.h272
-rw-r--r--gnu/lib/libg++/include/std.h35
-rw-r--r--gnu/lib/libg++/include/stdiostream.h77
-rw-r--r--gnu/lib/libg++/include/stream.h55
-rw-r--r--gnu/lib/libg++/include/streambuf.h455
-rw-r--r--gnu/lib/libg++/include/strfile.h46
-rw-r--r--gnu/lib/libg++/include/strstream.h109
-rw-r--r--gnu/lib/libg++/libg++/ACG.cc291
-rw-r--r--gnu/lib/libg++/libg++/AllocRing.cc110
-rw-r--r--gnu/lib/libg++/libg++/Binomial.cc34
-rw-r--r--gnu/lib/libg++/libg++/BitSet.cc1006
-rw-r--r--gnu/lib/libg++/libg++/BitString.cc1606
-rw-r--r--gnu/lib/libg++/libg++/Complex.cc256
-rw-r--r--gnu/lib/libg++/libg++/CursesW.cc253
-rw-r--r--gnu/lib/libg++/libg++/DLList.cc327
-rw-r--r--gnu/lib/libg++/libg++/DiscUnif.cc29
-rw-r--r--gnu/lib/libg++/libg++/Erlang.cc32
-rw-r--r--gnu/lib/libg++/libg++/Fix.cc663
-rw-r--r--gnu/lib/libg++/libg++/Fix16.cc238
-rw-r--r--gnu/lib/libg++/libg++/Fix24.cc327
-rw-r--r--gnu/lib/libg++/libg++/Geom.cc30
-rw-r--r--gnu/lib/libg++/libg++/GetOpt.cc253
-rw-r--r--gnu/lib/libg++/libg++/HypGeom.cc30
-rw-r--r--gnu/lib/libg++/libg++/Intdouble.cc142
-rw-r--r--gnu/lib/libg++/libg++/Integer.cc2280
-rw-r--r--gnu/lib/libg++/libg++/LogNorm.cc36
-rw-r--r--gnu/lib/libg++/libg++/MLCG.cc103
-rw-r--r--gnu/lib/libg++/libg++/NegExp.cc28
-rw-r--r--gnu/lib/libg++/libg++/Normal.cc60
-rw-r--r--gnu/lib/libg++/libg++/Obstack.cc125
-rw-r--r--gnu/lib/libg++/libg++/Poisson.cc36
-rw-r--r--gnu/lib/libg++/libg++/RNG.cc131
-rw-r--r--gnu/lib/libg++/libg++/Random.cc4
-rw-r--r--gnu/lib/libg++/libg++/Rational.cc414
-rw-r--r--gnu/lib/libg++/libg++/Regex.cc135
-rw-r--r--gnu/lib/libg++/libg++/RndInt.cc4
-rw-r--r--gnu/lib/libg++/libg++/SLList.cc247
-rw-r--r--gnu/lib/libg++/libg++/SmplHist.cc112
-rw-r--r--gnu/lib/libg++/libg++/SmplStat.cc160
-rw-r--r--gnu/lib/libg++/libg++/String.cc1313
-rw-r--r--gnu/lib/libg++/libg++/Uniform.cc27
-rw-r--r--gnu/lib/libg++/libg++/Weibull.cc33
-rw-r--r--gnu/lib/libg++/libg++/bitand.c41
-rw-r--r--gnu/lib/libg++/libg++/bitany.c38
-rw-r--r--gnu/lib/libg++/libg++/bitblt.c97
-rw-r--r--gnu/lib/libg++/libg++/bitclear.c37
-rw-r--r--gnu/lib/libg++/libg++/bitcopy.c41
-rw-r--r--gnu/lib/libg++/libg++/bitcount.c64
-rw-r--r--gnu/lib/libg++/libg++/bitinvert.c37
-rw-r--r--gnu/lib/libg++/libg++/bitlcomp.c92
-rw-r--r--gnu/lib/libg++/libg++/bitset1.c37
-rw-r--r--gnu/lib/libg++/libg++/bitxor.c41
-rw-r--r--gnu/lib/libg++/libg++/builtin.cc4
-rw-r--r--gnu/lib/libg++/libg++/chr.cc37
-rw-r--r--gnu/lib/libg++/libg++/compare.cc4
-rw-r--r--gnu/lib/libg++/libg++/error.cc58
-rw-r--r--gnu/lib/libg++/libg++/fmtq.cc29
-rw-r--r--gnu/lib/libg++/libg++/gcd.cc52
-rw-r--r--gnu/lib/libg++/libg++/hash.cc56
-rw-r--r--gnu/lib/libg++/libg++/ioob.cc32
-rw-r--r--gnu/lib/libg++/libg++/lg.cc32
-rw-r--r--gnu/lib/libg++/libg++/math.cc4
-rw-r--r--gnu/lib/libg++/libg++/new.cc31
-rw-r--r--gnu/lib/libg++/libg++/pow.cc70
-rw-r--r--gnu/lib/libg++/libg++/regex.cc2757
-rw-r--r--gnu/lib/libg++/libg++/sqrt.cc43
-rw-r--r--gnu/lib/libg++/libg++/str.cc38
-rw-r--r--gnu/lib/libg++/libg++/timer.c135
-rw-r--r--gnu/lib/libg++/libiberty/strerror.c823
-rw-r--r--gnu/lib/libg++/libiberty/strsignal.c643
-rw-r--r--gnu/lib/libg++/libiberty/vasprintf.c139
-rw-r--r--gnu/lib/libg++/libio/PlotFile.cc157
-rw-r--r--gnu/lib/libg++/libio/SFile.cc82
-rw-r--r--gnu/lib/libg++/libio/builtinbuf.cc96
-rw-r--r--gnu/lib/libg++/libio/cleanup.c14
-rw-r--r--gnu/lib/libg++/libio/editbuf.cc717
-rw-r--r--gnu/lib/libg++/libio/filebuf.cc199
-rw-r--r--gnu/lib/libg++/libio/filedoalloc.c103
-rw-r--r--gnu/lib/libg++/libio/fileops.c735
-rw-r--r--gnu/lib/libg++/libio/floatconv.c2357
-rw-r--r--gnu/lib/libg++/libio/fstream.cc84
-rw-r--r--gnu/lib/libg++/libio/genops.c867
-rw-r--r--gnu/lib/libg++/libio/indstream.cc116
-rw-r--r--gnu/lib/libg++/libio/ioextend.cc129
-rw-r--r--gnu/lib/libg++/libio/iofclose.c47
-rw-r--r--gnu/lib/libg++/libio/iofgetpos.c47
-rw-r--r--gnu/lib/libg++/libio/iofread.c41
-rw-r--r--gnu/lib/libg++/libio/iofscanf.c48
-rw-r--r--gnu/lib/libg++/libio/iofsetpos.c44
-rw-r--r--gnu/lib/libg++/libio/iogetline.c77
-rw-r--r--gnu/lib/libg++/libio/ioignore.c47
-rw-r--r--gnu/lib/libg++/libio/iomanip.cc90
-rw-r--r--gnu/lib/libg++/libio/iopadn.c67
-rw-r--r--gnu/lib/libg++/libio/iopopen.c221
-rw-r--r--gnu/lib/libg++/libio/ioprims.c79
-rw-r--r--gnu/lib/libg++/libio/ioprintf.c47
-rw-r--r--gnu/lib/libg++/libio/ioseekoff.c47
-rw-r--r--gnu/lib/libg++/libio/ioseekpos.c41
-rw-r--r--gnu/lib/libg++/libio/iostream.cc813
-rw-r--r--gnu/lib/libg++/libio/iostrerror.c11
-rw-r--r--gnu/lib/libg++/libio/ioungetc.c36
-rw-r--r--gnu/lib/libg++/libio/iovfprintf.c885
-rw-r--r--gnu/lib/libg++/libio/iovfscanf.c784
-rw-r--r--gnu/lib/libg++/libio/isgetline.cc140
-rw-r--r--gnu/lib/libg++/libio/isgetsb.cc59
-rw-r--r--gnu/lib/libg++/libio/isscan.cc45
-rw-r--r--gnu/lib/libg++/libio/osform.cc54
-rw-r--r--gnu/lib/libg++/libio/outfloat.c209
-rw-r--r--gnu/lib/libg++/libio/parsestream.cc317
-rw-r--r--gnu/lib/libg++/libio/pfstream.cc92
-rw-r--r--gnu/lib/libg++/libio/procbuf.cc51
-rw-r--r--gnu/lib/libg++/libio/sbform.cc40
-rw-r--r--gnu/lib/libg++/libio/sbgetline.cc31
-rw-r--r--gnu/lib/libg++/libio/sbscan.cc45
-rw-r--r--gnu/lib/libg++/libio/stdiostream.cc146
-rw-r--r--gnu/lib/libg++/libio/stdstrbufs.cc89
-rw-r--r--gnu/lib/libg++/libio/stdstreams.cc143
-rw-r--r--gnu/lib/libg++/libio/stream.cc144
-rw-r--r--gnu/lib/libg++/libio/streambuf.cc341
-rw-r--r--gnu/lib/libg++/libio/strops.c292
-rw-r--r--gnu/lib/libg++/libio/strstream.cc133
185 files changed, 40372 insertions, 0 deletions
diff --git a/gnu/lib/libg++/Makefile b/gnu/lib/libg++/Makefile
new file mode 100644
index 0000000..519c317
--- /dev/null
+++ b/gnu/lib/libg++/Makefile
@@ -0,0 +1,18 @@
+#
+# $FreeBSD$
+#
+
+SRCS= vasprintf.c strerror.c strsignal.c
+SRCS+= filedoalloc.c floatconv.c genops.c fileops.c iovfprintf.c iovfscanf.c ioignore.c iopadn.c iofgetpos.c iofread.c iofscanf.c iofsetpos.c iogetline.c ioprintf.c ioseekoff.c ioseekpos.c outfloat.c strops.c iofclose.c iopopen.c ioungetc.c builtinbuf.cc filebuf.cc fstream.cc indstream.cc isgetline.cc isgetsb.cc isscan.cc ioextend.cc iomanip.cc iostream.cc osform.cc procbuf.cc sbform.cc sbgetline.cc sbscan.cc stdiostream.cc stdstrbufs.cc stdstreams.cc stream.cc streambuf.cc strstream.cc PlotFile.cc SFile.cc parsestream.cc pfstream.cc editbuf.cc ioprims.c iostrerror.c cleanup.c
+SRCS+= AllocRing.cc Obstack.cc builtin.cc regex.cc Regex.cc String.cc Intdouble.cc Integer.cc Rational.cc Complex.cc Random.cc BitSet.cc BitString.cc LogNorm.cc SmplHist.cc SmplStat.cc Normal.cc NegExp.cc Weibull.cc Erlang.cc DiscUnif.cc Uniform.cc Poisson.cc HypGeom.cc Geom.cc Binomial.cc RNG.cc ACG.cc MLCG.cc RndInt.cc Fix.cc Fix16.cc Fix24.cc CursesW.cc GetOpt.cc new.cc chr.cc error.cc gcd.cc hash.cc lg.cc fmtq.cc ioob.cc pow.cc sqrt.cc str.cc timer.c math.cc compare.cc bitand.c bitany.c bitblt.c bitclear.c bitcopy.c bitcount.c bitinvert.c bitlcomp.c bitset1.c bitxor.c SLList.cc DLList.cc
+LIB= libg++
+NOMAN= noman
+CFLAGS+= -nostdinc -I${.CURDIR}/include -I/usr/include
+CXXFLAGS+= -fexternal-templates
+.PATH: ${.CURDIR}/libiberty ${.CURDIR}/libio ${.CURDIR}/libg++
+
+beforeinstall:
+ @-if [ ! -d ${DESTDIR}/usr/include/g++ ]; then mkdir ${DESTDIR}/usr/include/g++; chown ${BINOWN}.${BINGRP} ${DESTDIR}/usr/include/g++; chmod 755 ${DESTDIR}/usr/include/g++; fi
+ @(cd include ; for j in *.h; do cmp -s $$j ${DESTDIR}/usr/include/g++/$$j || install -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j ${DESTDIR}/usr/include/$$j; done)
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libg++/include/ACG.h b/gnu/lib/libg++/include/ACG.h
new file mode 100644
index 0000000..d7101c7
--- /dev/null
+++ b/gnu/lib/libg++/include/ACG.h
@@ -0,0 +1,68 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _ACG_h
+#define _ACG_h 1
+
+#include <RNG.h>
+#include <math.h>
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+//
+// Additive number generator. This method is presented in Volume II
+// of The Art of Computer Programming by Knuth. I've coded the algorithm
+// and have added the extensions by Andres Nowatzyk of CMU to randomize
+// the result of algorithm M a bit by using an LCG & a spatial
+// permutation table.
+//
+// The version presented uses the same constants for the LCG that Andres
+// uses (chosen by trial & error). The spatial permutation table is
+// the same size (it's based on word size). This is for 32-bit words.
+//
+// The ``auxillary table'' used by the LCG table varies in size, and
+// is chosen to be the the smallest power of two which is larger than
+// twice the size of the state table.
+//
+
+class ACG : public RNG {
+
+ unsigned long initialSeed; // used to reset generator
+ int initialTableEntry;
+
+ unsigned long *state;
+ unsigned long *auxState;
+ short stateSize;
+ short auxSize;
+ unsigned long lcgRecurr;
+ short j;
+ short k;
+
+protected:
+
+public:
+ ACG(unsigned long seed = 0, int size = 55);
+ virtual ~ACG();
+ //
+ // Return a long-words word of random bits
+ //
+ virtual unsigned long asLong();
+ virtual void reset();
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/AllocRing.h b/gnu/lib/libg++/include/AllocRing.h
new file mode 100644
index 0000000..15dd161
--- /dev/null
+++ b/gnu/lib/libg++/include/AllocRing.h
@@ -0,0 +1,62 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef _AllocRing_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _AllocRing_h 1
+
+
+/*
+ An AllocRing holds the last n malloc'ed strings, reallocating/reusing
+ one only when the queue wraps around. It thus guarantees that the
+ last n allocations are intact. It is useful for things like I/O
+ formatting where reasonable restrictions may be made about the
+ number of allowable live allocations before auto-deletion.
+*/
+
+class AllocRing
+{
+
+ struct AllocQNode
+ {
+ void* ptr;
+ int sz;
+ };
+
+ AllocQNode* nodes;
+ int n;
+ int current;
+
+ int find(void* p);
+
+public:
+
+ AllocRing(int max);
+ ~AllocRing();
+
+ void* alloc(int size);
+ int contains(void* ptr);
+ void clear();
+ void free(void* p);
+};
+
+
+#endif
diff --git a/gnu/lib/libg++/include/Binomial.h b/gnu/lib/libg++/include/Binomial.h
new file mode 100644
index 0000000..f88dfc3
--- /dev/null
+++ b/gnu/lib/libg++/include/Binomial.h
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Binomial_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Binomial_h 1
+
+#include <Random.h>
+
+class Binomial: public Random {
+protected:
+ int pN;
+ double pU;
+public:
+ Binomial(int n, double u, RNG *gen);
+
+ int n();
+ int n(int xn);
+
+ double u();
+ double u(int xu);
+
+ virtual double operator()();
+
+};
+
+
+inline Binomial::Binomial(int n, double u, RNG *gen)
+: Random(gen){
+ pN = n; pU = u;
+}
+
+inline int Binomial::n() { return pN; }
+inline int Binomial::n(int xn) { int tmp = pN; pN = xn; return tmp; }
+
+inline double Binomial::u() { return pU; }
+inline double Binomial::u(int xu) { double tmp = pU; pU = xu; return tmp; }
+
+#endif
diff --git a/gnu/lib/libg++/include/BitSet.h b/gnu/lib/libg++/include/BitSet.h
new file mode 100644
index 0000000..ca1d96f
--- /dev/null
+++ b/gnu/lib/libg++/include/BitSet.h
@@ -0,0 +1,374 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _BitSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#define _BitSet_h 1
+
+#include <iostream.h>
+#include <limits.h>
+
+#define BITSETBITS (sizeof(short) * CHAR_BIT)
+
+struct BitSetRep
+{
+ unsigned short len; // number of shorts in s
+ unsigned short sz; // allocated slots
+ unsigned short virt; // virtual 0 or 1
+ unsigned short s[1]; // bits start here
+};
+
+extern BitSetRep* BitSetalloc(BitSetRep*, const unsigned short*,
+ int, int, int);
+extern BitSetRep* BitSetcopy(BitSetRep*, const BitSetRep*);
+extern BitSetRep* BitSetresize(BitSetRep*, int);
+extern BitSetRep* BitSetop(const BitSetRep*, const BitSetRep*,
+ BitSetRep*, char);
+extern BitSetRep* BitSetcmpl(const BitSetRep*, BitSetRep*);
+
+
+extern BitSetRep _nilBitSetRep;
+
+class BitSet;
+
+class BitSetBit
+{
+protected:
+ BitSet* src;
+ unsigned long pos;
+
+ public:
+ BitSetBit(BitSet* v, int p);
+ BitSetBit(const BitSetBit& b);
+ ~BitSetBit();
+ operator int() const;
+ int operator = (int b);
+ int operator = (const BitSetBit& b);
+};
+
+class BitSet
+{
+protected:
+ BitSetRep* rep;
+
+
+public:
+
+// constructors
+ BitSet();
+ BitSet(const BitSet&);
+
+ ~BitSet();
+
+ BitSet& operator = (const BitSet& y);
+
+// equality & subset tests
+
+ friend int operator == (const BitSet& x, const BitSet& y);
+ friend int operator != (const BitSet& x, const BitSet& y);
+ friend int operator < (const BitSet& x, const BitSet& y);
+ friend int operator <= (const BitSet& x, const BitSet& y);
+ friend int operator > (const BitSet& x, const BitSet& y);
+ friend int operator >= (const BitSet& x, const BitSet& y);
+
+
+// operations on self
+
+ BitSet& operator |= (const BitSet& y);
+ BitSet& operator &= (const BitSet& y);
+ BitSet& operator -= (const BitSet& y);
+ BitSet& operator ^= (const BitSet& y);
+
+ void complement();
+
+// individual bit manipulation
+
+ void set(int pos);
+ void set(int from, int to);
+ void set(); // set all
+
+ void clear(int pos);
+ void clear(int from, int to);
+ void clear(); // clear all
+
+ void invert(int pos);
+ void invert(int from, int to);
+
+ int test(int pos) const;
+ int test(int from, int to) const;
+
+ BitSetBit operator [] (int i);
+
+// iterators
+
+ int first(int b = 1) const;
+ int last(int b = 1) const;
+
+ int next(int pos, int b = 1) const;
+ int prev(int pos, int b = 1) const;
+ int previous(int pos, int b = 1) const /* Obsolete synonym */
+ { return prev(pos, b); }
+
+// status
+
+ int empty() const;
+ int virtual_bit() const;
+ int count(int b = 1) const;
+
+// convertors & IO
+
+ friend BitSet atoBitSet(const char* s,
+ char f='0', char t='1', char star='*');
+ // BitSettoa is deprecated; do not use in new programs.
+ friend const char* BitSettoa(const BitSet& x,
+ char f='0', char t='1', char star='*');
+
+ friend BitSet shorttoBitSet(unsigned short w);
+ friend BitSet longtoBitSet(unsigned long w);
+
+ friend ostream& operator << (ostream& s, const BitSet& x);
+ void printon(ostream& s,
+ char f='0', char t='1', char star='*') const;
+
+// procedural versions of operators
+
+ friend void and(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void or(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void xor(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void diff(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void complement(const BitSet& x, BitSet& r);
+
+// misc
+
+ void error(const char* msg) const;
+ int OK() const;
+};
+
+
+typedef BitSet BitSetTmp;
+
+
+ BitSet operator | (const BitSet& x, const BitSet& y);
+ BitSet operator & (const BitSet& x, const BitSet& y);
+ BitSet operator - (const BitSet& x, const BitSet& y);
+ BitSet operator ^ (const BitSet& x, const BitSet& y);
+
+ BitSet operator ~ (const BitSet& x);
+
+// These are inlined regardless of optimization
+
+inline int BitSet_index(int l)
+{
+ return (unsigned)(l) / BITSETBITS;
+}
+
+inline int BitSet_pos(int l)
+{
+ return l & (BITSETBITS - 1);
+}
+
+
+inline BitSet::BitSet() : rep(&_nilBitSetRep) {}
+
+inline BitSet::BitSet(const BitSet& x) :rep(BitSetcopy(0, x.rep)) {}
+
+inline BitSet::~BitSet() { if (rep != &_nilBitSetRep) delete rep; }
+
+inline BitSet& BitSet::operator = (const BitSet& y)
+{
+ rep = BitSetcopy(rep, y.rep);
+ return *this;
+}
+
+inline int operator != (const BitSet& x, const BitSet& y) { return !(x == y); }
+
+inline int operator > (const BitSet& x, const BitSet& y) { return y < x; }
+
+inline int operator >= (const BitSet& x, const BitSet& y) { return y <= x; }
+
+inline void and(const BitSet& x, const BitSet& y, BitSet& r)
+{
+ r.rep = BitSetop(x.rep, y.rep, r.rep, '&');
+}
+
+inline void or(const BitSet& x, const BitSet& y, BitSet& r)
+{
+ r.rep = BitSetop(x.rep, y.rep, r.rep, '|');
+}
+
+inline void xor(const BitSet& x, const BitSet& y, BitSet& r)
+{
+ r.rep = BitSetop(x.rep, y.rep, r.rep, '^');
+}
+
+inline void diff(const BitSet& x, const BitSet& y, BitSet& r)
+{
+ r.rep = BitSetop(x.rep, y.rep, r.rep, '-');
+}
+
+inline void complement(const BitSet& x, BitSet& r)
+{
+ r.rep = BitSetcmpl(x.rep, r.rep);
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+inline BitSet operator & (const BitSet& x, const BitSet& y) return r
+{
+ and(x, y, r);
+}
+
+inline BitSet operator | (const BitSet& x, const BitSet& y) return r
+{
+ or(x, y, r);
+}
+
+inline BitSet operator ^ (const BitSet& x, const BitSet& y) return r
+{
+ xor(x, y, r);
+}
+
+inline BitSet operator - (const BitSet& x, const BitSet& y) return r
+{
+ diff(x, y, r);
+}
+
+inline BitSet operator ~ (const BitSet& x) return r
+{
+ ::complement(x, r);
+}
+
+#else /* NO_NRV */
+
+inline BitSet operator & (const BitSet& x, const BitSet& y)
+{
+ BitSet r; and(x, y, r); return r;
+}
+
+inline BitSet operator | (const BitSet& x, const BitSet& y)
+{
+ BitSet r; or(x, y, r); return r;
+}
+
+inline BitSet operator ^ (const BitSet& x, const BitSet& y)
+{
+ BitSet r; xor(x, y, r); return r;
+}
+
+inline BitSet operator - (const BitSet& x, const BitSet& y)
+{
+ BitSet r; diff(x, y, r); return r;
+}
+
+inline BitSet operator ~ (const BitSet& x)
+{
+ BitSet r; ::complement(x, r); return r;
+}
+
+#endif
+
+inline BitSet& BitSet::operator &= (const BitSet& y)
+{
+ and(*this, y, *this);
+ return *this;
+}
+
+inline BitSet& BitSet::operator |= (const BitSet& y)
+{
+ or(*this, y, *this);
+ return *this;
+}
+
+inline BitSet& BitSet::operator ^= (const BitSet& y)
+{
+ xor(*this, y, *this);
+ return *this;
+}
+
+inline BitSet& BitSet::operator -= (const BitSet& y)
+{
+ diff(*this, y, *this);
+ return *this;
+}
+
+
+inline void BitSet::complement()
+{
+ ::complement(*this, *this);
+}
+
+inline int BitSet::virtual_bit() const
+{
+ return rep->virt;
+}
+
+inline int BitSet::first(int b) const
+{
+ return next(-1, b);
+}
+
+inline int BitSet::test(int p) const
+{
+ if (p < 0) error("Illegal bit index");
+ int index = BitSet_index(p);
+ return (index >= rep->len)? rep->virt :
+ ((rep->s[index] & (1 << BitSet_pos(p))) != 0);
+}
+
+
+inline void BitSet::set()
+{
+ rep = BitSetalloc(rep, 0, 0, 1, 0);
+}
+
+inline BitSetBit::BitSetBit(const BitSetBit& b) :src(b.src), pos(b.pos) {}
+
+inline BitSetBit::BitSetBit(BitSet* v, int p)
+{
+ src = v; pos = p;
+}
+
+inline BitSetBit::~BitSetBit() {}
+
+inline BitSetBit::operator int() const
+{
+ return src->test(pos);
+}
+
+inline int BitSetBit::operator = (int b)
+{
+ if (b) src->set(pos); else src->clear(pos); return b;
+}
+
+inline int BitSetBit::operator = (const BitSetBit& b)
+{
+ int i = (int)b;
+ *this = i;
+ return i;
+}
+
+inline BitSetBit BitSet::operator [] (int i)
+{
+ if (i < 0) error("illegal bit index");
+ return BitSetBit(this, i);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/BitString.h b/gnu/lib/libg++/include/BitString.h
new file mode 100644
index 0000000..b2b92b1
--- /dev/null
+++ b/gnu/lib/libg++/include/BitString.h
@@ -0,0 +1,761 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _BitString_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#define _BitString_h 1
+
+#include <stream.h>
+#include <limits.h>
+
+#include <bitprims.h>
+#define BITSTRBITS _BS_BITS_PER_WORD
+
+struct BitStrRep
+{
+ unsigned int len; // length in bits
+ unsigned short sz; // allocated slots
+ _BS_word s[1]; // bits start here
+};
+
+extern BitStrRep* BStr_alloc(BitStrRep*, const _BS_word*, int, int,int);
+extern BitStrRep* BStr_resize(BitStrRep*, int);
+extern BitStrRep* BStr_copy(BitStrRep*, const BitStrRep*);
+extern BitStrRep* cmpl(const BitStrRep*, BitStrRep*);
+extern BitStrRep* and(const BitStrRep*, const BitStrRep*, BitStrRep*);
+extern BitStrRep* or(const BitStrRep*, const BitStrRep*, BitStrRep*);
+extern BitStrRep* xor(const BitStrRep*, const BitStrRep*, BitStrRep*);
+extern BitStrRep* diff(const BitStrRep*, const BitStrRep*, BitStrRep*);
+extern BitStrRep* cat(const BitStrRep*, const BitStrRep*, BitStrRep*);
+extern BitStrRep* cat(const BitStrRep*, unsigned int, BitStrRep*);
+extern BitStrRep* lshift(const BitStrRep*, int, BitStrRep*);
+
+
+class BitString;
+class BitPattern;
+
+class BitStrBit
+{
+protected:
+ BitString& src;
+ unsigned int pos;
+
+ public:
+ BitStrBit(BitString& v, int p);
+ BitStrBit(const BitStrBit& b);
+ ~BitStrBit();
+ operator unsigned int() const;
+ int operator = (unsigned int b);
+};
+
+class BitSubString
+{
+ friend class BitString;
+ friend class BitPattern;
+
+protected:
+
+ BitString& S;
+ unsigned int pos;
+ unsigned int len;
+
+ BitSubString(BitString& x, int p, int l);
+ BitSubString(const BitSubString& x);
+public:
+ ~BitSubString();
+
+ BitSubString& operator = (const BitString&);
+ BitSubString& operator = (const BitSubString&);
+
+ int length() const;
+ int empty() const;
+
+ int OK() const;
+};
+
+class BitString
+{
+ friend class BitSubString;
+ friend class BitPattern;
+protected:
+ BitStrRep* rep;
+
+ int search(int, int, const _BS_word*, int, int) const;
+ int match(int, int, int, const _BS_word*,int,int) const;
+ BitSubString _substr(int first, int l);
+
+public:
+
+// constructors
+ BitString();
+ BitString(const BitString&);
+ BitString(const BitSubString& y);
+
+ ~BitString();
+
+ BitString& operator = (unsigned int bit);
+ BitString& operator = (const BitString& y);
+ BitString& operator = (const BitSubString& y);
+
+// equality & subset tests
+
+ friend int operator == (const BitString&, const BitString&);
+ friend int operator != (const BitString&, const BitString&);
+ friend int operator < (const BitString&, const BitString&);
+ friend int operator <= (const BitString&, const BitString&);
+ friend int operator > (const BitString&, const BitString&);
+ friend int operator >= (const BitString&, const BitString&);
+
+// procedural versions of operators
+
+
+ friend void and(const BitString&, const BitString&, BitString&);
+ friend void or(const BitString&, const BitString&, BitString&);
+ friend void xor(const BitString&, const BitString&, BitString&);
+ friend void diff(const BitString&, const BitString&, BitString&);
+ friend void cat(const BitString&, const BitString&, BitString&);
+ friend void cat(const BitString&, unsigned int, BitString&);
+ friend void lshift(const BitString&, int, BitString&);
+ friend void rshift(const BitString&, int, BitString&);
+
+ friend void complement(const BitString&, BitString&);
+
+ friend int lcompare(const BitString&, const BitString&);
+
+// assignment-based operators
+// (constuctive versions decalred inline below
+
+ BitString& operator |= (const BitString&);
+ BitString& operator &= (const BitString&);
+ BitString& operator -= (const BitString&);
+ BitString& operator ^= (const BitString&);
+ BitString& operator += (const BitString&);
+ BitString& operator += (unsigned int b);
+ BitString& operator <<=(int s);
+ BitString& operator >>=(int s);
+
+ void complement();
+
+// individual bit manipulation
+
+ void set(int pos);
+ void set(int from, int to);
+ void set();
+
+ void clear(int pos);
+ void clear(int from, int to);
+ void clear();
+
+ void invert(int pos);
+ void invert(int from, int to);
+
+ int test(int pos) const;
+ int test(int from, int to) const;
+
+ void assign(int p, unsigned int bit);
+
+// indexing
+
+ BitStrBit operator [] (int pos);
+
+// iterators
+
+ int first(unsigned int bit = 1) const;
+ int last(unsigned int b = 1) const;
+
+ int next(int pos, unsigned int b = 1) const;
+ int prev(int pos, unsigned int b = 1) const;
+ int previous(int pos, unsigned int b = 1) const
+ { return prev(pos, b); } /* Obsolete synonym */
+
+// searching & matching
+
+ int index(unsigned int bit, int startpos = 0) const ;
+ int index(const BitString&, int startpos = 0) const;
+ int index(const BitSubString&, int startpos = 0) const;
+ int index(const BitPattern&, int startpos = 0) const;
+
+ int contains(const BitString&) const;
+ int contains(const BitSubString&) const;
+ int contains(const BitPattern&) const;
+
+ int contains(const BitString&, int pos) const;
+ int contains(const BitSubString&, int pos) const;
+ int contains(const BitPattern&, int pos) const;
+
+ int matches(const BitString&, int pos = 0) const;
+ int matches(const BitSubString&, int pos = 0) const;
+ int matches(const BitPattern&, int pos = 0) const;
+
+// BitSubString extraction
+
+ BitSubString at(int pos, int len);
+ BitSubString at(const BitString&, int startpos = 0);
+ BitSubString at(const BitSubString&, int startpos = 0);
+ BitSubString at(const BitPattern&, int startpos = 0);
+
+ BitSubString before(int pos);
+ BitSubString before(const BitString&, int startpos = 0);
+ BitSubString before(const BitSubString&, int startpos = 0);
+ BitSubString before(const BitPattern&, int startpos = 0);
+
+ BitSubString after(int pos);
+ BitSubString after(const BitString&, int startpos = 0);
+ BitSubString after(const BitSubString&, int startpos = 0);
+ BitSubString after(const BitPattern&, int startpos = 0);
+
+// other friends & utilities
+
+ friend BitString common_prefix(const BitString&, const BitString&,
+ int pos = 0);
+ friend BitString common_suffix(const BitString&, const BitString&,
+ int pos = -1);
+ friend BitString reverse(const BitString&);
+
+ void right_trim(unsigned int bit);
+ void left_trim(unsigned int bit);
+
+// status
+
+ int empty() const ;
+ int count(unsigned int bit = 1) const;
+ int length() const;
+
+// convertors & IO
+
+ friend BitString atoBitString(const char* s, char f='0', char t='1');
+ // BitStringtoa is deprecated; do not use in new programs!
+ friend const char* BitStringtoa(const BitString&, char f='0', char t='1');
+ void printon(ostream&, char f='0', char t='1') const;
+
+ friend BitString shorttoBitString(unsigned short);
+ friend BitString longtoBitString(unsigned long);
+
+ friend ostream& operator << (ostream& s, const BitString&);
+
+// misc
+
+ void error(const char* msg) const;
+
+// indirect friends
+
+ friend BitPattern atoBitPattern(const char* s,
+ char f='0',char t='1',char x='X');
+ friend const char* BitPatterntoa(const BitPattern& p,
+ char f='0',char t='1',char x='X');
+ int OK() const;
+};
+
+
+class BitPattern
+{
+public:
+ BitString pattern;
+ BitString mask;
+
+ BitPattern();
+ BitPattern(const BitPattern&);
+ BitPattern(const BitString& p, const BitString& m);
+
+ ~BitPattern();
+
+ friend const char* BitPatterntoa(const BitPattern& p,
+ char f/*='0'*/,char t/*='1'*/,char x/*='X'*/);
+ void printon(ostream&, char f='0',char t='1',char x='X') const;
+ friend BitPattern atoBitPattern(const char* s, char f,char t, char x);
+ friend ostream& operator << (ostream& s, const BitPattern&);
+
+ int search(const _BS_word*, int, int) const;
+ int match(const _BS_word* xs, int, int, int) const;
+
+ int OK() const;
+};
+
+BitString operator & (const BitString& x, const BitString& y);
+BitString operator | (const BitString& x, const BitString& y);
+BitString operator ^ (const BitString& x, const BitString& y);
+BitString operator << (const BitString& x, int y);
+BitString operator >> (const BitString& x, int y);
+BitString operator - (const BitString& x, const BitString& y);
+BitString operator + (const BitString& x, const BitString& y);
+BitString operator + (const BitString& x, unsigned int y);
+BitString operator ~ (const BitString& x);
+int operator != (const BitString& x, const BitString& y);
+int operator>(const BitString& x, const BitString& y);
+int operator>=(const BitString& x, const BitString& y);
+
+extern BitStrRep _nilBitStrRep;
+extern BitString _nil_BitString;
+
+// primitive bit extraction
+
+// These must be inlined regardless of optimization.
+
+inline int BitStr_index(int l) { return (unsigned)(l) / BITSTRBITS; }
+
+inline int BitStr_pos(int l) { return l & (BITSTRBITS - 1); }
+
+
+// constructors & assignment
+
+inline BitString::BitString() :rep(&_nilBitStrRep) {}
+
+inline BitString::BitString(const BitString& x) :rep(BStr_copy(0, x.rep)) {}
+
+inline BitString::BitString(const BitSubString& y)
+ :rep (BStr_alloc(0, y.S.rep->s, y.pos, y.pos+y.len, y.len)) {}
+
+inline BitString::~BitString()
+{
+ if (rep != &_nilBitStrRep) delete rep;
+}
+
+inline BitString shorttoBitString(unsigned short w)
+{
+ BitString r;
+ _BS_word ww = w;
+#if _BS_BIGENDIAN
+ abort();
+#endif
+ r.rep = BStr_alloc(0, &ww, 0, 8 * sizeof(short), 8 * sizeof(short));
+ return r;
+}
+
+inline BitString longtoBitString(unsigned long w)
+{
+ BitString r;
+#if 1
+ _BS_word u = w;
+ r.rep = BStr_alloc(0, &u, 0, BITSTRBITS, BITSTRBITS);
+#else
+ unsigned short u[2];
+ u[0] = w & ((unsigned short)(~(0)));
+ u[1] = w >> BITSTRBITS;
+ r.rep = BStr_alloc(0, &u[0], 0, 2*BITSTRBITS, 2*BITSTRBITS);
+#endif
+ return r;
+}
+
+inline BitString& BitString::operator = (const BitString& y)
+{
+ rep = BStr_copy(rep, y.rep);
+ return *this;
+}
+
+inline BitString& BitString::operator = (unsigned int b)
+{
+ _BS_word bit = b;
+ rep = BStr_alloc(rep, &bit, 0, 1, 1);
+ return *this;
+}
+
+inline BitString& BitString::operator=(const BitSubString& y)
+{
+ rep = BStr_alloc(rep, y.S.rep->s, y.pos, y.pos+y.len, y.len);
+ return *this;
+}
+
+inline BitSubString::BitSubString(const BitSubString& x)
+ :S(x.S), pos(x.pos), len(x.len) {}
+
+inline BitSubString::BitSubString(BitString& x, int p, int l)
+ : S(x), pos(p), len(l) {}
+
+inline BitSubString::~BitSubString() {}
+
+inline BitPattern::BitPattern(const BitString& p, const BitString& m)
+ :pattern(p), mask(m) {}
+
+inline BitPattern::BitPattern(const BitPattern& b)
+ :pattern(b.pattern), mask(b.mask) {}
+
+inline BitPattern::BitPattern() {}
+inline BitPattern::~BitPattern() {}
+
+
+// procedural versions of operators
+
+inline void and(const BitString& x, const BitString& y, BitString& r)
+{
+ r.rep = and(x.rep, y.rep, r.rep);
+}
+
+inline void or(const BitString& x, const BitString& y, BitString& r)
+{
+ r.rep = or(x.rep, y.rep, r.rep);
+}
+
+inline void xor(const BitString& x, const BitString& y, BitString& r)
+{
+ r.rep = xor(x.rep, y.rep, r.rep);
+}
+
+inline void diff(const BitString& x, const BitString& y, BitString& r)
+{
+ r.rep = diff(x.rep, y.rep, r.rep);
+}
+
+inline void cat(const BitString& x, const BitString& y, BitString& r)
+{
+ r.rep = cat(x.rep, y.rep, r.rep);
+}
+
+inline void cat(const BitString& x, unsigned int y, BitString& r)
+{
+ r.rep = cat(x.rep, y, r.rep);
+}
+
+inline void rshift(const BitString& x, int y, BitString& r)
+{
+ r.rep = lshift(x.rep, -y, r.rep);
+}
+
+inline void lshift(const BitString& x, int y, BitString& r)
+{
+ r.rep = lshift(x.rep, y, r.rep);
+}
+
+inline void complement(const BitString& x, BitString& r)
+{
+ r.rep = cmpl(x.rep, r.rep);
+}
+
+// operators
+
+
+inline BitString& BitString::operator &= (const BitString& y)
+{
+ and(*this, y, *this);
+ return *this;
+}
+
+
+inline BitString& BitString::operator |= (const BitString& y)
+{
+ or(*this, y, *this);
+ return *this;
+}
+
+inline BitString& BitString::operator ^= (const BitString& y)
+{
+ xor(*this, y, *this);
+ return *this;
+}
+
+inline BitString& BitString::operator <<= (int y)
+{
+ lshift(*this, y, *this);
+ return *this;
+}
+
+inline BitString& BitString::operator >>= (int y)
+{
+ rshift(*this, y, *this);
+ return *this;
+}
+
+inline BitString& BitString::operator -= (const BitString& y)
+{
+ diff(*this, y, *this);
+ return *this;
+}
+
+inline BitString& BitString::operator += (const BitString& y)
+{
+ cat(*this, y, *this);
+ return *this;
+}
+
+inline BitString& BitString::operator += (unsigned int y)
+{
+ cat(*this, y, *this);
+ return *this;
+}
+
+inline void BitString::complement()
+{
+ ::complement(*this, *this);
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+inline BitString operator & (const BitString& x, const BitString& y) return r
+{
+ and(x, y, r);
+}
+
+inline BitString operator | (const BitString& x, const BitString& y) return r
+{
+ or(x, y, r);
+}
+
+inline BitString operator ^ (const BitString& x, const BitString& y) return r
+{
+ xor(x, y, r);
+}
+
+inline BitString operator << (const BitString& x, int y) return r
+{
+ lshift(x, y, r);
+}
+
+inline BitString operator >> (const BitString& x, int y) return r
+{
+ rshift(x, y, r);
+}
+
+inline BitString operator - (const BitString& x, const BitString& y) return r
+{
+ diff(x, y, r);
+}
+
+inline BitString operator + (const BitString& x, const BitString& y) return r
+{
+ cat(x, y, r);
+}
+
+inline BitString operator + (const BitString& x, unsigned int y) return r
+{
+ cat(x, y, r);
+}
+
+inline BitString operator ~ (const BitString& x) return r
+{
+ complement(x, r);
+}
+
+#else /* NO_NRV */
+
+inline BitString operator & (const BitString& x, const BitString& y)
+{
+ BitString r; and(x, y, r); return r;
+}
+
+inline BitString operator | (const BitString& x, const BitString& y)
+{
+ BitString r; or(x, y, r); return r;
+}
+
+inline BitString operator ^ (const BitString& x, const BitString& y)
+{
+ BitString r; xor(x, y, r); return r;
+}
+
+inline BitString operator << (const BitString& x, int y)
+{
+ BitString r; lshift(x, y, r); return r;
+}
+
+inline BitString operator >> (const BitString& x, int y)
+{
+ BitString r; rshift(x, y, r); return r;
+}
+
+inline BitString operator - (const BitString& x, const BitString& y)
+{
+ BitString r; diff(x, y, r); return r;
+}
+
+inline BitString operator + (const BitString& x, const BitString& y)
+{
+ BitString r; cat(x, y, r); return r;
+}
+
+inline BitString operator + (const BitString& x, unsigned int y)
+{
+ BitString r; cat(x, y, r); return r;
+}
+
+inline BitString operator ~ (const BitString& x)
+{
+ BitString r; complement(x, r); return r;
+}
+
+#endif
+
+// status, matching
+
+inline int BitString::length() const
+{
+ return rep->len;
+}
+
+inline int BitString::empty() const
+{
+ return rep->len == 0;
+}
+
+inline int BitString::index(const BitString& y, int startpos) const
+{
+ return search(startpos, rep->len, y.rep->s, 0, y.rep->len);
+}
+
+inline int BitString::index(const BitSubString& y, int startpos) const
+{
+ return search(startpos, rep->len, y.S.rep->s, y.pos, y.pos+y.len);
+}
+
+inline int BitString::contains(const BitString& y) const
+{
+ return search(0, rep->len, y.rep->s, 0, y.rep->len) >= 0;
+}
+
+inline int BitString::contains(const BitSubString& y) const
+{
+ return search(0, rep->len, y.S.rep->s, y.pos, y.pos+y.len) >= 0;
+}
+
+inline int BitString::contains(const BitString& y, int p) const
+{
+ return match(p, rep->len, 0, y.rep->s, 0, y.rep->len);
+}
+
+inline int BitString::matches(const BitString& y, int p) const
+{
+ return match(p, rep->len, 1, y.rep->s, 0, y.rep->len);
+}
+
+inline int BitString::contains(const BitSubString& y, int p) const
+{
+ return match(p, rep->len, 0, y.S.rep->s, y.pos, y.pos+y.len);
+}
+
+inline int BitString::matches(const BitSubString& y, int p) const
+{
+ return match(p, rep->len, 1, y.S.rep->s, y.pos, y.pos+y.len);
+}
+
+inline int BitString::contains(const BitPattern& r) const
+{
+ return r.search(rep->s, 0, rep->len) >= 0;
+}
+
+inline int BitString::contains(const BitPattern& r, int p) const
+{
+ return r.match(rep->s, p, rep->len, 0);
+}
+
+inline int BitString::matches(const BitPattern& r, int p) const
+{
+ return r.match(rep->s, p, rep->len, 1);
+}
+
+inline int BitString::index(const BitPattern& r, int startpos) const
+{
+ return r.search(rep->s, startpos, rep->len);
+}
+
+inline int BitSubString::length() const
+{
+ return len;
+}
+
+inline int BitSubString::empty() const
+{
+ return len == 0;
+}
+
+inline int operator != (const BitString& x, const BitString& y)
+{
+ return !(x == y);
+}
+
+inline int operator>(const BitString& x, const BitString& y)
+{
+ return y < x;
+}
+
+inline int operator>=(const BitString& x, const BitString& y)
+{
+ return y <= x;
+}
+
+inline int BitString::first(unsigned int b) const
+{
+ return next(-1, b);
+}
+
+inline int BitString::last(unsigned int b) const
+{
+ return prev(rep->len, b);
+}
+
+inline int BitString::index(unsigned int bit, int startpos) const
+{
+ if (startpos >= 0)
+ return next(startpos - 1, bit);
+ else
+ return prev(rep->len + startpos + 1, bit);
+}
+
+inline void BitString::right_trim(unsigned int b)
+{
+ int nb = (b == 0)? 1 : 0;
+ rep = BStr_resize(rep, prev(rep->len, nb) + 1);
+}
+
+inline void BitString::left_trim(unsigned int b)
+{
+ int nb = (b == 0)? 1 : 0;
+ int p = next(-1, nb);
+ rep = BStr_alloc(rep, rep->s, p, rep->len, rep->len - p);
+}
+
+inline int BitString::test(int i) const
+{
+ return ((unsigned)(i) >= rep->len)? 0 :
+ ((rep->s[BitStr_index(i)] & (1 << (BitStr_pos(i)))) != 0);
+}
+
+
+// subscripting
+
+inline BitStrBit::BitStrBit(const BitStrBit& b) :src(b.src), pos(b.pos) {}
+
+inline BitStrBit::BitStrBit(BitString& v, int p) :src(v), pos(p) {}
+
+inline BitStrBit::~BitStrBit() {}
+
+inline BitStrBit::operator unsigned int() const
+{
+ return src.test(pos);
+}
+
+inline int BitStrBit::operator = (unsigned int b)
+{
+ src.assign(pos, b); return b;
+}
+
+inline BitStrBit BitString::operator [] (int i)
+{
+ if ((unsigned)(i) >= rep->len) error("illegal bit index");
+ return BitStrBit(*this, i);
+}
+
+inline BitSubString BitString::_substr(int first, int l)
+{
+ if (first < 0 || l <= 0 || (unsigned)(first + l) > rep->len)
+ return BitSubString(_nil_BitString, 0, 0) ;
+ else
+ return BitSubString(*this, first, l);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Complex.h b/gnu/lib/libg++/include/Complex.h
new file mode 100644
index 0000000..385ea606d7
--- /dev/null
+++ b/gnu/lib/libg++/include/Complex.h
@@ -0,0 +1,276 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _Complex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Complex_h 1
+
+
+#include <iostream.h>
+#include <math.h>
+
+class Complex
+{
+#ifdef __ATT_complex__
+public:
+#else
+protected:
+#endif
+
+ double re;
+ double im;
+
+public:
+
+ double real() const;
+ double imag() const;
+
+ Complex();
+ Complex(const Complex& y);
+ Complex(double r, double i=0);
+
+ ~Complex();
+
+ Complex& operator = (const Complex& y);
+
+ Complex& operator += (const Complex& y);
+ Complex& operator += (double y);
+ Complex& operator -= (const Complex& y);
+ Complex& operator -= (double y);
+ Complex& operator *= (const Complex& y);
+ Complex& operator *= (double y);
+
+ Complex& operator /= (const Complex& y);
+ Complex& operator /= (double y);
+
+ void error(const char* msg) const;
+};
+
+
+// non-inline functions
+
+Complex operator / (const Complex& x, const Complex& y);
+Complex operator / (const Complex& x, double y);
+Complex operator / (double x, const Complex& y);
+
+Complex cos(const Complex& x);
+Complex sin(const Complex& x);
+
+Complex cosh(const Complex& x);
+Complex sinh(const Complex& x);
+
+Complex exp(const Complex& x);
+Complex log(const Complex& x);
+
+Complex pow(const Complex& x, int p);
+Complex pow(const Complex& x, const Complex& p);
+Complex pow(const Complex& x, double y);
+Complex sqrt(const Complex& x);
+
+istream& operator >> (istream& s, Complex& x);
+ostream& operator << (ostream& s, const Complex& x);
+
+// other functions defined as inlines
+
+int operator == (const Complex& x, const Complex& y);
+int operator == (const Complex& x, double y);
+int operator != (const Complex& x, const Complex& y);
+int operator != (const Complex& x, double y);
+
+Complex operator - (const Complex& x);
+Complex conj(const Complex& x);
+Complex operator + (const Complex& x, const Complex& y);
+Complex operator + (const Complex& x, double y);
+Complex operator + (double x, const Complex& y);
+Complex operator - (const Complex& x, const Complex& y);
+Complex operator - (const Complex& x, double y);
+Complex operator - (double x, const Complex& y);
+Complex operator * (const Complex& x, const Complex& y);
+Complex operator * (const Complex& x, double y);
+Complex operator * (double x, const Complex& y);
+
+double real(const Complex& x);
+double imag(const Complex& x);
+double abs(const Complex& x);
+double norm(const Complex& x);
+double arg(const Complex& x);
+
+Complex polar(double r, double t = 0.0);
+
+
+// inline members
+
+inline double Complex::real() const { return re; }
+inline double Complex::imag() const { return im; }
+
+inline Complex::Complex() {}
+inline Complex::Complex(const Complex& y) :re(y.real()), im(y.imag()) {}
+inline Complex::Complex(double r, double i) :re(r), im(i) {}
+
+inline Complex::~Complex() {}
+
+inline Complex& Complex::operator = (const Complex& y)
+{
+ re = y.real(); im = y.imag(); return *this;
+}
+
+inline Complex& Complex::operator += (const Complex& y)
+{
+ re += y.real(); im += y.imag(); return *this;
+}
+
+inline Complex& Complex::operator += (double y)
+{
+ re += y; return *this;
+}
+
+inline Complex& Complex::operator -= (const Complex& y)
+{
+ re -= y.real(); im -= y.imag(); return *this;
+}
+
+inline Complex& Complex::operator -= (double y)
+{
+ re -= y; return *this;
+}
+
+inline Complex& Complex::operator *= (const Complex& y)
+{
+ double r = re * y.real() - im * y.imag();
+ im = re * y.imag() + im * y.real();
+ re = r;
+ return *this;
+}
+
+inline Complex& Complex::operator *= (double y)
+{
+ re *= y; im *= y; return *this;
+}
+
+
+// functions
+
+inline int operator == (const Complex& x, const Complex& y)
+{
+ return x.real() == y.real() && x.imag() == y.imag();
+}
+
+inline int operator == (const Complex& x, double y)
+{
+ return x.imag() == 0.0 && x.real() == y;
+}
+
+inline int operator != (const Complex& x, const Complex& y)
+{
+ return x.real() != y.real() || x.imag() != y.imag();
+}
+
+inline int operator != (const Complex& x, double y)
+{
+ return x.imag() != 0.0 || x.real() != y;
+}
+
+inline Complex operator - (const Complex& x)
+{
+ return Complex(-x.real(), -x.imag());
+}
+
+inline Complex conj(const Complex& x)
+{
+ return Complex(x.real(), -x.imag());
+}
+
+inline Complex operator + (const Complex& x, const Complex& y)
+{
+ return Complex(x.real() + y.real(), x.imag() + y.imag());
+}
+
+inline Complex operator + (const Complex& x, double y)
+{
+ return Complex(x.real() + y, x.imag());
+}
+
+inline Complex operator + (double x, const Complex& y)
+{
+ return Complex(x + y.real(), y.imag());
+}
+
+inline Complex operator - (const Complex& x, const Complex& y)
+{
+ return Complex(x.real() - y.real(), x.imag() - y.imag());
+}
+
+inline Complex operator - (const Complex& x, double y)
+{
+ return Complex(x.real() - y, x.imag());
+}
+
+inline Complex operator - (double x, const Complex& y)
+{
+ return Complex(x - y.real(), -y.imag());
+}
+
+inline Complex operator * (const Complex& x, const Complex& y)
+{
+ return Complex(x.real() * y.real() - x.imag() * y.imag(),
+ x.real() * y.imag() + x.imag() * y.real());
+}
+
+inline Complex operator * (const Complex& x, double y)
+{
+ return Complex(x.real() * y, x.imag() * y);
+}
+
+inline Complex operator * (double x, const Complex& y)
+{
+ return Complex(x * y.real(), x * y.imag());
+}
+
+inline double real(const Complex& x)
+{
+ return x.real();
+}
+
+inline double imag(const Complex& x)
+{
+ return x.imag();
+}
+
+inline double abs(const Complex& x)
+{
+ return hypot(x.real(), x.imag());
+}
+
+inline double norm(const Complex& x)
+{
+ return (x.real() * x.real() + x.imag() * x.imag());
+}
+
+inline double arg(const Complex& x)
+{
+ return atan2(x.imag(), x.real());
+}
+
+inline Complex polar(double r, double t)
+{
+ return Complex(r * cos(t), r * sin(t));
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/CursesW.h b/gnu/lib/libg++/include/CursesW.h
new file mode 100644
index 0000000..4f367fd
--- /dev/null
+++ b/gnu/lib/libg++/include/CursesW.h
@@ -0,0 +1,590 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Eric Newton (newton@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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _CursesWindow_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _CursesWindow_h
+
+#include <_G_config.h>
+#if _G_HAVE_CURSES
+#include <curses.h>
+
+/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro.
+ Undefine it here, because CursesWindow uses lines as a method. */
+#undef lines
+
+// "Convert" macros to inlines, if needed.
+#ifdef addch
+inline int (addch)(char ch) { return addch(ch); }
+#undef addch
+#endif
+#ifdef addstr
+/* The (char*) cast is to hack around missing const's */
+inline int (addstr)(const char * str) { return addstr((char*)str); }
+#undef addstr
+#endif
+#ifdef clear
+inline int (clear)() { return clear(); }
+#undef clear
+#endif
+#ifdef clearok
+inline int (clearok)(WINDOW* win, int bf) { return clearok(win, bf); }
+#undef clearok
+#else
+extern "C" int clearok(WINDOW*, int);
+#endif
+#ifdef clrtobot
+inline int (clrtobot)() { return clrtobot(); }
+#undef clrtobot
+#endif
+#ifdef clrtoeol
+inline int (clrtoeol)() { return clrtoeol(); }
+#undef clrtoeol
+#endif
+#ifdef delch
+inline int (delch)() { return delch(); }
+#undef delch
+#endif
+#ifdef deleteln
+inline int (deleteln)() { return deleteln(); }
+#undef deleteln
+#endif
+#ifdef erase
+inline int (erase)() { return erase(); }
+#undef erase
+#endif
+#ifdef flushok
+inline int (flushok)(WINDOW* _win, int _bf) { return flushok(_win, _bf); }
+#undef flushok
+#else
+#define _no_flushok
+#endif
+#ifdef getch
+inline int (getch)() { return getch(); }
+#undef getch
+#endif
+#ifdef getstr
+inline int (getstr)(char *_str) { return getstr(_str); }
+#undef getstr
+#endif
+#ifdef getyx
+inline void (getyx)(WINDOW* win, int& y, int& x) { getyx(win, y, x); }
+#undef getyx
+#endif
+#ifdef inch
+inline int (inch)() { return inch(); }
+#undef inch
+#endif
+#ifdef insch
+inline int (insch)(char c) { return insch(c); }
+#undef insch
+#endif
+#ifdef insertln
+inline int (insertln)() { return insertln(); }
+#undef insertln
+#endif
+#ifdef leaveok
+inline int (leaveok)(WINDOW* win, int bf) { return leaveok(win, bf); }
+#undef leaveok
+#else
+extern "C" int leaveok(WINDOW* win, int bf);
+#endif
+#ifdef move
+inline int (move)(int x, int y) { return move(x, y); }
+#undef move
+#endif
+#ifdef refresh
+inline int (rfresh)() { return refresh(); }
+#undef refresh
+#endif
+#ifdef scrollok
+inline int (scrollok)(WINDOW* win, int bf) { return scrollok(win, bf); }
+#undef scrollok
+#else
+#ifndef hpux
+extern "C" int scrollok(WINDOW*, int);
+#else
+extern "C" int scrollok(WINDOW*, char);
+#endif
+#endif
+#ifdef standend
+inline int (standend)() { return standend(); }
+#undef standend
+#endif
+#ifdef standout
+inline int (standout)() { return standout(); }
+#undef standout
+#endif
+#ifdef wstandend
+inline int (wstandend)(WINDOW *win) { return wstandend(win); }
+#undef wstandend
+#endif
+#ifdef wstandout
+inline int (wstandout)(WINDOW *win) { return wstandout(win); }
+#undef wstandout
+#endif
+#ifdef winch
+inline int (winch)(WINDOW* win) { return winch(win); }
+#undef winch
+#endif
+
+/* deal with conflicting macros in ncurses.h which is SYSV based*/
+#ifdef box
+inline (box)(WINDOW* win, chtype v, chtype h) {return box(win, v, h); }
+#undef box
+#endif
+#ifdef scroll
+inline (scroll)(WINDOW* win) { return scroll(win); }
+#undef scroll
+#endif
+#ifdef touchwin
+inline (touchwin)(WINDOW* win) { return touchwin(win); }
+#undef touchwin
+#endif
+
+#ifdef mvwaddch
+inline int (mvwaddch)(WINDOW *win, int y, int x, char ch)
+{ return mvwaddch(win, y, x, ch); }
+#undef mvwaddch
+#endif
+#ifdef mvwaddstr
+inline int (mvwaddstr)(WINDOW *win, int y, int x, const char * str)
+{ return mvwaddstr(win, y, x, (char*)str); }
+#undef mvwaddstr
+#endif
+#ifdef mvwdelch
+inline int (mvwdelch)(WINDOW *win, int y, int x) { return mvwdelch(win, y, x);}
+#undef mvwdelch
+#endif
+#ifdef mvwgetch
+inline int (mvwgetch)(WINDOW *win, int y, int x) { return mvwgetch(win, y, x);}
+#undef mvwgetch
+#endif
+#ifdef mvwgetstr
+inline int (mvwgetstr)(WINDOW *win, int y, int x, char *str)
+{return mvwgetstr(win,y,x, str);}
+#undef mvwgetstr
+#endif
+#ifdef mvwinch
+inline int (mvwinch)(WINDOW *win, int y, int x) { return mvwinch(win, y, x);}
+#undef mvwinch
+#endif
+#ifdef mvwinsch
+inline int (mvwinsch)(WINDOW *win, int y, int x, char c)
+{ return mvwinsch(win, y, x, c); }
+#undef mvwinsch
+#endif
+
+#ifdef mvaddch
+inline int (mvaddch)(int y, int x, char ch)
+{ return mvaddch(y, x, ch); }
+#undef mvaddch
+#endif
+#ifdef mvaddstr
+inline int (mvaddstr)(int y, int x, const char * str)
+{ return mvaddstr(y, x, (char*)str); }
+#undef mvaddstr
+#endif
+#ifdef mvdelch
+inline int (mvdelch)(int y, int x) { return mvdelch(y, x);}
+#undef mvdelch
+#endif
+#ifdef mvgetch
+inline int (mvgetch)(int y, int x) { return mvgetch(y, x);}
+#undef mvgetch
+#endif
+#ifdef mvgetstr
+inline int (mvgetstr)(int y, int x, char *str) {return mvgetstr(y, x, str);}
+#undef mvgetstr
+#endif
+#ifdef mvinch
+inline int (mvinch)(int y, int x) { return mvinch(y, x);}
+#undef mvinch
+#endif
+#ifdef mvinsch
+inline int (mvinsch)(int y, int x, char c)
+{ return mvinsch(y, x, c); }
+#undef mvinsch
+#endif
+
+/*
+ *
+ * C++ class for windows.
+ *
+ *
+ */
+
+class CursesWindow
+{
+protected:
+ static int count; // count of all active windows:
+ // We rely on the c++ promise that
+ // all otherwise uninitialized
+ // static class vars are set to 0
+
+ WINDOW * w; // the curses WINDOW
+
+ int alloced; // true if we own the WINDOW
+
+ CursesWindow* par; // parent, if subwindow
+ CursesWindow* subwins; // head of subwindows list
+ CursesWindow* sib; // next subwindow of parent
+
+ void kill_subwindows(); // disable all subwindows
+
+public:
+ CursesWindow(WINDOW* &window); // useful only for stdscr
+
+ CursesWindow(int lines, // number of lines
+ int cols, // number of columns
+ int begin_y, // line origin
+ int begin_x); // col origin
+
+ CursesWindow(CursesWindow& par, // parent window
+ int lines, // number of lines
+ int cols, // number of columns
+ int by, // absolute or relative
+ int bx, // origins:
+ char absrel = 'a'); // if `a', by & bx are
+ // absolute screen pos,
+ // else if `r', they are
+ // relative to par origin
+ ~CursesWindow();
+
+// terminal status
+ int lines(); // number of lines on terminal, *not* window
+ int cols(); // number of cols on terminal, *not* window
+
+// window status
+ int height(); // number of lines in this window
+ int width(); // number of cols in this window
+ int begx(); // smallest x coord in window
+ int begy(); // smallest y coord in window
+ int maxx(); // largest x coord in window
+ int maxy(); // largest x coord in window
+
+// window positioning
+ int move(int y, int x);
+
+// coordinate positioning
+ void getyx(int& y, int& x);
+ int mvcur(int sy, int ey, int sx, int ex);
+
+// input
+ int getch();
+ int getstr(char * str);
+ int scanw(const char *, ...);
+
+// input + positioning
+ int mvgetch(int y, int x);
+ int mvgetstr(int y, int x, char * str);
+ int mvscanw(int, int, const char*, ...);
+
+// output
+ int addch(const char ch);
+ int addstr(const char * str);
+ int printw(const char * fmt, ...);
+ int inch();
+ int insch(char c);
+ int insertln();
+
+// output + positioning
+ int mvaddch(int y, int x, char ch);
+ int mvaddstr(int y, int x, const char * str);
+ int mvprintw(int y, int x, const char * fmt, ...);
+ int mvinch(int y, int x);
+ int mvinsch(int y, int x, char ch);
+
+// borders
+ int box(char vert, char hor);
+
+// erasure
+ int erase();
+ int clear();
+ int clearok(int bf);
+ int clrtobot();
+ int clrtoeol();
+ int delch();
+ int mvdelch(int y, int x);
+ int deleteln();
+
+// screen control
+ int scroll();
+ int scrollok(int bf);
+ int touchwin();
+ int refresh();
+ int leaveok(int bf);
+#ifndef _no_flushok
+ int flushok(int bf);
+#endif
+ int standout();
+ int standend();
+
+// multiple window control
+ int overlay(CursesWindow &win);
+ int overwrite(CursesWindow &win);
+
+
+// traversal support
+ CursesWindow* child();
+ CursesWindow* sibling();
+ CursesWindow* parent();
+};
+
+
+inline int CursesWindow::begx()
+{
+ return w->_begx;
+}
+
+inline int CursesWindow::begy()
+{
+ return w->_begy;
+}
+
+inline int CursesWindow::maxx()
+{
+ return w->_maxx;
+}
+
+inline int CursesWindow::maxy()
+{
+ return w->_maxy;
+}
+
+inline int CursesWindow::height()
+{
+ return maxy() - begy() + 1;
+}
+
+inline int CursesWindow::width()
+{
+ return maxx() - begx() + 1;
+}
+
+inline int CursesWindow::box(char vert, char hor)
+{
+ return ::box(w, vert, hor);
+}
+
+inline int CursesWindow::overlay(CursesWindow &win)
+{
+ return ::overlay(w, win.w);
+}
+
+inline int CursesWindow::overwrite(CursesWindow &win)
+{
+ return ::overwrite(w, win.w);
+}
+
+inline int CursesWindow::scroll()
+{
+ return ::scroll(w);
+}
+
+
+inline int CursesWindow::touchwin()
+{
+ return ::touchwin(w);
+}
+
+inline int CursesWindow::addch(const char ch)
+{
+ return ::waddch(w, ch);
+}
+
+inline int CursesWindow::addstr(const char * str)
+{
+ // The (char*) cast is to hack around prototypes in curses.h that
+ // have const missing in the parameter lists. [E.g. SVR4]
+ return ::waddstr(w, (char*)str);
+}
+
+inline int CursesWindow::clear()
+{
+ return ::wclear(w);
+}
+
+inline int CursesWindow::clrtobot()
+{
+ return ::wclrtobot(w);
+}
+
+inline int CursesWindow::clrtoeol()
+{
+ return ::wclrtoeol(w);
+}
+
+inline int CursesWindow::delch()
+{
+ return ::wdelch(w);
+}
+
+inline int CursesWindow::deleteln()
+{
+ return ::wdeleteln(w);
+}
+
+inline int CursesWindow::erase()
+{
+ return ::werase(w);
+}
+
+inline int CursesWindow::getch()
+{
+ return ::wgetch(w);
+}
+
+inline int CursesWindow::getstr(char * str)
+{
+ return ::wgetstr(w, str);
+}
+
+inline int CursesWindow::inch()
+{
+ return winch(w);
+}
+
+inline int CursesWindow::insch(char c)
+{
+ return ::winsch(w, c);
+}
+
+inline int CursesWindow::insertln()
+{
+ return ::winsertln(w);
+}
+
+inline int CursesWindow::move(int y, int x)
+{
+ return ::wmove(w, y, x);
+}
+
+
+inline int CursesWindow::mvcur(int sy, int ey, int sx, int ex)
+{
+ return ::mvcur(sy, ey, sx,ex);
+}
+
+inline int CursesWindow::mvaddch(int y, int x, char ch)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::waddch(w, ch);
+}
+
+inline int CursesWindow::mvgetch(int y, int x)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::wgetch(w);
+}
+
+inline int CursesWindow::mvaddstr(int y, int x, const char * str)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::waddstr(w, (char*)str);
+}
+
+inline int CursesWindow::mvgetstr(int y, int x, char * str)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::wgetstr(w, str);
+}
+
+inline int CursesWindow::mvinch(int y, int x)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::winch(w);
+}
+
+inline int CursesWindow::mvdelch(int y, int x)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::wdelch(w);
+}
+
+inline int CursesWindow::mvinsch(int y, int x, char ch)
+{
+ return (::wmove(w, y, x)==ERR) ? ERR : ::winsch(w, ch);
+}
+
+inline int CursesWindow::refresh()
+{
+ return ::wrefresh(w);
+}
+
+inline int CursesWindow::clearok(int bf)
+{
+ return ::clearok(w,bf);
+}
+
+inline int CursesWindow::leaveok(int bf)
+{
+ return ::leaveok(w,bf);
+}
+
+inline int CursesWindow::scrollok(int bf)
+{
+ return ::scrollok(w,bf);
+}
+
+#ifndef _no_flushok
+inline int CursesWindow::flushok(int bf)
+{
+ return ::flushok(w, bf);
+}
+#endif
+
+inline void CursesWindow::getyx(int& y, int& x)
+{
+ ::getyx(w, y, x);
+}
+
+inline int CursesWindow::standout()
+{
+ return ::wstandout(w);
+}
+
+inline int CursesWindow::standend()
+{
+ return ::wstandend(w);
+}
+
+inline int CursesWindow::lines()
+{
+ return LINES;
+}
+
+inline int CursesWindow::cols()
+{
+ return COLS;
+}
+
+inline CursesWindow* CursesWindow::child()
+{
+ return subwins;
+}
+
+inline CursesWindow* CursesWindow::parent()
+{
+ return par;
+}
+
+inline CursesWindow* CursesWindow::sibling()
+{
+ return sib;
+}
+
+#endif /* _G_HAVE_CURSES */
+#endif
diff --git a/gnu/lib/libg++/include/DLList.h b/gnu/lib/libg++/include/DLList.h
new file mode 100644
index 0000000..0c3adc2
--- /dev/null
+++ b/gnu/lib/libg++/include/DLList.h
@@ -0,0 +1,126 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef _DLList_h
+#ifdef __GNUG__
+//#pragma interface
+#endif
+#define _DLList_h 1
+
+#include <Pix.h>
+
+struct BaseDLNode {
+ BaseDLNode *bk;
+ BaseDLNode *fd;
+ void *item() {return (void*)(this+1);} //Return ((DLNode<T>*)this)->hd
+};
+
+template<class T>
+class DLNode : public BaseDLNode
+{
+ public:
+ T hd;
+ DLNode() { }
+ DLNode(const T& h, DLNode* p = 0, DLNode* n = 0)
+ : hd(h) { bk = p; fd = n; }
+ ~DLNode() { }
+};
+
+class BaseDLList {
+ protected:
+ BaseDLNode *h;
+
+ BaseDLList() { h = 0; }
+ void copy(const BaseDLList&);
+ BaseDLList& operator= (const BaseDLList& a);
+ virtual void delete_node(BaseDLNode*node) = 0;
+ virtual BaseDLNode* copy_node(const void* datum) = 0;
+ virtual void copy_item(void *dst, void *src) = 0;
+ virtual ~BaseDLList() { }
+
+ Pix prepend(const void*);
+ Pix append(const void*);
+ Pix ins_after(Pix p, const void *datum);
+ Pix ins_before(Pix p, const void *datum);
+ void remove_front(void *dst);
+ void remove_rear(void *dst);
+ void join(BaseDLList&);
+
+ public:
+ int empty() const { return h == 0; }
+ int length() const;
+ void clear();
+ void error(const char* msg);
+ int owns(Pix p);
+ int OK();
+ void del(Pix& p, int dir = 1);
+ void del_after(Pix& p);
+ void del_front();
+ void del_rear();
+};
+
+template <class T>
+class DLList : public BaseDLList {
+ //friend class <T>DLListTrav;
+
+ virtual void delete_node(BaseDLNode *node) { delete (DLNode<T>*)node; }
+ virtual BaseDLNode* copy_node(const void *datum)
+ { return new DLNode<T>(*(const T*)datum); }
+ virtual void copy_item(void *dst, void *src) { *(T*)dst = *(T*)src; }
+
+ public:
+ DLList() : BaseDLList() { }
+ DLList(const DLList<T>& a) : BaseDLList() { copy(a); }
+
+ DLList<T>& operator = (const DLList<T>& a)
+ { BaseDLList::operator=((const BaseDLList&) a); return *this; }
+ virtual ~DLList() { clear(); }
+
+ Pix prepend(const T& item) {return BaseDLList::prepend(&item);}
+ Pix append(const T& item) {return BaseDLList::append(&item);}
+
+ void join(DLList<T>& a) { BaseDLList::join(a); }
+
+ T& front() {
+ if (h == 0) error("front: empty list");
+ return ((DLNode<T>*)h)->hd; }
+ T& rear() {
+ if (h == 0) error("rear: empty list");
+ return ((DLNode<T>*)h->bk)->hd;
+ }
+ T remove_front() { T dst; BaseDLList::remove_front(&dst); return dst; }
+ T remove_rear() { T dst; BaseDLList::remove_rear(&dst); return dst; }
+
+ T& operator () (Pix p) {
+ if (p == 0) error("null Pix");
+ return ((DLNode<T>*)p)->hd;
+ }
+ Pix first() { return Pix(h); }
+ Pix last() { return (h == 0)? 0 : Pix(h->bk); }
+ void next(Pix& p)
+ { p = (p == 0 || p == h->bk)? 0 : Pix(((DLNode<T>*)p)->fd); }
+ void prev(Pix& p)
+ { p = (p == 0 || p == h)? 0 : Pix(((DLNode<T>*)p)->bk); }
+ Pix ins_after(Pix p, const T& item)
+ {return BaseDLList::ins_after(p, &item); }
+ Pix ins_before(Pix p, const T& item)
+ {return BaseDLList::ins_before(p, &item);}
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/DiscUnif.h b/gnu/lib/libg++/include/DiscUnif.h
new file mode 100644
index 0000000..5f26f90
--- /dev/null
+++ b/gnu/lib/libg++/include/DiscUnif.h
@@ -0,0 +1,72 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _DiscreteUniform_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _DiscreteUniform_h 1
+
+#include <Random.h>
+
+//
+// The interval [lo..hi)
+//
+
+class DiscreteUniform: public Random {
+ long pLow;
+ long pHigh;
+ double delta;
+public:
+ DiscreteUniform(long low, long high, RNG *gen);
+
+ long low();
+ long low(long x);
+ long high();
+ long high(long x);
+
+ virtual double operator()();
+};
+
+
+inline DiscreteUniform::DiscreteUniform(long low, long high, RNG *gen)
+: Random(gen)
+{
+ pLow = (low < high) ? low : high;
+ pHigh = (low < high) ? high : low;
+ delta = (pHigh - pLow) + 1;
+}
+
+inline long DiscreteUniform::low() { return pLow; }
+
+inline long DiscreteUniform::low(long x) {
+ long tmp = pLow;
+ pLow = x;
+ delta = (pHigh - pLow) + 1;
+ return tmp;
+}
+
+inline long DiscreteUniform::high() { return pHigh; }
+
+inline long DiscreteUniform::high(long x) {
+ long tmp = pHigh;
+ pHigh = x;
+ delta = (pHigh - pLow) + 1;
+ return tmp;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Erlang.h b/gnu/lib/libg++/include/Erlang.h
new file mode 100644
index 0000000..9809388
--- /dev/null
+++ b/gnu/lib/libg++/include/Erlang.h
@@ -0,0 +1,68 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Erlang_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Erlang_h 1
+
+#include <Random.h>
+
+class Erlang: public Random {
+protected:
+ double pMean;
+ double pVariance;
+ int k;
+ double a;
+ void setState();
+public:
+ Erlang(double mean, double variance, RNG *gen);
+
+ double mean();
+ double mean(double x);
+ double variance();
+ double variance(double x);
+
+ virtual double operator()();
+
+};
+
+
+inline void Erlang::setState() {
+ k = int( (pMean * pMean ) / pVariance + 0.5 );
+ k = (k > 0) ? k : 1;
+ a = k / pMean;
+}
+
+inline Erlang::Erlang(double mean, double variance, RNG *gen) : Random(gen)
+{
+ pMean = mean; pVariance = variance;
+ setState();
+}
+
+inline double Erlang::mean() { return pMean; }
+inline double Erlang::mean(double x) {
+ double tmp = pMean; pMean = x; setState(); return tmp;
+};
+
+inline double Erlang::variance() { return pVariance; }
+inline double Erlang::variance(double x) {
+ double tmp = pVariance; pVariance = x; setState(); return tmp;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Fix.h b/gnu/lib/libg++/include/Fix.h
new file mode 100644
index 0000000..df76c94
--- /dev/null
+++ b/gnu/lib/libg++/include/Fix.h
@@ -0,0 +1,513 @@
+// -*- C++ -*-
+// Fix.h : variable length fixed point data type
+//
+
+#ifndef _Fix_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Fix_h 1
+
+#include <stream.h>
+#include <std.h>
+#include <stddef.h>
+#include <Integer.h>
+#include <builtin.h>
+
+class Fix
+{
+ struct Rep // internal Fix representation
+ {
+ _G_uint16_t len; // length in bits
+ _G_uint16_t siz; // allocated storage
+ _G_int16_t ref; // reference count
+ _G_uint16_t s[1]; // start of ushort array represention
+ };
+
+public:
+
+ typedef void (*PEH)(Rep*);
+
+private:
+
+ Rep* rep;
+
+ Fix(Rep*);
+ Fix(int, const Rep*);
+
+ void unique();
+
+ static const _G_uint16_t min_length = 1;
+ static const _G_uint16_t max_length = 65535;
+ static const double min_value = -1.0;
+ static const double max_value = 1.0;
+
+ static _G_uint16_t default_length;
+ static int default_print_width;
+ static Rep Rep_0;
+ static Rep Rep_m1;
+ static Rep Rep_quotient_bump;
+
+ // internal class functions
+ static void mask(Rep*);
+ static int compare(const Rep*, const Rep* = &Rep_0);
+
+ static Rep* new_Fix(_G_uint16_t);
+ static Rep* new_Fix(_G_uint16_t, const Rep*);
+ static Rep* new_Fix(_G_uint16_t, double);
+
+ static Rep* copy(const Rep*, Rep*);
+ static Rep* negate(const Rep*, Rep* = NULL);
+ static Rep* add(const Rep*, const Rep*, Rep* = NULL);
+ static Rep* subtract(const Rep*, const Rep*, Rep* = NULL);
+ static Rep* multiply(const Rep*, const Rep*, Rep* = NULL);
+ static Rep* multiply(const Rep*, int, Rep* = NULL);
+ static Rep* divide(const Rep*, const Rep*, Rep* = NULL,
+ Rep* = NULL);
+ static Rep* shift(const Rep*, int, Rep* = NULL);
+
+ static one_arg_error_handler_t error_handler;
+ static one_arg_error_handler_t range_error_handler;
+
+ static PEH overflow_handler;
+
+public:
+ Fix();
+ Fix(const Fix&);
+ Fix(double);
+ Fix(int);
+ Fix(int, const Fix&);
+ Fix(int, double);
+
+ ~Fix();
+
+ Fix operator = (const Fix&);
+ Fix operator = (double);
+
+ friend int operator == (const Fix&, const Fix&);
+ friend int operator != (const Fix&, const Fix&);
+
+ friend int operator < (const Fix&, const Fix&);
+ friend int operator <= (const Fix&, const Fix&);
+ friend int operator > (const Fix&, const Fix&);
+ friend int operator >= (const Fix&, const Fix&);
+
+ Fix& operator + ();
+ Fix operator - ();
+
+ friend Fix operator + (const Fix&, const Fix&);
+ friend Fix operator - (const Fix&, const Fix&);
+ friend Fix operator * (const Fix&, const Fix&);
+ friend Fix operator / (const Fix&, const Fix&);
+
+ friend Fix operator * (const Fix&, int);
+ friend Fix operator * (int, const Fix&);
+ friend Fix operator % (const Fix&, int);
+ friend Fix operator << (const Fix&, int);
+ friend Fix operator >> (const Fix&, int);
+
+#if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
+ friend Fix operator <? (const Fix&, const Fix&); // min
+ friend Fix operator >? (const Fix&, const Fix&); // max
+#endif
+
+ Fix operator += (const Fix&);
+ Fix operator -= (const Fix&);
+ Fix operator *= (const Fix&);
+ Fix operator /= (const Fix&);
+
+ Fix operator *= (int);
+ Fix operator %= (int);
+ Fix operator <<=(int);
+ Fix operator >>=(int);
+
+ friend char* Ftoa(const Fix&, int width = default_print_width);
+ void printon(ostream&, int width = default_print_width) const;
+ friend Fix atoF(const char*, int len = default_length);
+
+ friend istream& operator >> (istream&, Fix&);
+ friend ostream& operator << (ostream&, const Fix&);
+
+ // built-in functions
+ friend Fix abs(Fix); // absolute value
+ friend int sgn(const Fix&); // -1, 0, +1
+ friend Integer mantissa(const Fix&); // integer representation
+ friend double value(const Fix&); // double value
+ friend int length(const Fix&); // field length
+ friend void show(const Fix&); // show contents
+
+ // error handlers
+ static void error(const char* msg); // error handler
+ static void range_error(const char* msg); // range error handler
+
+ static one_arg_error_handler_t set_error_handler(one_arg_error_handler_t f);
+ static one_arg_error_handler_t
+ set_range_error_handler(one_arg_error_handler_t f);
+
+ static void default_error_handler (const char *);
+ static void default_range_error_handler (const char *);
+
+ // non-operator versions for user
+ friend void negate(const Fix& x, Fix& r);
+ friend void add(const Fix& x, const Fix& y, Fix& r);
+ friend void subtract(const Fix& x, const Fix& y, Fix& r);
+ friend void multiply(const Fix& x, const Fix& y, Fix& r);
+ friend void divide(const Fix& x, const Fix& y, Fix& q, Fix& r);
+ friend void shift(const Fix& x, int y, Fix& r);
+
+ // overflow handlers
+ static void overflow_saturate(Fix::Rep*);
+ static void overflow_wrap(Fix::Rep*);
+ static void overflow_warning_saturate(Fix::Rep*);
+ static void overflow_warning(Fix::Rep*);
+ static void overflow_error(Fix::Rep*);
+
+ static PEH set_overflow_handler(PEH);
+
+ static int set_default_length(int);
+};
+
+// function definitions
+
+inline void
+Fix::unique()
+{
+ if ( rep->ref > 1 )
+ {
+ rep->ref--;
+ rep = new_Fix(rep->len,rep);
+ }
+}
+
+inline void
+Fix::mask (Fix::Rep* x)
+{
+ int n = x->len & 0x0f;
+ if ( n )
+ x->s[x->siz - 1] &= 0xffff0000 >> n;
+}
+
+inline Fix::Rep*
+Fix::copy(const Fix::Rep* from, Fix::Rep* to)
+{
+ _G_uint16_t *ts = to->s;
+ const _G_uint16_t *fs = from->s;
+ int ilim = to->siz < from->siz ? to->siz : from->siz;
+ for ( int i=0; i < ilim; i++ )
+ *ts++ = *fs++;
+ for ( ; i < to->siz; i++ )
+ *ts++ = 0;
+ mask(to);
+ return to;
+}
+
+inline
+Fix::Fix(Rep* f)
+{
+ rep = f;
+}
+
+inline
+Fix::Fix()
+{
+ rep = new_Fix(default_length);
+}
+
+inline
+Fix::Fix(int len)
+{
+ if ( len < min_length || len > max_length )
+ error("illegal length in declaration");
+ rep = new_Fix((_G_uint16_t) len);
+}
+
+inline
+Fix::Fix(double d)
+{
+ rep = new_Fix(default_length,d);
+}
+
+inline
+Fix::Fix(const Fix& y)
+{
+ rep = y.rep; rep->ref++;
+}
+
+inline
+Fix::Fix(int len, const Fix& y)
+{
+ if ( len < Fix::min_length || len > Fix::max_length )
+ error("illegal length in declaration");
+ rep = new_Fix((_G_uint16_t) len,y.rep);
+}
+
+inline
+Fix::Fix(int len, const Rep* fr)
+{
+ if ( len < Fix::min_length || len > Fix::max_length )
+ error("illegal length in declaration");
+ rep = new_Fix((_G_uint16_t) len,fr);
+}
+
+inline
+Fix::Fix(int len, double d)
+{
+ if ( len < Fix::min_length || len > Fix::max_length )
+ error("illegal length in declaration");
+ rep = new_Fix((_G_uint16_t) len,d);
+}
+
+inline
+Fix::~Fix()
+{
+ if ( --rep->ref <= 0 ) delete rep;
+}
+
+inline Fix
+Fix::operator = (const Fix& y)
+{
+ if ( rep->len == y.rep->len ) {
+ ++y.rep->ref;
+ if ( --rep->ref <= 0 ) delete rep;
+ rep = y.rep;
+ }
+ else {
+ unique();
+ copy(y.rep,rep);
+ }
+ return *this;
+}
+
+inline Fix
+Fix::operator = (double d)
+{
+ int oldlen = rep->len;
+ if ( --rep->ref <= 0 ) delete rep;
+ rep = new_Fix(oldlen,d);
+ return *this;
+}
+
+inline int
+operator == (const Fix& x, const Fix& y)
+{
+ return Fix::compare(x.rep, y.rep) == 0;
+}
+
+inline int
+operator != (const Fix& x, const Fix& y)
+{
+ return Fix::compare(x.rep, y.rep) != 0;
+}
+
+inline int
+operator < (const Fix& x, const Fix& y)
+{
+ return Fix::compare(x.rep, y.rep) < 0;
+}
+
+inline int
+operator <= (const Fix& x, const Fix& y)
+{
+ return Fix::compare(x.rep, y.rep) <= 0;
+}
+
+inline int
+operator > (const Fix& x, const Fix& y)
+{
+ return Fix::compare(x.rep, y.rep) > 0;
+}
+
+inline int
+operator >= (const Fix& x, const Fix& y)
+{
+ return Fix::compare(x.rep, y.rep) >= 0;
+}
+
+inline Fix&
+Fix::operator + ()
+{
+ return *this;
+}
+
+inline Fix
+Fix::operator - ()
+{
+ Rep* r = negate(rep); return r;
+}
+
+inline Fix
+operator + (const Fix& x, const Fix& y)
+{
+ Fix::Rep* r = Fix::add(x.rep, y.rep); return r;
+}
+
+inline Fix
+operator - (const Fix& x, const Fix& y)
+{
+ Fix::Rep* r = Fix::subtract(x.rep, y.rep); return r;
+}
+
+inline Fix
+operator * (const Fix& x, const Fix& y)
+{
+ Fix::Rep* r = Fix::multiply(x.rep, y.rep); return r;
+}
+
+inline Fix
+operator * (const Fix& x, int y)
+{
+ Fix::Rep* r = Fix::multiply(x.rep, y); return r;
+}
+
+inline Fix
+operator * (int y, const Fix& x)
+{
+ Fix::Rep* r = Fix::multiply(x.rep, y); return r;
+}
+
+inline Fix
+operator / (const Fix& x, const Fix& y)
+{
+ Fix::Rep* r = Fix::divide(x.rep, y.rep); return r;
+}
+
+inline Fix
+Fix::operator += (const Fix& y)
+{
+ unique(); Fix::add(rep, y.rep, rep); return *this;
+}
+
+inline Fix
+Fix::operator -= (const Fix& y)
+{
+ unique(); Fix::subtract(rep, y.rep, rep); return *this;
+}
+
+inline Fix
+Fix::operator *= (const Fix& y)
+{
+ unique(); Fix::multiply(rep, y.rep, rep); return *this;
+}
+
+inline Fix
+Fix::operator *= (int y)
+{
+ unique(); Fix::multiply(rep, y, rep); return *this;
+}
+
+inline Fix
+Fix::operator /= (const Fix& y)
+{
+ unique(); Fix::divide(rep, y.rep, rep); return *this;
+}
+
+inline Fix
+operator % (const Fix& x, int y)
+{
+ Fix r((int) x.rep->len + y, x); return r;
+}
+
+inline Fix
+operator << (const Fix& x, int y)
+{
+ Fix::Rep* rep = Fix::shift(x.rep, y); return rep;
+}
+
+inline Fix
+operator >> (const Fix& x, int y)
+{
+ Fix::Rep* rep = Fix::shift(x.rep, -y); return rep;
+}
+
+inline Fix
+Fix::operator <<= (int y)
+{
+ unique(); Fix::shift(rep, y, rep); return *this;
+}
+
+inline Fix
+Fix::operator >>= (int y)
+{
+ unique(); Fix::shift(rep, -y, rep); return *this;
+}
+
+#if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
+inline Fix
+operator <? (const Fix& x, const Fix& y)
+{
+ if ( Fix::compare(x.rep, y.rep) <= 0 ) return x; else return y;
+}
+
+inline Fix
+operator >? (const Fix& x, const Fix& y)
+{
+ if ( Fix::compare(x.rep, y.rep) >= 0 ) return x; else return y;
+}
+#endif
+
+inline Fix
+abs(Fix x)
+{
+ Fix::Rep* r = (Fix::compare(x.rep) >= 0 ? Fix::new_Fix(x.rep->len,x.rep) :
+ Fix::negate(x.rep));
+ return r;
+}
+
+inline int
+sgn(const Fix& x)
+{
+ int a = Fix::compare(x.rep);
+ return a == 0 ? 0 : (a > 0 ? 1 : -1);
+}
+
+inline int
+length(const Fix& x)
+{
+ return x.rep->len;
+}
+
+inline ostream&
+operator << (ostream& s, const Fix& y)
+{
+ if (s.opfx())
+ y.printon(s);
+ return s;
+}
+
+inline void
+negate (const Fix& x, Fix& r)
+{
+ Fix::negate(x.rep, r.rep);
+}
+
+inline void
+add (const Fix& x, const Fix& y, Fix& r)
+{
+ Fix::add(x.rep, y.rep, r.rep);
+}
+
+inline void
+subtract (const Fix& x, const Fix& y, Fix& r)
+{
+ Fix::subtract(x.rep, y.rep, r.rep);
+}
+
+inline void
+multiply (const Fix& x, const Fix& y, Fix& r)
+{
+ Fix::multiply(x.rep, y.rep, r.rep);
+}
+
+inline void
+divide (const Fix& x, const Fix& y, Fix& q, Fix& r)
+{
+ Fix::divide(x.rep, y.rep, q.rep, r.rep);
+}
+
+inline void
+shift (const Fix& x, int y, Fix& r)
+{
+ Fix::shift(x.rep, y, r.rep);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Fix16.h b/gnu/lib/libg++/include/Fix16.h
new file mode 100644
index 0000000..36728b4
--- /dev/null
+++ b/gnu/lib/libg++/include/Fix16.h
@@ -0,0 +1,648 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _Fix16_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Fix16_h 1
+
+#include <stream.h>
+#include <std.h>
+
+// constant definitions
+
+#define Fix16_fs ((double)((unsigned)(1 << 15)))
+
+#define Fix16_msb (1 << 15)
+#define Fix16_m_max ((1 << 15) - 1)
+#define Fix16_m_min ((short)(1 << 15))
+
+#define Fix16_mult Fix16_fs
+#define Fix16_div (1./Fix16_fs)
+#define Fix16_max (1. - .5/Fix16_fs)
+#define Fix16_min (-1.)
+
+
+#define Fix32_fs ((double)((unsigned long)(1 << 31)))
+
+#define Fix32_msb ((unsigned long)(1 << 31))
+#define Fix32_m_max ((long)((1 << 31) - 1))
+#define Fix32_m_min ((long)(1 << 31))
+
+#define Fix32_mult Fix32_fs
+#define Fix32_div (1./Fix32_fs)
+#define Fix32_max (1. - .5/Fix32_fs)
+#define Fix32_min (-1.)
+
+
+//
+// Fix16 class: 16-bit Fixed point data type
+//
+// consists of a 16-bit mantissa (sign bit & 15 data bits).
+//
+
+class Fix16
+{
+ friend class Fix32;
+
+ short m;
+
+ short round(double d);
+ short assign(double d);
+ Fix16(short i);
+ Fix16(int i);
+
+ operator double() const;
+
+
+public:
+ Fix16();
+ Fix16(const Fix16& f);
+ Fix16(double d);
+ Fix16(const Fix32& f);
+
+ ~Fix16();
+
+ Fix16& operator=(const Fix16& f);
+ Fix16& operator=(double d);
+ Fix16& operator=(const Fix32& f);
+
+ friend short& mantissa(Fix16& f);
+ friend const short& mantissa(const Fix16& f);
+ friend double value(const Fix16& f);
+
+ Fix16 operator + () const;
+ Fix16 operator - () const;
+
+ friend Fix16 operator + (const Fix16& f, const Fix16& g);
+ friend Fix16 operator - (const Fix16& f, const Fix16& g);
+ friend Fix32 operator * (const Fix16& f, const Fix16& g);
+ friend Fix16 operator / (const Fix16& f, const Fix16& g);
+ friend Fix16 operator << (const Fix16& f, int b);
+ friend Fix16 operator >> (const Fix16& f, int b);
+
+ Fix16& operator += (const Fix16& f);
+ Fix16& operator -= (const Fix16& f);
+ Fix16& operator *= (const Fix16& );
+ Fix16& operator /= (const Fix16& f);
+
+ Fix16& operator <<=(int b);
+ Fix16& operator >>=(int b);
+
+ friend int operator == (const Fix16& f, const Fix16& g);
+ friend int operator != (const Fix16& f, const Fix16& g);
+ friend int operator >= (const Fix16& f, const Fix16& g);
+ friend int operator <= (const Fix16& f, const Fix16& g);
+ friend int operator > (const Fix16& f, const Fix16& g);
+ friend int operator < (const Fix16& f, const Fix16& g);
+
+ friend istream& operator >> (istream& s, Fix16& f);
+ friend ostream& operator << (ostream& s, const Fix16& f);
+
+ void overflow(short&) const;
+ void range_error(short&) const;
+
+ friend Fix16 operator * (const Fix16& f, int g);
+ friend Fix16 operator * (int g, const Fix16& f);
+ Fix16& operator *= (int g);
+};
+
+
+//
+// Fix32 class: 32-bit Fixed point data type
+//
+// consists of a 32-bit mantissa (sign bit & 31 data bits).
+//
+
+class Fix32
+{
+ friend class Fix16;
+
+ long m;
+
+ long round(double d);
+ long assign(double d);
+
+ Fix32(long i);
+ operator double() const;
+
+
+public:
+ Fix32();
+ Fix32(const Fix32& f);
+ Fix32(const Fix16& f);
+ Fix32(double d);
+ ~Fix32();
+
+ Fix32& operator = (const Fix32& f);
+ Fix32& operator = (const Fix16& f);
+ Fix32& operator = (double d);
+
+ friend long& mantissa(Fix32& f);
+ friend const long& mantissa(const Fix32& f);
+ friend double value(const Fix32& f);
+
+ Fix32 operator + () const;
+ Fix32 operator - () const;
+
+ friend Fix32 operator + (const Fix32& f, const Fix32& g);
+ friend Fix32 operator - (const Fix32& f, const Fix32& g);
+ friend Fix32 operator * (const Fix32& f, const Fix32& g);
+ friend Fix32 operator / (const Fix32& f, const Fix32& g);
+ friend Fix32 operator << (const Fix32& f, int b);
+ friend Fix32 operator >> (const Fix32& f, int b);
+
+ friend Fix32 operator * (const Fix16& f, const Fix16& g);
+
+ Fix32& operator += (const Fix32& f);
+ Fix32& operator -= (const Fix32& f);
+ Fix32& operator *= (const Fix32& f);
+ Fix32& operator /= (const Fix32& f);
+ Fix32& operator <<=(int b);
+ Fix32& operator >>=(int b);
+
+ friend int operator == (const Fix32& f, const Fix32& g);
+ friend int operator != (const Fix32& f, const Fix32& g);
+ friend int operator >= (const Fix32& f, const Fix32& g);
+ friend int operator <= (const Fix32& f, const Fix32& g);
+ friend int operator > (const Fix32& f, const Fix32& g);
+ friend int operator < (const Fix32& f, const Fix32& g);
+
+ friend istream& operator >> (istream& s, Fix32& f);
+ friend ostream& operator << (ostream& s, const Fix32& f);
+
+ void overflow(long& i) const;
+ void range_error(long& i) const;
+
+ friend Fix32 operator * (const Fix32& f, int g);
+ friend Fix32 operator * (int g, const Fix32& f);
+ Fix32& operator *= (int g);
+};
+
+// active error handler declarations
+
+typedef void (*Fix16_peh)(short&);
+typedef void (*Fix32_peh)(long&);
+
+extern Fix16_peh Fix16_overflow_handler;
+extern Fix32_peh Fix32_overflow_handler;
+
+extern Fix16_peh Fix16_range_error_handler;
+extern Fix32_peh Fix32_range_error_handler;
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define set_overflow_handler sohndl
+#define set_range_error_handler srnghdl
+#endif
+
+
+// error handler declarations
+
+extern Fix16_peh set_Fix16_overflow_handler(Fix16_peh);
+extern Fix32_peh set_Fix32_overflow_handler(Fix32_peh);
+extern void set_overflow_handler(Fix16_peh, Fix32_peh);
+
+extern Fix16_peh set_Fix16_range_error_handler(Fix16_peh);
+extern Fix32_peh set_Fix32_range_error_handler(Fix32_peh);
+extern void set_range_error_handler(Fix16_peh, Fix32_peh);
+
+extern void
+ Fix16_ignore(short&),
+ Fix16_overflow_saturate(short&),
+ Fix16_overflow_warning_saturate(short&),
+ Fix16_warning(short&),
+ Fix16_abort(short&);
+
+extern void
+ Fix32_ignore(long&),
+ Fix32_overflow_saturate(long&),
+ Fix32_overflow_warning_saturate(long&),
+ Fix32_warning(long&),
+ Fix32_abort(long&);
+
+
+inline Fix16::~Fix16() {}
+
+inline short Fix16::round(double d)
+{
+ return short( (d >= 0)? d + 0.5 : d - 0.5);
+}
+
+inline Fix16::Fix16(short i)
+{
+ m = i;
+}
+
+inline Fix16::Fix16(int i)
+{
+ m = i;
+}
+
+inline Fix16::operator double() const
+{
+ return Fix16_div * m;
+}
+
+inline Fix16::Fix16()
+{
+ m = 0;
+}
+
+inline Fix16::Fix16(const Fix16& f)
+{
+ m = f.m;
+}
+
+inline Fix16::Fix16(double d)
+{
+ m = assign(d);
+}
+
+
+inline Fix16& Fix16::operator=(const Fix16& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix16& Fix16::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+
+inline Fix32::Fix32()
+{
+ m = 0;
+}
+
+inline Fix32::Fix32(long i)
+{
+ m = i;
+}
+
+inline Fix32:: operator double() const
+{
+ return Fix32_div * m;
+}
+
+
+inline Fix32::Fix32(const Fix32& f)
+{
+ m = f.m;
+}
+
+inline Fix32::Fix32(const Fix16& f)
+{
+ m = long(f.m) << 16;
+}
+
+inline Fix32::Fix32(double d)
+{
+ m = assign(d);
+}
+
+inline Fix16::Fix16(const Fix32& f)
+{
+ m = f.m >> 16;
+}
+
+
+inline Fix16& Fix16::operator=(const Fix32& f)
+{
+ m = f.m >> 16;
+ return *this;
+}
+
+inline Fix32& Fix32::operator=(const Fix32& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix32& Fix32::operator=(const Fix16& f)
+{
+ m = long(f.m) << 16;
+ return *this;
+}
+
+inline Fix32& Fix32::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+inline short& mantissa(Fix16& f)
+{
+ return f.m;
+}
+
+inline const short& mantissa(const Fix16& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix16& f)
+{
+ return double(f);
+}
+
+inline Fix16 Fix16::operator+() const
+{
+ return m;
+}
+
+inline Fix16 Fix16::operator-() const
+{
+ return -m;
+}
+
+inline Fix16 operator+(const Fix16& f, const Fix16& g)
+{
+ short sum = f.m + g.m;
+ if ( (f.m ^ sum) & (g.m ^ sum) & Fix16_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix16 operator-(const Fix16& f, const Fix16& g)
+{
+ short sum = f.m - g.m;
+ if ( (f.m ^ sum) & (-g.m ^ sum) & Fix16_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix32 operator*(const Fix16& f, const Fix16& g)
+{
+ return Fix32( long( long(f.m) * long(g.m) << 1));
+}
+
+inline Fix16 operator<<(const Fix16& a, int b)
+{
+ return a.m << b;
+}
+
+inline Fix16 operator>>(const Fix16& a, int b)
+{
+ return a.m >> b;
+}
+
+inline Fix16& Fix16:: operator+=(const Fix16& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix16& Fix16:: operator-=(const Fix16& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix16& Fix16::operator*=(const Fix16& f)
+{
+ return *this = *this * f;
+}
+
+inline Fix16& Fix16:: operator/=(const Fix16& f)
+{
+ return *this = *this / f;
+}
+
+inline Fix16& Fix16:: operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix16& Fix16:: operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline int operator==(const Fix16& f, const Fix16& g)
+{
+ return f.m == g.m;
+}
+
+inline int operator!=(const Fix16& f, const Fix16& g)
+{
+ return f.m != g.m;
+}
+
+inline int operator>=(const Fix16& f, const Fix16& g)
+{
+ return f.m >= g.m;
+}
+
+inline int operator<=(const Fix16& f, const Fix16& g)
+{
+ return f.m <= g.m;
+}
+
+inline int operator>(const Fix16& f, const Fix16& g)
+{
+ return f.m > g.m;
+}
+
+inline int operator<(const Fix16& f, const Fix16& g)
+{
+ return f.m < g.m;
+}
+
+inline istream& operator>>(istream& s, Fix16& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix16& f)
+{
+ return s << double(f);
+}
+
+
+inline Fix16 operator*(const Fix16& f, int g)
+{
+ return Fix16(short(f.m * g));
+}
+
+inline Fix16 operator*(int g, const Fix16& f)
+{
+ return f * g;
+}
+
+
+inline Fix16& Fix16::operator*=(int g)
+{
+ return *this = *this * g;
+}
+
+inline Fix32::~Fix32() {}
+
+inline long Fix32::round(double d)
+{
+ return long( (d >= 0)? d + 0.5 : d - 0.5);
+}
+
+inline long& mantissa(Fix32& f)
+{
+ return f.m;
+}
+
+inline const long& mantissa(const Fix32& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix32& f)
+{
+ return double(f);
+}
+
+inline Fix32 Fix32::operator+() const
+{
+ return m;
+}
+
+inline Fix32 Fix32::operator-() const
+{
+ return -m;
+}
+
+inline Fix32 operator+(const Fix32& f, const Fix32& g)
+{
+ long sum = f.m + g.m;
+ if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix32 operator-(const Fix32& f, const Fix32& g)
+{
+ long sum = f.m - g.m;
+ if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix32 operator<<(const Fix32& a, int b)
+{
+ return a.m << b;
+}
+
+inline Fix32 operator>>(const Fix32& a, int b)
+{
+ return a.m >> b;
+}
+
+inline Fix32& Fix32::operator+=(const Fix32& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix32& Fix32::operator-=(const Fix32& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix32& Fix32::operator*=(const Fix32& f)
+{
+ return *this = *this * f;
+}
+
+inline Fix32& Fix32::operator/=(const Fix32& f)
+{
+ return *this = *this / f;
+}
+
+
+inline Fix32& Fix32::operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix32& Fix32::operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline int operator==(const Fix32& f, const Fix32& g)
+{
+ return f.m == g.m;
+}
+
+inline int operator!=(const Fix32& f, const Fix32& g)
+{
+ return f.m != g.m;
+}
+
+inline int operator>=(const Fix32& f, const Fix32& g)
+{
+ return f.m >= g.m;
+}
+
+inline int operator<=(const Fix32& f, const Fix32& g)
+{
+ return f.m <= g.m;
+}
+
+inline int operator>(const Fix32& f, const Fix32& g)
+{
+ return f.m > g.m;
+}
+
+inline int operator<(const Fix32& f, const Fix32& g)
+{
+ return f.m < g.m;
+}
+
+inline istream& operator>>(istream& s, Fix32& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix32& f)
+{
+ return s << double(f);
+}
+
+inline Fix32 operator*(const Fix32& f, int g)
+{
+ return Fix32(long(f.m * g));
+}
+
+inline Fix32 operator*(int g, const Fix32& f)
+{
+ return f * g;
+}
+
+
+
+inline Fix32& Fix32::operator*=(int g)
+{
+ return *this = *this * g;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Fix24.h b/gnu/lib/libg++/include/Fix24.h
new file mode 100644
index 0000000..56d1191
--- /dev/null
+++ b/gnu/lib/libg++/include/Fix24.h
@@ -0,0 +1,597 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _Fix24_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Fix24_h 1
+
+#include <stream.h>
+#include <std.h>
+
+// extra type definitions
+
+typedef struct {
+ long u;
+ unsigned long l;
+} twolongs;
+
+// constant definitions
+
+static const int
+ Fix24_shift = 31;
+
+static const double
+ Fix24_fs = 2147483648., // 2^Fix24_shift
+ Fix24_mult = Fix24_fs,
+ Fix24_div = 1./Fix24_fs,
+ Fix24_max = 1. - .5/Fix24_fs,
+ Fix24_min = -1.;
+
+static const unsigned long
+ Fix24_msb = 0x80000000L,
+ Fix24_lsb = 0x00000100L,
+ Fix24_m_max = 0x7fffff00L,
+ Fix24_m_min = 0x80000000L;
+
+static const double
+ Fix48_fs = 36028797018963968., // 2^(24+Fix24_shift)
+ Fix48_max = 1. - .5/Fix48_fs,
+ Fix48_min = -1.,
+ Fix48_div_u = 1./Fix24_fs,
+ Fix48_div_l = 1./Fix48_fs;
+
+static const twolongs
+ Fix48_msb = { 0x80000000L, 0L },
+ Fix48_lsb = { 0L, 0x00000100L },
+ Fix48_m_max = { 0x7fffff00L, 0xffffff00L },
+ Fix48_m_min = { 0x80000000L, 0L };
+
+//
+// Fix24 class: 24-bit Fixed point data type
+//
+// consists of a 24-bit mantissa (sign bit & 23 data bits).
+//
+
+class Fix24
+{
+ friend class Fix48;
+
+ long m;
+
+ long assign(double d);
+ operator double() const;
+ Fix24(long i);
+ Fix24(int i);
+
+
+public:
+ Fix24();
+ Fix24(const Fix24& f);
+ Fix24(double d);
+ Fix24(const Fix48& f);
+
+ ~Fix24();
+
+ Fix24& operator=(const Fix24& f);
+ Fix24& operator=(double d);
+ Fix24& operator=(const Fix48& f);
+
+ friend long& mantissa(Fix24& f);
+ friend const long& mantissa(const Fix24& f);
+ friend double value(const Fix24& f);
+
+ Fix24 operator + () const;
+ Fix24 operator - () const;
+
+ friend Fix24 operator + (const Fix24& f, const Fix24& g);
+ friend Fix24 operator - (const Fix24& f, const Fix24& g);
+ friend Fix48 operator * (const Fix24& f, const Fix24& g);
+ friend Fix24 operator * (const Fix24& f, int g);
+ friend Fix24 operator * (int g, const Fix24& f);
+ friend Fix24 operator / (const Fix24& f, const Fix24& g);
+ friend Fix24 operator << (const Fix24& f, int b);
+ friend Fix24 operator >> (const Fix24& f, int b);
+
+ Fix24& operator += (const Fix24& f);
+ Fix24& operator -= (const Fix24& f);
+ Fix24& operator *= (const Fix24& f);
+ Fix24& operator *= (int b);
+ Fix24& operator /= (const Fix24& f);
+
+ Fix24& operator <<=(int b);
+ Fix24& operator >>=(int b);
+
+ friend int operator == (const Fix24& f, const Fix24& g);
+ friend int operator != (const Fix24& f, const Fix24& g);
+ friend int operator >= (const Fix24& f, const Fix24& g);
+ friend int operator <= (const Fix24& f, const Fix24& g);
+ friend int operator > (const Fix24& f, const Fix24& g);
+ friend int operator < (const Fix24& f, const Fix24& g);
+
+ friend istream& operator >> (istream& s, Fix24& f);
+ friend ostream& operator << (ostream& s, const Fix24& f);
+
+ void overflow(long&) const;
+ void range_error(long&) const;
+};
+
+
+//
+// Fix48 class: 48-bit Fixed point data type
+//
+// consists of a 48-bit mantissa (sign bit & 47 data bits).
+//
+
+class Fix48
+{
+ friend class Fix24;
+
+ twolongs m;
+
+ twolongs assign(double d);
+ operator double() const;
+ Fix48(twolongs i);
+
+public:
+ Fix48();
+ Fix48(const Fix48& f);
+ Fix48(const Fix24& f);
+ Fix48(double d);
+ ~Fix48();
+
+ Fix48& operator = (const Fix48& f);
+ Fix48& operator = (const Fix24& f);
+ Fix48& operator = (double d);
+
+ friend twolongs& mantissa(Fix48& f);
+ friend const twolongs& mantissa(const Fix48& f);
+ friend double value(const Fix48& f);
+
+ Fix48 operator + () const;
+ Fix48 operator - () const;
+
+ friend Fix48 operator + (const Fix48& f, const Fix48& g);
+ friend Fix48 operator - (const Fix48& f, const Fix48& g);
+ friend Fix48 operator * (const Fix48& f, int g);
+ friend Fix48 operator * (int g, const Fix48& f);
+ friend Fix48 operator << (const Fix48& f, int b);
+ friend Fix48 operator >> (const Fix48& f, int b);
+
+ friend Fix48 operator * (const Fix24& f, const Fix24& g);
+
+ Fix48& operator += (const Fix48& f);
+ Fix48& operator -= (const Fix48& f);
+ Fix48& operator *= (int b);
+ Fix48& operator <<=(int b);
+ Fix48& operator >>=(int b);
+
+ friend int operator == (const Fix48& f, const Fix48& g);
+ friend int operator != (const Fix48& f, const Fix48& g);
+ friend int operator >= (const Fix48& f, const Fix48& g);
+ friend int operator <= (const Fix48& f, const Fix48& g);
+ friend int operator > (const Fix48& f, const Fix48& g);
+ friend int operator < (const Fix48& f, const Fix48& g);
+
+ friend istream& operator >> (istream& s, Fix48& f);
+ friend ostream& operator << (ostream& s, const Fix48& f);
+
+ void overflow(twolongs& i) const;
+ void range_error(twolongs& i) const;
+};
+
+
+// active error handler declarations
+
+typedef void (*Fix24_peh)(long&);
+typedef void (*Fix48_peh)(twolongs&);
+
+extern Fix24_peh Fix24_overflow_handler;
+extern Fix48_peh Fix48_overflow_handler;
+
+extern Fix24_peh Fix24_range_error_handler;
+extern Fix48_peh Fix48_range_error_handler;
+
+
+// error handler declarations
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define set_overflow_handler sohndl
+#define set_range_error_handler srnghdl
+#endif
+
+extern Fix24_peh set_Fix24_overflow_handler(Fix24_peh);
+extern Fix48_peh set_Fix48_overflow_handler(Fix48_peh);
+extern void set_overflow_handler(Fix24_peh, Fix48_peh);
+
+extern Fix24_peh set_Fix24_range_error_handler(Fix24_peh);
+extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh);
+extern void set_range_error_handler(Fix24_peh, Fix48_peh);
+
+extern void
+ Fix24_ignore(long&),
+ Fix24_overflow_saturate(long&),
+ Fix24_overflow_warning_saturate(long&),
+ Fix24_warning(long&),
+ Fix24_abort(long&);
+
+extern void
+ Fix48_ignore(twolongs&),
+ Fix48_overflow_saturate(twolongs&),
+ Fix48_overflow_warning_saturate(twolongs&),
+ Fix48_warning(twolongs&),
+ Fix48_abort(twolongs&);
+
+
+inline Fix24::~Fix24() {}
+
+inline Fix24::Fix24(long i)
+{
+ m = i;
+}
+
+inline Fix24::Fix24(int i)
+{
+ m = i;
+}
+
+inline Fix24::operator double() const
+{
+ return Fix24_div * m;
+}
+
+inline Fix24::Fix24()
+{
+ m = 0;
+}
+
+inline Fix24::Fix24(const Fix24& f)
+{
+ m = f.m;
+}
+
+inline Fix24::Fix24(double d)
+{
+ m = assign(d);
+}
+
+inline Fix24::Fix24(const Fix48& f)
+{
+ m = f.m.u;
+}
+
+inline Fix24& Fix24::operator=(const Fix24& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix24& Fix24::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+inline Fix24& Fix24::operator=(const Fix48& f)
+{
+ m = f.m.u;
+ return *this;
+}
+
+inline long& mantissa(Fix24& f)
+{
+ return f.m;
+}
+
+inline const long& mantissa(const Fix24& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix24& f)
+{
+ return double(f);
+}
+
+inline Fix24 Fix24::operator+() const
+{
+ return m;
+}
+
+inline Fix24 Fix24::operator-() const
+{
+ return -m;
+}
+
+inline Fix24 operator+(const Fix24& f, const Fix24& g)
+{
+ long sum = f.m + g.m;
+ if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix24 operator-(const Fix24& f, const Fix24& g)
+{
+ long sum = f.m - g.m;
+ if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix24 operator*(const Fix24& a, int b)
+{
+ return a.m * b;
+}
+
+inline Fix24 operator*(int b, const Fix24& a)
+{
+ return a * b;
+}
+
+inline Fix24 operator<<(const Fix24& a, int b)
+{
+ return a.m << b;
+}
+
+inline Fix24 operator>>(const Fix24& a, int b)
+{
+ return (a.m >> b) & (long)0xffffff00;
+}
+
+inline Fix24& Fix24:: operator+=(const Fix24& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix24& Fix24:: operator-=(const Fix24& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix24& Fix24::operator*=(const Fix24& f)
+{
+ return *this = *this * f;
+}
+
+inline Fix24& Fix24:: operator/=(const Fix24& f)
+{
+ return *this = *this / f;
+}
+
+inline Fix24& Fix24:: operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix24& Fix24:: operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline Fix24& Fix24::operator*=(int b)
+{
+ return *this = *this * b;
+}
+
+inline int operator==(const Fix24& f, const Fix24& g)
+{
+ return f.m == g.m;
+}
+
+inline int operator!=(const Fix24& f, const Fix24& g)
+{
+ return f.m != g.m;
+}
+
+inline int operator>=(const Fix24& f, const Fix24& g)
+{
+ return f.m >= g.m;
+}
+
+inline int operator<=(const Fix24& f, const Fix24& g)
+{
+ return f.m <= g.m;
+}
+
+inline int operator>(const Fix24& f, const Fix24& g)
+{
+ return f.m > g.m;
+}
+
+inline int operator<(const Fix24& f, const Fix24& g)
+{
+ return f.m < g.m;
+}
+
+inline istream& operator>>(istream& s, Fix24& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix24& f)
+{
+ return s << double(f);
+}
+
+inline Fix48::~Fix48() {}
+
+inline Fix48::Fix48(twolongs i)
+{
+ m = i;
+}
+
+inline Fix48:: operator double() const
+{
+/*
+ * Note: can't simply do Fix48_div_u * m.u + Fix48_div_l * m.l, because
+ * m.u is signed and m.l is unsigned.
+ */
+ return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l :
+ (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00))
+ + Fix48_div_l * m.l) - 2;
+}
+
+inline Fix48::Fix48()
+{
+ m.u = 0;
+ m.l = 0;
+}
+
+inline Fix48::Fix48(const Fix48& f)
+{
+ m = f.m;
+}
+
+inline Fix48::Fix48(const Fix24& f)
+{
+ m.u = f.m;
+ m.l = 0;
+}
+
+inline Fix48::Fix48(double d)
+{
+ m = assign(d);
+}
+
+inline Fix48& Fix48::operator=(const Fix48& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix48& Fix48::operator=(const Fix24& f)
+{
+ m.u = f.m;
+ m.l = 0;
+ return *this;
+}
+
+inline Fix48& Fix48::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+inline twolongs& mantissa(Fix48& f)
+{
+ return f.m;
+}
+
+inline const twolongs& mantissa(const Fix48& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix48& f)
+{
+ return double(f);
+}
+
+inline Fix48 Fix48::operator+() const
+{
+ return m;
+}
+
+inline Fix48 Fix48::operator-() const
+{
+ twolongs n;
+ n.l = -m.l;
+ n.u = ~m.u + ((n.l ^ m.l) & Fix24_msb ? 0 : Fix24_lsb);
+ return Fix48(n);
+}
+
+inline Fix48 operator*(int b, const Fix48& a)
+{
+ return a * b;
+}
+
+inline Fix48& Fix48::operator+=(const Fix48& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix48& Fix48::operator-=(const Fix48& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix48& Fix48::operator*=(int b)
+{
+ return *this = *this * b;
+}
+
+inline Fix48& Fix48::operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix48& Fix48::operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline int operator==(const Fix48& f, const Fix48& g)
+{
+ return f.m.u == g.m.u && f.m.l == g.m.l;
+}
+
+inline int operator!=(const Fix48& f, const Fix48& g)
+{
+ return f.m.u != g.m.u || f.m.l != g.m.l;
+}
+
+inline int operator>=(const Fix48& f, const Fix48& g)
+{
+ return f.m.u >= g.m.u || (f.m.u == g.m.u && f.m.l >= g.m.l);
+}
+
+inline int operator<=(const Fix48& f, const Fix48& g)
+{
+ return f.m.u <= g.m.u || (f.m.u == g.m.u && f.m.l <= g.m.l);
+}
+
+inline int operator>(const Fix48& f, const Fix48& g)
+{
+ return f.m.u > g.m.u || (f.m.u == g.m.u && f.m.l > g.m.l);
+}
+
+inline int operator<(const Fix48& f, const Fix48& g)
+{
+ return f.m.u < g.m.u || (f.m.u == g.m.u && f.m.l < g.m.l);
+}
+
+inline istream& operator>>(istream& s, Fix48& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix48& f)
+{
+ return s << double(f);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Geom.h b/gnu/lib/libg++/include/Geom.h
new file mode 100644
index 0000000..5cfa39a
--- /dev/null
+++ b/gnu/lib/libg++/include/Geom.h
@@ -0,0 +1,52 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Geometric_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Geometric_h
+
+#include <Random.h>
+
+class Geometric: public Random {
+protected:
+ double pMean;
+public:
+ Geometric(double mean, RNG *gen);
+
+ double mean();
+ double mean(double x);
+
+ virtual double operator()();
+
+};
+
+
+inline Geometric::Geometric(double mean, RNG *gen) : Random(gen)
+{
+ pMean = mean;
+}
+
+
+inline double Geometric::mean() { return pMean; }
+inline double Geometric::mean(double x) {
+ double tmp = pMean; pMean = x; return tmp;
+}
+
+
+#endif
diff --git a/gnu/lib/libg++/include/GetOpt.h b/gnu/lib/libg++/include/GetOpt.h
new file mode 100644
index 0000000..66ecf5c
--- /dev/null
+++ b/gnu/lib/libg++/include/GetOpt.h
@@ -0,0 +1,129 @@
+/* Getopt for GNU.
+ Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+ (Modified by Douglas C. Schmidt for use with GNU G++.)
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of `argv' so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#ifndef GetOpt_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define GetOpt_h 1
+
+#include <std.h>
+#include <stdio.h>
+
+class GetOpt
+{
+private:
+ /* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+ static char *nextchar;
+
+
+ /* Describe how to deal with options that follow non-option ARGV-elements.
+
+ UNSPECIFIED means the caller did not specify anything;
+ the default is then REQUIRE_ORDER if the environment variable
+ _OPTIONS_FIRST is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options.
+ Stop option processing when the first non-option is seen.
+ This is what Unix does.
+
+ PERMUTE is the default. We permute the contents of `argv' as we scan,
+ so that eventually all the options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code zero.
+ Using `-' as the first character of the list of option characters
+ requests this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return EOF with `optind' != ARGC. */
+
+ enum OrderingEnum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER };
+ OrderingEnum ordering;
+
+ /* Handle permutation of arguments. */
+
+ /* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+ static int first_nonopt;
+ static int last_nonopt;
+
+ void exchange (char **argv);
+public:
+ /* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+ char *optarg;
+
+ /* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+ int optind;
+
+ /* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+ int opterr;
+
+ int nargc;
+ char **nargv;
+ const char *noptstring;
+
+ GetOpt (int argc, char **argv, const char *optstring);
+ int operator () (void);
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/HypGeom.h b/gnu/lib/libg++/include/HypGeom.h
new file mode 100644
index 0000000..e16e655
--- /dev/null
+++ b/gnu/lib/libg++/include/HypGeom.h
@@ -0,0 +1,70 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _HyperGeometric_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _HyperGeometric_h
+
+#include <Random.h>
+
+class HyperGeometric: public Random {
+protected:
+ double pMean;
+ double pVariance;
+ double pP;
+ void setState();
+
+public:
+ HyperGeometric(double mean, double variance, RNG *gen);
+
+ double mean();
+ double mean(double x);
+ double variance();
+ double variance(double x);
+
+ virtual double operator()();
+};
+
+
+inline void HyperGeometric::setState() {
+ double z = pVariance / (pMean * pMean);
+ pP = 0.5 * (1.0 - sqrt((z - 1.0) / ( z + 1.0 )));
+}
+
+inline HyperGeometric::HyperGeometric(double mean, double variance, RNG *gen)
+: Random(gen) {
+ pMean = mean; pVariance = variance;
+ setState();
+}
+
+inline double HyperGeometric::mean() { return pMean; };
+
+inline double HyperGeometric::mean(double x) {
+ double t = pMean; pMean = x;
+ setState(); return t;
+}
+
+inline double HyperGeometric::variance() { return pVariance; }
+
+inline double HyperGeometric::variance(double x) {
+ double t = pVariance; pVariance = x;
+ setState(); return t;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Integer.h b/gnu/lib/libg++/include/Integer.h
new file mode 100644
index 0000000..7e67ae5
--- /dev/null
+++ b/gnu/lib/libg++/include/Integer.h
@@ -0,0 +1,1119 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _Integer_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Integer_h 1
+
+#include <iostream.h>
+
+struct IntRep // internal Integer representations
+{
+ unsigned short len; // current length
+ unsigned short sz; // allocated space (0 means static).
+ short sgn; // 1 means >= 0; 0 means < 0
+ unsigned short s[1]; // represented as ushort array starting here
+};
+
+// True if REP is staticly (or manually) allocated,
+// and should not be deleted by an Integer destructor.
+#define STATIC_IntRep(rep) ((rep)->sz==0)
+
+extern IntRep* Ialloc(IntRep*, const unsigned short *, int, int, int);
+extern IntRep* Icalloc(IntRep*, int);
+extern IntRep* Icopy_ulong(IntRep*, unsigned long);
+extern IntRep* Icopy_long(IntRep*, long);
+extern IntRep* Icopy(IntRep*, const IntRep*);
+extern IntRep* Iresize(IntRep*, int);
+extern IntRep* add(const IntRep*, int, const IntRep*, int, IntRep*);
+extern IntRep* add(const IntRep*, int, long, IntRep*);
+extern IntRep* multiply(const IntRep*, const IntRep*, IntRep*);
+extern IntRep* multiply(const IntRep*, long, IntRep*);
+extern IntRep* lshift(const IntRep*, long, IntRep*);
+extern IntRep* lshift(const IntRep*, const IntRep*, int, IntRep*);
+extern IntRep* bitop(const IntRep*, const IntRep*, IntRep*, char);
+extern IntRep* bitop(const IntRep*, long, IntRep*, char);
+extern IntRep* power(const IntRep*, long, IntRep*);
+extern IntRep* div(const IntRep*, const IntRep*, IntRep*);
+extern IntRep* mod(const IntRep*, const IntRep*, IntRep*);
+extern IntRep* div(const IntRep*, long, IntRep*);
+extern IntRep* mod(const IntRep*, long, IntRep*);
+extern IntRep* compl(const IntRep*, IntRep*);
+extern IntRep* abs(const IntRep*, IntRep*);
+extern IntRep* negate(const IntRep*, IntRep*);
+extern IntRep* pow(const IntRep*, long);
+extern IntRep* gcd(const IntRep*, const IntRep* y);
+extern int compare(const IntRep*, const IntRep*);
+extern int compare(const IntRep*, long);
+extern int ucompare(const IntRep*, const IntRep*);
+extern int ucompare(const IntRep*, long);
+extern char* Itoa(const IntRep* x, int base = 10, int width = 0);
+extern char* cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base,
+ int showbase, int width, int align_right,
+ char fillchar, char Xcase, int showpos);
+extern IntRep* atoIntRep(const char* s, int base = 10);
+extern long Itolong(const IntRep*);
+extern int Iislong(const IntRep*);
+extern long lg(const IntRep*);
+
+extern IntRep _ZeroRep, _OneRep, _MinusOneRep;
+
+class Integer
+{
+protected:
+ IntRep* rep;
+public:
+ Integer();
+ Integer(int);
+ Integer(long);
+ Integer(unsigned long);
+ Integer(IntRep*);
+ Integer(const Integer&);
+
+ ~Integer();
+ Integer& operator = (const Integer&);
+ Integer& operator = (long);
+
+// unary operations to self
+
+ Integer& operator ++ ();
+ Integer& operator -- ();
+ void negate(); // negate in-place
+ void abs(); // absolute-value in-place
+ void complement(); // bitwise complement in-place
+
+// assignment-based operations
+
+ Integer& operator += (const Integer&);
+ Integer& operator -= (const Integer&);
+ Integer& operator *= (const Integer&);
+ Integer& operator /= (const Integer&);
+ Integer& operator %= (const Integer&);
+ Integer& operator <<=(const Integer&);
+ Integer& operator >>=(const Integer&);
+ Integer& operator &= (const Integer&);
+ Integer& operator |= (const Integer&);
+ Integer& operator ^= (const Integer&);
+
+ Integer& operator += (long);
+ Integer& operator -= (long);
+ Integer& operator *= (long);
+ Integer& operator /= (long);
+ Integer& operator %= (long);
+ Integer& operator <<=(long);
+ Integer& operator >>=(long);
+ Integer& operator &= (long);
+ Integer& operator |= (long);
+ Integer& operator ^= (long);
+
+// (constructive binary operations are inlined below)
+
+#if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
+ friend Integer operator <? (const Integer& x, const Integer& y); // min
+ friend Integer operator >? (const Integer& x, const Integer& y); // max
+#endif
+
+// builtin Integer functions that must be friends
+
+ friend long lg (const Integer&); // floor log base 2 of abs(x)
+ friend double ratio(const Integer& x, const Integer& y);
+ // return x/y as a double
+
+ friend Integer gcd(const Integer&, const Integer&);
+ friend int even(const Integer&); // true if even
+ friend int odd(const Integer&); // true if odd
+ friend int sign(const Integer&); // returns -1, 0, +1
+
+ friend void (setbit)(Integer& x, long b); // set b'th bit of x
+ friend void clearbit(Integer& x, long b); // clear b'th bit
+ friend int testbit(const Integer& x, long b); // return b'th bit
+
+// procedural versions of operators
+
+ friend void abs(const Integer& x, Integer& dest);
+ friend void negate(const Integer& x, Integer& dest);
+ friend void complement(const Integer& x, Integer& dest);
+
+ friend int compare(const Integer&, const Integer&);
+ friend int ucompare(const Integer&, const Integer&);
+ friend void add(const Integer& x, const Integer& y, Integer& dest);
+ friend void sub(const Integer& x, const Integer& y, Integer& dest);
+ friend void mul(const Integer& x, const Integer& y, Integer& dest);
+ friend void div(const Integer& x, const Integer& y, Integer& dest);
+ friend void mod(const Integer& x, const Integer& y, Integer& dest);
+ friend void divide(const Integer& x, const Integer& y,
+ Integer& q, Integer& r);
+ friend void and(const Integer& x, const Integer& y, Integer& dest);
+ friend void or(const Integer& x, const Integer& y, Integer& dest);
+ friend void xor(const Integer& x, const Integer& y, Integer& dest);
+ friend void lshift(const Integer& x, const Integer& y, Integer& dest);
+ friend void rshift(const Integer& x, const Integer& y, Integer& dest);
+ friend void pow(const Integer& x, const Integer& y, Integer& dest);
+
+ friend int compare(const Integer&, long);
+ friend int ucompare(const Integer&, long);
+ friend void add(const Integer& x, long y, Integer& dest);
+ friend void sub(const Integer& x, long y, Integer& dest);
+ friend void mul(const Integer& x, long y, Integer& dest);
+ friend void div(const Integer& x, long y, Integer& dest);
+ friend void mod(const Integer& x, long y, Integer& dest);
+ friend void divide(const Integer& x, long y, Integer& q, long& r);
+ friend void and(const Integer& x, long y, Integer& dest);
+ friend void or(const Integer& x, long y, Integer& dest);
+ friend void xor(const Integer& x, long y, Integer& dest);
+ friend void lshift(const Integer& x, long y, Integer& dest);
+ friend void rshift(const Integer& x, long y, Integer& dest);
+ friend void pow(const Integer& x, long y, Integer& dest);
+
+ friend int compare(long, const Integer&);
+ friend int ucompare(long, const Integer&);
+ friend void add(long x, const Integer& y, Integer& dest);
+ friend void sub(long x, const Integer& y, Integer& dest);
+ friend void mul(long x, const Integer& y, Integer& dest);
+ friend void and(long x, const Integer& y, Integer& dest);
+ friend void or(long x, const Integer& y, Integer& dest);
+ friend void xor(long x, const Integer& y, Integer& dest);
+
+// coercion & conversion
+
+ int fits_in_long() const { return Iislong(rep); }
+ int fits_in_double() const;
+
+ long as_long() const { return Itolong(rep); }
+ double as_double() const;
+
+ friend char* Itoa(const Integer& x, int base = 10, int width = 0);
+ friend Integer atoI(const char* s, int base = 10);
+ void printon(ostream& s, int base = 10, int width = 0) const;
+
+ friend istream& operator >> (istream& s, Integer& y);
+ friend ostream& operator << (ostream& s, const Integer& y);
+
+// error detection
+
+ int initialized() const;
+ void error(const char* msg) const;
+ int OK() const;
+};
+
+
+// (These are declared inline)
+
+ int operator == (const Integer&, const Integer&);
+ int operator == (const Integer&, long);
+ int operator != (const Integer&, const Integer&);
+ int operator != (const Integer&, long);
+ int operator < (const Integer&, const Integer&);
+ int operator < (const Integer&, long);
+ int operator <= (const Integer&, const Integer&);
+ int operator <= (const Integer&, long);
+ int operator > (const Integer&, const Integer&);
+ int operator > (const Integer&, long);
+ int operator >= (const Integer&, const Integer&);
+ int operator >= (const Integer&, long);
+ Integer operator - (const Integer&);
+ Integer operator ~ (const Integer&);
+ Integer operator + (const Integer&, const Integer&);
+ Integer operator + (const Integer&, long);
+ Integer operator + (long, const Integer&);
+ Integer operator - (const Integer&, const Integer&);
+ Integer operator - (const Integer&, long);
+ Integer operator - (long, const Integer&);
+ Integer operator * (const Integer&, const Integer&);
+ Integer operator * (const Integer&, long);
+ Integer operator * (long, const Integer&);
+ Integer operator / (const Integer&, const Integer&);
+ Integer operator / (const Integer&, long);
+ Integer operator % (const Integer&, const Integer&);
+ Integer operator % (const Integer&, long);
+ Integer operator << (const Integer&, const Integer&);
+ Integer operator << (const Integer&, long);
+ Integer operator >> (const Integer&, const Integer&);
+ Integer operator >> (const Integer&, long);
+ Integer operator & (const Integer&, const Integer&);
+ Integer operator & (const Integer&, long);
+ Integer operator & (long, const Integer&);
+ Integer operator | (const Integer&, const Integer&);
+ Integer operator | (const Integer&, long);
+ Integer operator | (long, const Integer&);
+ Integer operator ^ (const Integer&, const Integer&);
+ Integer operator ^ (const Integer&, long);
+ Integer operator ^ (long, const Integer&);
+
+ Integer abs(const Integer&); // absolute value
+ Integer sqr(const Integer&); // square
+
+ Integer pow(const Integer& x, const Integer& y);
+ Integer pow(const Integer& x, long y);
+ Integer Ipow(long x, long y); // x to the y as Integer
+
+
+extern char* dec(const Integer& x, int width = 0);
+extern char* oct(const Integer& x, int width = 0);
+extern char* hex(const Integer& x, int width = 0);
+extern Integer sqrt(const Integer&); // floor of square root
+extern Integer lcm(const Integer& x, const Integer& y); // least common mult
+
+
+typedef Integer IntTmp; // for backward compatibility
+
+inline Integer::Integer() :rep(&_ZeroRep) {}
+
+inline Integer::Integer(IntRep* r) :rep(r) {}
+
+inline Integer::Integer(int y) :rep(Icopy_long(0, (long)y)) {}
+
+inline Integer::Integer(long y) :rep(Icopy_long(0, y)) {}
+
+inline Integer::Integer(unsigned long y) :rep(Icopy_ulong(0, y)) {}
+
+inline Integer::Integer(const Integer& y) :rep(Icopy(0, y.rep)) {}
+
+inline Integer::~Integer() { if (rep && !STATIC_IntRep(rep)) delete rep; }
+
+inline Integer& Integer::operator = (const Integer& y)
+{
+ rep = Icopy(rep, y.rep);
+ return *this;
+}
+
+inline Integer& Integer::operator = (long y)
+{
+ rep = Icopy_long(rep, y);
+ return *this;
+}
+
+inline int Integer::initialized() const
+{
+ return rep != 0;
+}
+
+// procedural versions
+
+inline int compare(const Integer& x, const Integer& y)
+{
+ return compare(x.rep, y.rep);
+}
+
+inline int ucompare(const Integer& x, const Integer& y)
+{
+ return ucompare(x.rep, y.rep);
+}
+
+inline int compare(const Integer& x, long y)
+{
+ return compare(x.rep, y);
+}
+
+inline int ucompare(const Integer& x, long y)
+{
+ return ucompare(x.rep, y);
+}
+
+inline int compare(long x, const Integer& y)
+{
+ return -compare(y.rep, x);
+}
+
+inline int ucompare(long x, const Integer& y)
+{
+ return -ucompare(y.rep, x);
+}
+
+inline void add(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = add(x.rep, 0, y.rep, 0, dest.rep);
+}
+
+inline void sub(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = add(x.rep, 0, y.rep, 1, dest.rep);
+}
+
+inline void mul(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = multiply(x.rep, y.rep, dest.rep);
+}
+
+inline void div(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = div(x.rep, y.rep, dest.rep);
+}
+
+inline void mod(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = mod(x.rep, y.rep, dest.rep);
+}
+
+inline void and(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = bitop(x.rep, y.rep, dest.rep, '&');
+}
+
+inline void or(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = bitop(x.rep, y.rep, dest.rep, '|');
+}
+
+inline void xor(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = bitop(x.rep, y.rep, dest.rep, '^');
+}
+
+inline void lshift(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = lshift(x.rep, y.rep, 0, dest.rep);
+}
+
+inline void rshift(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = lshift(x.rep, y.rep, 1, dest.rep);
+}
+
+inline void pow(const Integer& x, const Integer& y, Integer& dest)
+{
+ dest.rep = power(x.rep, Itolong(y.rep), dest.rep); // not incorrect
+}
+
+inline void add(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = add(x.rep, 0, y, dest.rep);
+}
+
+inline void sub(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = add(x.rep, 0, -y, dest.rep);
+}
+
+inline void mul(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = multiply(x.rep, y, dest.rep);
+}
+
+inline void div(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = div(x.rep, y, dest.rep);
+}
+
+inline void mod(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = mod(x.rep, y, dest.rep);
+}
+
+inline void and(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = bitop(x.rep, y, dest.rep, '&');
+}
+
+inline void or(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = bitop(x.rep, y, dest.rep, '|');
+}
+
+inline void xor(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = bitop(x.rep, y, dest.rep, '^');
+}
+
+inline void lshift(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = lshift(x.rep, y, dest.rep);
+}
+
+inline void rshift(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = lshift(x.rep, -y, dest.rep);
+}
+
+inline void pow(const Integer& x, long y, Integer& dest)
+{
+ dest.rep = power(x.rep, y, dest.rep);
+}
+
+inline void abs(const Integer& x, Integer& dest)
+{
+ dest.rep = abs(x.rep, dest.rep);
+}
+
+inline void negate(const Integer& x, Integer& dest)
+{
+ dest.rep = negate(x.rep, dest.rep);
+}
+
+inline void complement(const Integer& x, Integer& dest)
+{
+ dest.rep = compl(x.rep, dest.rep);
+}
+
+inline void add(long x, const Integer& y, Integer& dest)
+{
+ dest.rep = add(y.rep, 0, x, dest.rep);
+}
+
+inline void sub(long x, const Integer& y, Integer& dest)
+{
+ dest.rep = add(y.rep, 1, x, dest.rep);
+}
+
+inline void mul(long x, const Integer& y, Integer& dest)
+{
+ dest.rep = multiply(y.rep, x, dest.rep);
+}
+
+inline void and(long x, const Integer& y, Integer& dest)
+{
+ dest.rep = bitop(y.rep, x, dest.rep, '&');
+}
+
+inline void or(long x, const Integer& y, Integer& dest)
+{
+ dest.rep = bitop(y.rep, x, dest.rep, '|');
+}
+
+inline void xor(long x, const Integer& y, Integer& dest)
+{
+ dest.rep = bitop(y.rep, x, dest.rep, '^');
+}
+
+
+// operator versions
+
+inline int operator == (const Integer& x, const Integer& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator == (const Integer& x, long y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator != (const Integer& x, const Integer& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator != (const Integer& x, long y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator < (const Integer& x, const Integer& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator < (const Integer& x, long y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator <= (const Integer& x, const Integer& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator <= (const Integer& x, long y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator > (const Integer& x, const Integer& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator > (const Integer& x, long y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator >= (const Integer& x, const Integer& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator >= (const Integer& x, long y)
+{
+ return compare(x, y) >= 0;
+}
+
+
+inline Integer& Integer::operator += (const Integer& y)
+{
+ add(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator += (long y)
+{
+ add(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator ++ ()
+{
+ add(*this, 1, *this);
+ return *this;
+}
+
+
+inline Integer& Integer::operator -= (const Integer& y)
+{
+ sub(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator -= (long y)
+{
+ sub(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator -- ()
+{
+ add(*this, -1, *this);
+ return *this;
+}
+
+
+
+inline Integer& Integer::operator *= (const Integer& y)
+{
+ mul(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator *= (long y)
+{
+ mul(*this, y, *this);
+ return *this;
+}
+
+
+inline Integer& Integer::operator &= (const Integer& y)
+{
+ and(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator &= (long y)
+{
+ and(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator |= (const Integer& y)
+{
+ or(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator |= (long y)
+{
+ or(*this, y, *this);
+ return *this;
+}
+
+
+inline Integer& Integer::operator ^= (const Integer& y)
+{
+ xor(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator ^= (long y)
+{
+ xor(*this, y, *this);
+ return *this;
+}
+
+
+
+inline Integer& Integer::operator /= (const Integer& y)
+{
+ div(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator /= (long y)
+{
+ div(*this, y, *this);
+ return *this;
+}
+
+
+inline Integer& Integer::operator <<= (const Integer& y)
+{
+ lshift(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator <<= (long y)
+{
+ lshift(*this, y, *this);
+ return *this;
+}
+
+
+inline Integer& Integer::operator >>= (const Integer& y)
+{
+ rshift(*this, y, *this);
+ return *this;
+}
+
+inline Integer& Integer::operator >>= (long y)
+{
+ rshift(*this, y, *this);
+ return *this;
+}
+
+#if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
+inline Integer operator <? (const Integer& x, const Integer& y)
+{
+ return (compare(x.rep, y.rep) <= 0) ? x : y;
+}
+
+inline Integer operator >? (const Integer& x, const Integer& y)
+{
+ return (compare(x.rep, y.rep) >= 0)? x : y;
+}
+#endif
+
+
+inline void Integer::abs()
+{
+ ::abs(*this, *this);
+}
+
+inline void Integer::negate()
+{
+ ::negate(*this, *this);
+}
+
+
+inline void Integer::complement()
+{
+ ::complement(*this, *this);
+}
+
+
+inline int sign(const Integer& x)
+{
+ return (x.rep->len == 0) ? 0 : ( (x.rep->sgn == 1) ? 1 : -1 );
+}
+
+inline int even(const Integer& y)
+{
+ return y.rep->len == 0 || !(y.rep->s[0] & 1);
+}
+
+inline int odd(const Integer& y)
+{
+ return y.rep->len > 0 && (y.rep->s[0] & 1);
+}
+
+inline char* Itoa(const Integer& y, int base, int width)
+{
+ return Itoa(y.rep, base, width);
+}
+
+
+
+inline long lg(const Integer& x)
+{
+ return lg(x.rep);
+}
+
+// constructive operations
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+inline Integer operator + (const Integer& x, const Integer& y) return r
+{
+ add(x, y, r);
+}
+
+inline Integer operator + (const Integer& x, long y) return r
+{
+ add(x, y, r);
+}
+
+inline Integer operator + (long x, const Integer& y) return r
+{
+ add(x, y, r);
+}
+
+inline Integer operator - (const Integer& x, const Integer& y) return r
+{
+ sub(x, y, r);
+}
+
+inline Integer operator - (const Integer& x, long y) return r
+{
+ sub(x, y, r);
+}
+
+inline Integer operator - (long x, const Integer& y) return r
+{
+ sub(x, y, r);
+}
+
+inline Integer operator * (const Integer& x, const Integer& y) return r
+{
+ mul(x, y, r);
+}
+
+inline Integer operator * (const Integer& x, long y) return r
+{
+ mul(x, y, r);
+}
+
+inline Integer operator * (long x, const Integer& y) return r
+{
+ mul(x, y, r);
+}
+
+inline Integer sqr(const Integer& x) return r
+{
+ mul(x, x, r);
+}
+
+inline Integer operator & (const Integer& x, const Integer& y) return r
+{
+ and(x, y, r);
+}
+
+inline Integer operator & (const Integer& x, long y) return r
+{
+ and(x, y, r);
+}
+
+inline Integer operator & (long x, const Integer& y) return r
+{
+ and(x, y, r);
+}
+
+inline Integer operator | (const Integer& x, const Integer& y) return r
+{
+ or(x, y, r);
+}
+
+inline Integer operator | (const Integer& x, long y) return r
+{
+ or(x, y, r);
+}
+
+inline Integer operator | (long x, const Integer& y) return r
+{
+ or(x, y, r);
+}
+
+inline Integer operator ^ (const Integer& x, const Integer& y) return r
+{
+ xor(x, y, r);
+}
+
+inline Integer operator ^ (const Integer& x, long y) return r
+{
+ xor(x, y, r);
+}
+
+inline Integer operator ^ (long x, const Integer& y) return r
+{
+ xor(x, y, r);
+}
+
+inline Integer operator / (const Integer& x, const Integer& y) return r
+{
+ div(x, y, r);
+}
+
+inline Integer operator / (const Integer& x, long y) return r
+{
+ div(x, y, r);
+}
+
+inline Integer operator % (const Integer& x, const Integer& y) return r
+{
+ mod(x, y, r);
+}
+
+inline Integer operator % (const Integer& x, long y) return r
+{
+ mod(x, y, r);
+}
+
+inline Integer operator << (const Integer& x, const Integer& y) return r
+{
+ lshift(x, y, r);
+}
+
+inline Integer operator << (const Integer& x, long y) return r
+{
+ lshift(x, y, r);
+}
+
+inline Integer operator >> (const Integer& x, const Integer& y) return r;
+{
+ rshift(x, y, r);
+}
+
+inline Integer operator >> (const Integer& x, long y) return r
+{
+ rshift(x, y, r);
+}
+
+inline Integer pow(const Integer& x, long y) return r
+{
+ pow(x, y, r);
+}
+
+inline Integer Ipow(long x, long y) return r(x)
+{
+ pow(r, y, r);
+}
+
+inline Integer pow(const Integer& x, const Integer& y) return r
+{
+ pow(x, y, r);
+}
+
+
+
+inline Integer abs(const Integer& x) return r
+{
+ abs(x, r);
+}
+
+inline Integer operator - (const Integer& x) return r
+{
+ negate(x, r);
+}
+
+inline Integer operator ~ (const Integer& x) return r
+{
+ complement(x, r);
+}
+
+inline Integer atoI(const char* s, int base) return r
+{
+ r.rep = atoIntRep(s, base);
+}
+
+inline Integer gcd(const Integer& x, const Integer& y) return r
+{
+ r.rep = gcd(x.rep, y.rep);
+}
+
+#else /* NO_NRV */
+
+inline Integer operator + (const Integer& x, const Integer& y)
+{
+ Integer r; add(x, y, r); return r;
+}
+
+inline Integer operator + (const Integer& x, long y)
+{
+ Integer r; add(x, y, r); return r;
+}
+
+inline Integer operator + (long x, const Integer& y)
+{
+ Integer r; add(x, y, r); return r;
+}
+
+inline Integer operator - (const Integer& x, const Integer& y)
+{
+ Integer r; sub(x, y, r); return r;
+}
+
+inline Integer operator - (const Integer& x, long y)
+{
+ Integer r; sub(x, y, r); return r;
+}
+
+inline Integer operator - (long x, const Integer& y)
+{
+ Integer r; sub(x, y, r); return r;
+}
+
+inline Integer operator * (const Integer& x, const Integer& y)
+{
+ Integer r; mul(x, y, r); return r;
+}
+
+inline Integer operator * (const Integer& x, long y)
+{
+ Integer r; mul(x, y, r); return r;
+}
+
+inline Integer operator * (long x, const Integer& y)
+{
+ Integer r; mul(x, y, r); return r;
+}
+
+inline Integer sqr(const Integer& x)
+{
+ Integer r; mul(x, x, r); return r;
+}
+
+inline Integer operator & (const Integer& x, const Integer& y)
+{
+ Integer r; and(x, y, r); return r;
+}
+
+inline Integer operator & (const Integer& x, long y)
+{
+ Integer r; and(x, y, r); return r;
+}
+
+inline Integer operator & (long x, const Integer& y)
+{
+ Integer r; and(x, y, r); return r;
+}
+
+inline Integer operator | (const Integer& x, const Integer& y)
+{
+ Integer r; or(x, y, r); return r;
+}
+
+inline Integer operator | (const Integer& x, long y)
+{
+ Integer r; or(x, y, r); return r;
+}
+
+inline Integer operator | (long x, const Integer& y)
+{
+ Integer r; or(x, y, r); return r;
+}
+
+inline Integer operator ^ (const Integer& x, const Integer& y)
+{
+ Integer r; xor(x, y, r); return r;
+}
+
+inline Integer operator ^ (const Integer& x, long y)
+{
+ Integer r; xor(x, y, r); return r;
+}
+
+inline Integer operator ^ (long x, const Integer& y)
+{
+ Integer r; xor(x, y, r); return r;
+}
+
+inline Integer operator / (const Integer& x, const Integer& y)
+{
+ Integer r; div(x, y, r); return r;
+}
+
+inline Integer operator / (const Integer& x, long y)
+{
+ Integer r; div(x, y, r); return r;
+}
+
+inline Integer operator % (const Integer& x, const Integer& y)
+{
+ Integer r; mod(x, y, r); return r;
+}
+
+inline Integer operator % (const Integer& x, long y)
+{
+ Integer r; mod(x, y, r); return r;
+}
+
+inline Integer operator << (const Integer& x, const Integer& y)
+{
+ Integer r; lshift(x, y, r); return r;
+}
+
+inline Integer operator << (const Integer& x, long y)
+{
+ Integer r; lshift(x, y, r); return r;
+}
+
+inline Integer operator >> (const Integer& x, const Integer& y)
+{
+ Integer r; rshift(x, y, r); return r;
+}
+
+inline Integer operator >> (const Integer& x, long y)
+{
+ Integer r; rshift(x, y, r); return r;
+}
+
+inline Integer pow(const Integer& x, long y)
+{
+ Integer r; pow(x, y, r); return r;
+}
+
+inline Integer Ipow(long x, long y)
+{
+ Integer r(x); pow(r, y, r); return r;
+}
+
+inline Integer pow(const Integer& x, const Integer& y)
+{
+ Integer r; pow(x, y, r); return r;
+}
+
+
+
+inline Integer abs(const Integer& x)
+{
+ Integer r; abs(x, r); return r;
+}
+
+inline Integer operator - (const Integer& x)
+{
+ Integer r; negate(x, r); return r;
+}
+
+inline Integer operator ~ (const Integer& x)
+{
+ Integer r; complement(x, r); return r;
+}
+
+inline Integer atoI(const char* s, int base)
+{
+ Integer r; r.rep = atoIntRep(s, base); return r;
+}
+
+inline Integer gcd(const Integer& x, const Integer& y)
+{
+ Integer r; r.rep = gcd(x.rep, y.rep); return r;
+}
+
+#endif /* NO_NRV */
+
+inline Integer& Integer::operator %= (const Integer& y)
+{
+ *this = *this % y; // mod(*this, y, *this) doesn't work.
+ return *this;
+}
+
+inline Integer& Integer::operator %= (long y)
+{
+ *this = *this % y; // mod(*this, y, *this) doesn't work.
+ return *this;
+}
+#endif /* !_Integer_h */
diff --git a/gnu/lib/libg++/include/Integer.hP b/gnu/lib/libg++/include/Integer.hP
new file mode 100644
index 0000000..b8a8039
--- /dev/null
+++ b/gnu/lib/libg++/include/Integer.hP
@@ -0,0 +1,30 @@
+// Stuff used to implement the Integer class.
+// WARNING: Its internals WILL change!
+
+/*
+ Sizes of shifts for multiple-precision arithmetic.
+ These should not be changed unless Integer representation
+ as unsigned shorts is changed in the implementation files.
+*/
+
+#define I_SHIFT (sizeof(short) * CHAR_BIT)
+#define I_RADIX ((unsigned long)(1L << I_SHIFT))
+#define I_MAXNUM ((unsigned long)((I_RADIX - 1)))
+#define I_MINNUM ((unsigned long)(I_RADIX >> 1))
+#define I_POSITIVE 1
+#define I_NEGATIVE 0
+
+/* All routines assume SHORT_PER_LONG > 1 */
+#define SHORT_PER_LONG ((unsigned)(((sizeof(long) + sizeof(short) - 1) / sizeof(short))))
+#define CHAR_PER_LONG ((unsigned)sizeof(long))
+
+/*
+ minimum and maximum sizes for an IntRep
+*/
+
+#define MINIntRep_SIZE 16
+#define MAXIntRep_SIZE I_MAXNUM
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
diff --git a/gnu/lib/libg++/include/LogNorm.h b/gnu/lib/libg++/include/LogNorm.h
new file mode 100644
index 0000000..ac98141
--- /dev/null
+++ b/gnu/lib/libg++/include/LogNorm.h
@@ -0,0 +1,78 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _LogNormal_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _LogNormal_h
+
+#include <Normal.h>
+
+class LogNormal: public Normal {
+protected:
+ double logMean;
+ double logVariance;
+ void setState();
+public:
+ LogNormal(double mean, double variance, RNG *gen);
+ double mean();
+ double mean(double x);
+ double variance();
+ double variance(double x);
+ virtual double operator()();
+};
+
+
+inline void LogNormal::setState()
+{
+ double m2 = logMean * logMean;
+ pMean = log(m2 / sqrt(logVariance + m2) );
+// from ch@heike.informatik.uni-dortmund.de:
+// (was pVariance = log((sqrt(logVariance + m2)/m2 )); )
+ pStdDev = sqrt(log((logVariance + m2)/m2 ));
+}
+
+inline LogNormal::LogNormal(double mean, double variance, RNG *gen)
+ : Normal(mean, variance, gen)
+{
+ logMean = mean;
+ logVariance = variance;
+ setState();
+}
+
+inline double LogNormal::mean() {
+ return logMean;
+}
+
+inline double LogNormal::mean(double x)
+{
+ double t=logMean; logMean = x; setState();
+ return t;
+}
+
+inline double LogNormal::variance() {
+ return logVariance;
+}
+
+inline double LogNormal::variance(double x)
+{
+ double t=logVariance; logVariance = x; setState();
+ return t;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/MLCG.h b/gnu/lib/libg++/include/MLCG.h
new file mode 100644
index 0000000..8f104a1
--- /dev/null
+++ b/gnu/lib/libg++/include/MLCG.h
@@ -0,0 +1,87 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _MLCG_h
+#define _MLCG_h 1
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <RNG.h>
+#include <math.h>
+
+//
+// Multiplicative Linear Conguential Generator
+//
+
+class MLCG : public RNG {
+ _G_int32_t initialSeedOne;
+ _G_int32_t initialSeedTwo;
+ _G_int32_t seedOne;
+ _G_int32_t seedTwo;
+
+protected:
+
+public:
+ MLCG(_G_int32_t seed1 = 0, _G_int32_t seed2 = 1);
+ //
+ // Return a long-words word of random bits
+ //
+ virtual unsigned long asLong();
+ virtual void reset();
+ _G_int32_t seed1();
+ void seed1(_G_int32_t);
+ _G_int32_t seed2();
+ void seed2(_G_int32_t);
+ void reseed(_G_int32_t, _G_int32_t);
+};
+
+inline _G_int32_t
+MLCG::seed1()
+{
+ return(seedOne);
+}
+
+inline void
+MLCG::seed1(_G_int32_t s)
+{
+ initialSeedOne = s;
+ reset();
+}
+
+inline _G_int32_t
+MLCG::seed2()
+{
+ return(seedTwo);
+}
+
+inline void
+MLCG::seed2(_G_int32_t s)
+{
+ initialSeedTwo = s;
+ reset();
+}
+
+inline void
+MLCG::reseed(_G_int32_t s1, _G_int32_t s2)
+{
+ initialSeedOne = s1;
+ initialSeedTwo = s2;
+ reset();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/NegExp.h b/gnu/lib/libg++/include/NegExp.h
new file mode 100644
index 0000000..b96f913
--- /dev/null
+++ b/gnu/lib/libg++/include/NegExp.h
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _NegativeExpntl_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _NegativeExpntl_h 1
+
+
+//
+// Negative Exponential Random Numbers
+//
+//
+
+#include <Random.h>
+
+class NegativeExpntl: public Random {
+protected:
+ double pMean;
+public:
+ NegativeExpntl(double xmean, RNG *gen);
+ double mean();
+ double mean(double x);
+
+ virtual double operator()();
+};
+
+
+inline NegativeExpntl::NegativeExpntl(double xmean, RNG *gen)
+: Random(gen) {
+ pMean = xmean;
+}
+
+inline double NegativeExpntl::mean() { return pMean; }
+inline double NegativeExpntl::mean(double x) {
+ double t = pMean; pMean = x;
+ return t;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Normal.h b/gnu/lib/libg++/include/Normal.h
new file mode 100644
index 0000000..8c8358e
--- /dev/null
+++ b/gnu/lib/libg++/include/Normal.h
@@ -0,0 +1,66 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Normal_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Normal_h
+
+#include <Random.h>
+
+class Normal: public Random {
+ char haveCachedNormal;
+ double cachedNormal;
+
+protected:
+ double pMean;
+ double pVariance;
+ double pStdDev;
+
+public:
+ Normal(double xmean, double xvariance, RNG *gen);
+ double mean();
+ double mean(double x);
+ double variance();
+ double variance(double x);
+ virtual double operator()();
+};
+
+
+inline Normal::Normal(double xmean, double xvariance, RNG *gen)
+: Random(gen) {
+ pMean = xmean;
+ pVariance = xvariance;
+ pStdDev = sqrt(pVariance);
+ haveCachedNormal = 0;
+}
+
+inline double Normal::mean() { return pMean; };
+inline double Normal::mean(double x) {
+ double t=pMean; pMean = x;
+ return t;
+}
+
+inline double Normal::variance() { return pVariance; }
+inline double Normal::variance(double x) {
+ double t=pVariance; pVariance = x;
+ pStdDev = sqrt(pVariance);
+ return t;
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/Obstack.h b/gnu/lib/libg++/include/Obstack.h
new file mode 100644
index 0000000..384157f
--- /dev/null
+++ b/gnu/lib/libg++/include/Obstack.h
@@ -0,0 +1,216 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef _Obstack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Obstack_h 1
+
+#include <std.h>
+
+class Obstack
+{
+ struct _obstack_chunk
+ {
+ char* limit;
+ _obstack_chunk* prev;
+ char contents[4];
+ };
+
+protected:
+ long chunksize;
+ _obstack_chunk* chunk;
+ char* objectbase;
+ char* nextfree;
+ char* chunklimit;
+ int alignmentmask;
+
+ void _free(void* obj);
+ void newchunk(int size);
+
+public:
+ Obstack(int size = 4080, int alignment = 4); // 4080=4096-mallocslop
+
+ ~Obstack();
+
+ void* base();
+ void* next_free();
+ int alignment_mask();
+ int chunk_size();
+ int size();
+ int room();
+ int contains(void* p); // does Obstack hold pointer p?
+
+ void grow(const void* data, int size);
+ void grow(const void* data, int size, char terminator);
+ void grow(const char* s);
+ void grow(char c);
+ void grow_fast(char c);
+ void blank(int size);
+ void blank_fast(int size);
+
+ void* finish();
+ void* finish(char terminator);
+
+ void* copy(const void* data, int size);
+ void* copy(const void* data, int size, char terminator);
+ void* copy(const char* s);
+ void* copy(char c);
+ void* alloc(int size);
+
+ void free(void* obj);
+ void shrink(int size = 1); // suggested by ken@cs.rochester.edu
+
+ int OK(); // rep invariant
+};
+
+
+inline Obstack::~Obstack()
+{
+ _free(0);
+}
+
+inline void* Obstack::base()
+{
+ return objectbase;
+}
+
+inline void* Obstack::next_free()
+{
+ return nextfree;
+}
+
+inline int Obstack::alignment_mask()
+{
+ return alignmentmask;
+}
+
+inline int Obstack::chunk_size()
+{
+ return chunksize;
+}
+
+inline int Obstack::size()
+{
+ return nextfree - objectbase;
+}
+
+inline int Obstack::room()
+{
+ return chunklimit - nextfree;
+}
+
+inline void Obstack:: grow(const void* data, int size)
+{
+ if (nextfree+size > chunklimit)
+ newchunk(size);
+ memcpy(nextfree, data, size);
+ nextfree += size;
+}
+
+inline void Obstack:: grow(const void* data, int size, char terminator)
+{
+ if (nextfree+size+1 > chunklimit)
+ newchunk(size+1);
+ memcpy(nextfree, data, size);
+ nextfree += size;
+ *(nextfree)++ = terminator;
+}
+
+inline void Obstack:: grow(const char* s)
+{
+ grow((const void*)s, strlen(s), 0);
+}
+
+inline void Obstack:: grow(char c)
+{
+ if (nextfree+1 > chunklimit)
+ newchunk(1);
+ *(nextfree)++ = c;
+}
+
+inline void Obstack:: blank(int size)
+{
+ if (nextfree+size > chunklimit)
+ newchunk(size);
+ nextfree += size;
+}
+
+inline void* Obstack::finish(char terminator)
+{
+ grow(terminator);
+ return finish();
+}
+
+inline void* Obstack::copy(const void* data, int size)
+{
+ grow (data, size);
+ return finish();
+}
+
+inline void* Obstack::copy(const void* data, int size, char terminator)
+{
+ grow(data, size, terminator);
+ return finish();
+}
+
+inline void* Obstack::copy(const char* s)
+{
+ grow((const void*)s, strlen(s), 0);
+ return finish();
+}
+
+inline void* Obstack::copy(char c)
+{
+ grow(c);
+ return finish();
+}
+
+inline void* Obstack::alloc(int size)
+{
+ blank(size);
+ return finish();
+}
+
+inline void Obstack:: free(void* obj)
+{
+ if (obj >= (void*)chunk && obj<(void*)chunklimit)
+ nextfree = objectbase = (char *) obj;
+ else
+ _free(obj);
+}
+
+inline void Obstack:: grow_fast(char c)
+{
+ *(nextfree)++ = c;
+}
+
+inline void Obstack:: blank_fast(int size)
+{
+ nextfree += size;
+}
+
+inline void Obstack:: shrink(int size) // from ken@cs.rochester.edu
+{
+ if (nextfree >= objectbase + size)
+ nextfree -= size;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Pix.h b/gnu/lib/libg++/include/Pix.h
new file mode 100644
index 0000000..be90525
--- /dev/null
+++ b/gnu/lib/libg++/include/Pix.h
@@ -0,0 +1,5 @@
+
+#ifndef _Pix_h
+#define _Pix_h 1
+typedef void* Pix;
+#endif
diff --git a/gnu/lib/libg++/include/PlotFile.h b/gnu/lib/libg++/include/PlotFile.h
new file mode 100644
index 0000000..91ab6ae
--- /dev/null
+++ b/gnu/lib/libg++/include/PlotFile.h
@@ -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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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.
+*/
+
+
+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);
+};
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gnu/lib/libg++/include/Poisson.h b/gnu/lib/libg++/include/Poisson.h
new file mode 100644
index 0000000..e585145
--- /dev/null
+++ b/gnu/lib/libg++/include/Poisson.h
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Poisson_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Poisson_h
+
+#include <Random.h>
+
+class Poisson: public Random {
+protected:
+ double pMean;
+public:
+ Poisson(double mean, RNG *gen);
+
+ double mean();
+ double mean(double x);
+
+ virtual double operator()();
+};
+
+
+inline Poisson::Poisson(double mean, RNG *gen)
+: Random(gen) {
+ pMean = mean;
+}
+
+inline double Poisson::mean() { return pMean; }
+inline double Poisson::mean(double x) {
+ double t = pMean;
+ pMean = x;
+ return t;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/RNG.h b/gnu/lib/libg++/include/RNG.h
new file mode 100644
index 0000000..43d95b7
--- /dev/null
+++ b/gnu/lib/libg++/include/RNG.h
@@ -0,0 +1,58 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _RNG_h
+#define _RNG_h 1
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <assert.h>
+#include <math.h>
+#include <_G_config.h>
+
+union PrivateRNGSingleType { // used to access floats as unsigneds
+ float s;
+ _G_uint32_t u;
+};
+
+union PrivateRNGDoubleType { // used to access doubles as unsigneds
+ double d;
+ _G_uint32_t u[2];
+};
+
+//
+// Base class for Random Number Generators. See ACG and MLCG for instances.
+//
+class RNG {
+ static PrivateRNGSingleType singleMantissa; // mantissa bit vector
+ static PrivateRNGDoubleType doubleMantissa; // mantissa bit vector
+public:
+ RNG();
+ //
+ // Return a long-words word of random bits
+ //
+ virtual unsigned long asLong() = 0;
+ virtual void reset() = 0;
+ //
+ // Return random bits converted to either a float or a double
+ //
+ float asFloat();
+ double asDouble();
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/Random.h b/gnu/lib/libg++/include/Random.h
new file mode 100644
index 0000000..925698f
--- /dev/null
+++ b/gnu/lib/libg++/include/Random.h
@@ -0,0 +1,54 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Random_h
+#define _Random_h 1
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <math.h>
+#include <RNG.h>
+
+class Random {
+protected:
+ RNG *pGenerator;
+public:
+ Random(RNG *generator);
+ virtual double operator()() = 0;
+
+ RNG *generator();
+ void generator(RNG *p);
+};
+
+
+inline Random::Random(RNG *gen)
+{
+ pGenerator = gen;
+}
+
+inline RNG *Random::generator()
+{
+ return(pGenerator);
+}
+
+inline void Random::generator(RNG *p)
+{
+ pGenerator = p;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Rational.h b/gnu/lib/libg++/include/Rational.h
new file mode 100644
index 0000000..131aabc
--- /dev/null
+++ b/gnu/lib/libg++/include/Rational.h
@@ -0,0 +1,288 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _Rational_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Rational_h 1
+
+#include <Integer.h>
+#include <math.h>
+
+class Rational
+{
+protected:
+ Integer num;
+ Integer den;
+
+ void normalize();
+
+public:
+ Rational();
+ Rational(double);
+ Rational(int n);
+ Rational(long n);
+ Rational(int n, int d);
+ Rational(long n, long d);
+ Rational(long n, unsigned long d);
+ Rational(unsigned long n, long d);
+ Rational(unsigned long n, unsigned long d);
+ Rational(const Integer& n);
+ Rational(const Integer& n, const Integer& d);
+ Rational(const Rational&);
+
+ ~Rational();
+
+ Rational& operator = (const Rational& y);
+
+ friend int operator == (const Rational& x, const Rational& y);
+ friend int operator != (const Rational& x, const Rational& y);
+ friend int operator < (const Rational& x, const Rational& y);
+ friend int operator <= (const Rational& x, const Rational& y);
+ friend int operator > (const Rational& x, const Rational& y);
+ friend int operator >= (const Rational& x, const Rational& y);
+
+ friend Rational operator + (const Rational& x, const Rational& y);
+ friend Rational operator - (const Rational& x, const Rational& y);
+ friend Rational operator * (const Rational& x, const Rational& y);
+ friend Rational operator / (const Rational& x, const Rational& y);
+
+ Rational& operator += (const Rational& y);
+ Rational& operator -= (const Rational& y);
+ Rational& operator *= (const Rational& y);
+ Rational& operator /= (const Rational& y);
+
+#if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
+ friend Rational operator <? (const Rational& x, const Rational& y); // min
+ friend Rational operator >? (const Rational& x, const Rational& y); // max
+#endif
+
+ friend Rational operator - (const Rational& x);
+
+
+// builtin Rational functions
+
+
+ void negate(); // x = -x
+ void invert(); // x = 1/x
+
+ friend int sign(const Rational& x); // -1, 0, or +1
+ friend Rational abs(const Rational& x); // absolute value
+ friend Rational sqr(const Rational& x); // square
+ friend Rational pow(const Rational& x, long y);
+ friend Rational pow(const Rational& x, const Integer& y);
+ const Integer& numerator() const;
+ const Integer& denominator() const;
+
+// coercion & conversion
+
+ operator double() const;
+ friend Integer floor(const Rational& x);
+ friend Integer ceil(const Rational& x);
+ friend Integer trunc(const Rational& x);
+ friend Integer round(const Rational& x);
+
+ friend istream& operator >> (istream& s, Rational& y);
+ friend ostream& operator << (ostream& s, const Rational& y);
+
+ int fits_in_float() const;
+ int fits_in_double() const;
+
+// procedural versions of operators
+
+ friend int compare(const Rational& x, const Rational& y);
+ friend void add(const Rational& x, const Rational& y, Rational& dest);
+ friend void sub(const Rational& x, const Rational& y, Rational& dest);
+ friend void mul(const Rational& x, const Rational& y, Rational& dest);
+ friend void div(const Rational& x, const Rational& y, Rational& dest);
+
+// error detection
+
+ void error(const char* msg) const;
+ int OK() const;
+
+};
+
+typedef Rational RatTmp; // backwards compatibility
+
+inline Rational::Rational() : num(&_ZeroRep), den(&_OneRep) {}
+inline Rational::~Rational() {}
+
+inline Rational::Rational(const Rational& y) :num(y.num), den(y.den) {}
+
+inline Rational::Rational(const Integer& n) :num(n), den(&_OneRep) {}
+
+inline Rational::Rational(const Integer& n, const Integer& d) :num(n),den(d)
+{
+ normalize();
+}
+
+inline Rational::Rational(long n) :num(n), den(&_OneRep) { }
+
+inline Rational::Rational(int n) :num(n), den(&_OneRep) { }
+
+inline Rational::Rational(long n, long d) :num(n), den(d) { normalize(); }
+inline Rational::Rational(int n, int d) :num(n), den(d) { normalize(); }
+inline Rational::Rational(long n, unsigned long d) :num(n), den(d)
+{
+ normalize();
+}
+inline Rational::Rational(unsigned long n, long d) :num(n), den(d)
+{
+ normalize();
+}
+inline Rational::Rational(unsigned long n, unsigned long d) :num(n), den(d)
+{
+ normalize();
+}
+
+inline Rational& Rational::operator = (const Rational& y)
+{
+ num = y.num; den = y.den;
+ return *this;
+}
+
+inline int operator == (const Rational& x, const Rational& y)
+{
+ return compare(x.num, y.num) == 0 && compare(x.den, y.den) == 0;
+}
+
+inline int operator != (const Rational& x, const Rational& y)
+{
+ return compare(x.num, y.num) != 0 || compare(x.den, y.den) != 0;
+}
+
+inline int operator < (const Rational& x, const Rational& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator <= (const Rational& x, const Rational& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator > (const Rational& x, const Rational& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator >= (const Rational& x, const Rational& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int sign(const Rational& x)
+{
+ return sign(x.num);
+}
+
+inline void Rational::negate()
+{
+ num.negate();
+}
+
+
+inline Rational& Rational::operator += (const Rational& y)
+{
+ add(*this, y, *this);
+ return *this;
+}
+
+inline Rational& Rational::operator -= (const Rational& y)
+{
+ sub(*this, y, *this);
+ return *this;
+}
+
+inline Rational& Rational::operator *= (const Rational& y)
+{
+ mul(*this, y, *this);
+ return *this;
+}
+
+inline Rational& Rational::operator /= (const Rational& y)
+{
+ div(*this, y, *this);
+ return *this;
+}
+
+inline const Integer& Rational::numerator() const { return num; }
+inline const Integer& Rational::denominator() const { return den; }
+inline Rational::operator double() const { return ratio(num, den); }
+
+#if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
+inline Rational operator <? (const Rational& x, const Rational& y)
+{
+ if (compare(x, y) <= 0) return x; else return y;
+}
+
+inline Rational operator >? (const Rational& x, const Rational& y)
+{
+ if (compare(x, y) >= 0) return x; else return y;
+}
+#endif
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+inline Rational operator + (const Rational& x, const Rational& y) return r
+{
+ add(x, y, r);
+}
+
+inline Rational operator - (const Rational& x, const Rational& y) return r
+{
+ sub(x, y, r);
+}
+
+inline Rational operator * (const Rational& x, const Rational& y) return r
+{
+ mul(x, y, r);
+}
+
+inline Rational operator / (const Rational& x, const Rational& y) return r
+{
+ div(x, y, r);
+}
+
+#else /* NO_NRV */
+
+inline Rational operator + (const Rational& x, const Rational& y)
+{
+ Rational r; add(x, y, r); return r;
+}
+
+inline Rational operator - (const Rational& x, const Rational& y)
+{
+ Rational r; sub(x, y, r); return r;
+}
+
+inline Rational operator * (const Rational& x, const Rational& y)
+{
+ Rational r; mul(x, y, r); return r;
+}
+
+inline Rational operator / (const Rational& x, const Rational& y)
+{
+ Rational r; div(x, y, r); return r;
+}
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/include/Regex.h b/gnu/lib/libg++/include/Regex.h
new file mode 100644
index 0000000..c8cf731
--- /dev/null
+++ b/gnu/lib/libg++/include/Regex.h
@@ -0,0 +1,76 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef _Regex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Regex_h 1
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define re_compile_pattern recmppat
+#define re_pattern_buffer repatbuf
+#define re_registers reregs
+#endif
+
+struct re_pattern_buffer; // defined elsewhere
+struct re_registers;
+
+class Regex
+{
+private:
+
+ Regex(const Regex&) {} // no X(X&)
+ void operator = (const Regex&) {} // no assignment
+
+protected:
+ re_pattern_buffer* buf;
+ re_registers* reg;
+
+public:
+ Regex(const char* t,
+ int fast = 0,
+ int bufsize = 40,
+ const char* transtable = 0);
+
+ ~Regex();
+
+ int match(const char* s, int len, int pos = 0) const;
+ int search(const char* s, int len,
+ int& matchlen, int startpos = 0) const;
+ int match_info(int& start, int& length, int nth = 0) const;
+
+ int OK() const; // representation invariant
+};
+
+// some built in regular expressions
+
+extern const Regex RXwhite; // = "[ \n\t\r\v\f]+"
+extern const Regex RXint; // = "-?[0-9]+"
+extern const Regex RXdouble; // = "-?\\(\\([0-9]+\\.[0-9]*\\)\\|
+ // \\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)
+ // \\([eE][---+]?[0-9]+\\)?"
+extern const Regex RXalpha; // = "[A-Za-z]+"
+extern const Regex RXlowercase; // = "[a-z]+"
+extern const Regex RXuppercase; // = "[A-Z]+"
+extern const Regex RXalphanum; // = "[0-9A-Za-z]+"
+extern const Regex RXidentifier; // = "[A-Za-z_][A-Za-z0-9_]*"
+
+
+#endif
diff --git a/gnu/lib/libg++/include/RndInt.h b/gnu/lib/libg++/include/RndInt.h
new file mode 100644
index 0000000..b16c7f8
--- /dev/null
+++ b/gnu/lib/libg++/include/RndInt.h
@@ -0,0 +1,175 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1990 Free Software Foundation
+ adapted from a submission from John Reidl <riedl@cs.purdue.edu>
+
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU CC General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU CC, but only under the conditions described in the
+GNU CC General Public License. A copy of this license is
+supposed to have been given to you along with GNU CC so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RandomInteger_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _RandomInteger_h 1
+
+// RandomInteger uses a random number generator to generate an integer
+// in a specified range. By default the range is 0..1. Since in my
+// experience random numbers are often needed for a wide variety of
+// ranges in the same program, this generator accepts a new low or high value
+// as an argument to the asLong and operator() methods to temporarily
+// override stored values
+
+#include <math.h>
+#include <RNG.h>
+
+class RandomInteger
+{
+ protected:
+ RNG *pGenerator;
+ long pLow;
+ long pHigh;
+
+ long _asLong(long, long);
+
+ public:
+
+ RandomInteger(long low, long high, RNG *gen);
+ RandomInteger(long high, RNG *gen);
+ RandomInteger(RNG *gen);
+
+// read params
+
+ long low() const;
+ long high() const;
+ RNG* generator() const;
+
+// change params
+
+ long low(long x);
+ long high(long x);
+ RNG* generator(RNG *gen);
+
+// get a random number
+
+ long asLong();
+ long operator()(); // synonym for asLong
+ int asInt(); // (possibly) truncate as int
+
+// override params for one shot
+
+ long asLong(long high);
+ long asLong(long low, long high);
+
+ long operator () (long high); // synonyms
+ long operator () (long low, long high);
+
+};
+
+
+inline RandomInteger::RandomInteger(long low, long high, RNG *gen)
+ : pLow((low < high) ? low : high),
+ pHigh((low < high) ? high : low),
+ pGenerator(gen)
+{}
+
+inline RandomInteger::RandomInteger(long high, RNG *gen)
+ : pLow((0 < high) ? 0 : high),
+ pHigh((0 < high) ? high : 0),
+ pGenerator(gen)
+{}
+
+
+inline RandomInteger::RandomInteger(RNG *gen)
+ : pLow(0),
+ pHigh(1),
+ pGenerator(gen)
+{}
+
+inline RNG* RandomInteger::generator() const { return pGenerator;}
+inline long RandomInteger::low() const { return pLow; }
+inline long RandomInteger::high() const { return pHigh; }
+
+inline RNG* RandomInteger::generator(RNG *gen)
+{
+ RNG *tmp = pGenerator; pGenerator = gen; return tmp;
+}
+
+inline long RandomInteger::low(long x)
+{
+ long tmp = pLow; pLow = x; return tmp;
+}
+
+inline long RandomInteger:: high(long x)
+{
+ long tmp = pHigh; pHigh = x; return tmp;
+}
+
+inline long RandomInteger:: _asLong(long low, long high)
+{
+ return (pGenerator->asLong() % (high-low+1)) + low;
+}
+
+
+inline long RandomInteger:: asLong()
+{
+ return _asLong(pLow, pHigh);
+}
+
+inline long RandomInteger:: asLong(long high)
+{
+ return _asLong(pLow, high);
+}
+
+inline long RandomInteger:: asLong(long low, long high)
+{
+ return _asLong(low, high);
+}
+
+inline long RandomInteger:: operator () ()
+{
+ return _asLong(pLow, pHigh);
+}
+
+inline long RandomInteger:: operator () (long high)
+{
+ return _asLong(pLow, high);
+}
+
+inline long RandomInteger:: operator () (long low, long high)
+{
+ return _asLong(low, high);
+}
+
+
+
+
+inline int RandomInteger:: asInt()
+{
+ return int(asLong());
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/SFile.h b/gnu/lib/libg++/include/SFile.h
new file mode 100644
index 0000000..3726844
--- /dev/null
+++ b/gnu/lib/libg++/include/SFile.h
@@ -0,0 +1,53 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+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);
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/SLList.h b/gnu/lib/libg++/include/SLList.h
new file mode 100644
index 0000000..c613674
--- /dev/null
+++ b/gnu/lib/libg++/include/SLList.h
@@ -0,0 +1,115 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SLList_h
+#ifdef __GNUG__
+//#pragma interface
+#endif
+#define _SLList_h 1
+
+#include <Pix.h>
+
+struct BaseSLNode
+{
+ BaseSLNode *tl;
+ void *item() {return (void*)(this+1);} // Return ((SLNode<T>*)this)->hd
+};
+
+template<class T>
+class SLNode : public BaseSLNode
+{
+ public:
+ T hd; // Data part of node
+ SLNode() { }
+ SLNode(const T& h, SLNode* t = 0)
+ : hd(h) { tl = t; }
+ ~SLNode() { }
+};
+
+extern int __SLListLength(BaseSLNode *ptr);
+
+class BaseSLList {
+ protected:
+ BaseSLNode *last;
+ virtual void delete_node(BaseSLNode*node) = 0;
+ virtual BaseSLNode* copy_node(const void* datum) = 0;
+ virtual void copy_item(void *dst, void *src) = 0;
+ virtual ~BaseSLList() { }
+ BaseSLList() { last = 0; }
+ void copy(const BaseSLList&);
+ BaseSLList& operator = (const BaseSLList& a);
+ Pix ins_after(Pix p, const void *datum);
+ Pix prepend(const void *datum);
+ Pix append(const void *datum);
+ int remove_front(void *dst, int signal_error = 0);
+ void join(BaseSLList&);
+ public:
+ int length() const;
+ int empty() const { return last == 0; }
+ void clear();
+ Pix prepend(BaseSLNode*);
+ Pix append(BaseSLNode*);
+ int OK();
+ void error(const char* msg);
+ void del_after(Pix p);
+ int owns(Pix p);
+ void del_front();
+};
+
+template <class T>
+class SLList : public BaseSLList
+{
+ private:
+ virtual void delete_node(BaseSLNode *node) { delete (SLNode<T>*)node; }
+ virtual BaseSLNode* copy_node(const void *datum)
+ { return new SLNode<T>(*(const T*)datum); }
+ virtual void copy_item(void *dst, void *src) { *(T*)dst = *(T*)src; }
+
+public:
+ SLList() : BaseSLList() { }
+ SLList(const SLList<T>& a) : BaseSLList() { copy(a); }
+ SLList<T>& operator = (const SLList<T>& a)
+ { BaseSLList::operator=((const BaseSLList&) a); return *this; }
+ virtual ~SLList() { clear(); }
+
+ Pix prepend(const T& item) {return BaseSLList::prepend(&item);}
+ Pix append(const T& item) {return BaseSLList::append(&item);}
+ Pix prepend(SLNode<T>* node) {return BaseSLList::prepend(node);}
+ Pix append(SLNode<T>* node) {return BaseSLList::append(node);}
+
+ T& operator () (Pix p) {
+ if (p == 0) error("null Pix");
+ return ((SLNode<T>*)(p))->hd; }
+ inline Pix first() { return (last == 0)? 0 : Pix(last->tl); }
+ void next(Pix& p)
+ { p = (p == 0 || p == last)? 0 : Pix(((SLNode<T>*)(p))->tl); }
+ Pix ins_after(Pix p, const T& item)
+ { return BaseSLList::ins_after(p, &item); }
+ void join(SLList<T>& a) { BaseSLList::join(a); }
+
+ T& front() {
+ if (last == 0) error("front: empty list");
+ return ((SLNode<T>*)last->tl)->hd; }
+ T& rear() {
+ if (last == 0) error("rear: empty list");
+ return ((SLNode<T>*)last)->hd; }
+ int remove_front(T& x) { return BaseSLList::remove_front(&x); }
+ T remove_front() { T dst; BaseSLList::remove_front(&dst, 1); return dst; }
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/SmplHist.h b/gnu/lib/libg++/include/SmplHist.h
new file mode 100644
index 0000000..a9a7550
--- /dev/null
+++ b/gnu/lib/libg++/include/SmplHist.h
@@ -0,0 +1,72 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef SampleHistogram_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define SampleHistogram_h 1
+
+#include <iostream.h>
+#include <SmplStat.h>
+
+extern const int SampleHistogramMinimum;
+extern const int SampleHistogramMaximum;
+
+class SampleHistogram : public SampleStatistic
+{
+protected:
+ short howManyBuckets;
+ int *bucketCount;
+ double *bucketLimit;
+
+public:
+
+ SampleHistogram(double low, double hi, double bucketWidth = -1.0);
+
+ ~SampleHistogram();
+
+ virtual void reset();
+ virtual void operator+=(double);
+
+ int similarSamples(double);
+
+ int buckets();
+
+ double bucketThreshold(int i);
+ int inBucket(int i);
+ void printBuckets(ostream&);
+
+};
+
+
+inline int SampleHistogram:: buckets() { return(howManyBuckets); };
+
+inline double SampleHistogram:: bucketThreshold(int i) {
+ if (i < 0 || i >= howManyBuckets)
+ error("invalid bucket access");
+ return(bucketLimit[i]);
+}
+
+inline int SampleHistogram:: inBucket(int i) {
+ if (i < 0 || i >= howManyBuckets)
+ error("invalid bucket access");
+ return(bucketCount[i]);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/SmplStat.h b/gnu/lib/libg++/include/SmplStat.h
new file mode 100644
index 0000000..191ec67
--- /dev/null
+++ b/gnu/lib/libg++/include/SmplStat.h
@@ -0,0 +1,66 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef SampleStatistic_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define SampleStatistic_h 1
+
+#include <builtin.h>
+
+class SampleStatistic {
+protected:
+ int n;
+ double x;
+ double x2;
+ double minValue, maxValue;
+
+ public :
+
+ SampleStatistic();
+ virtual ~SampleStatistic();
+ virtual void reset();
+
+ virtual void operator+=(double);
+ int samples();
+ double mean();
+ double stdDev();
+ double var();
+ double min();
+ double max();
+ double confidence(int p_percentage);
+ double confidence(double p_value);
+
+ void error(const char* msg);
+};
+
+// error handlers
+
+extern void default_SampleStatistic_error_handler(const char*);
+extern one_arg_error_handler_t SampleStatistic_error_handler;
+
+extern one_arg_error_handler_t
+ set_SampleStatistic_error_handler(one_arg_error_handler_t f);
+
+inline SampleStatistic:: SampleStatistic(){ reset();}
+inline int SampleStatistic:: samples() {return(n);}
+inline double SampleStatistic:: min() {return(minValue);}
+inline double SampleStatistic:: max() {return(maxValue);}
+inline SampleStatistic::~SampleStatistic() {}
+
+#endif
diff --git a/gnu/lib/libg++/include/String.h b/gnu/lib/libg++/include/String.h
new file mode 100644
index 0000000..9537ba6
--- /dev/null
+++ b/gnu/lib/libg++/include/String.h
@@ -0,0 +1,1328 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef _String_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _String_h 1
+
+#include <iostream.h>
+#include <Regex.h>
+
+struct StrRep // internal String representations
+{
+ unsigned short len; // string length
+ unsigned short sz; // allocated space
+ char s[1]; // the string starts here
+ // (at least 1 char for trailing null)
+ // allocated & expanded via non-public fcts
+};
+
+// primitive ops on StrReps -- nearly all String fns go through these.
+
+StrRep* Salloc(StrRep*, const char*, int, int);
+StrRep* Scopy(StrRep*, const StrRep*);
+StrRep* Sresize(StrRep*, int);
+StrRep* Scat(StrRep*, const char*, int, const char*, int);
+StrRep* Scat(StrRep*, const char*, int,const char*,int, const char*,int);
+StrRep* Sprepend(StrRep*, const char*, int);
+StrRep* Sreverse(const StrRep*, StrRep*);
+StrRep* Supcase(const StrRep*, StrRep*);
+StrRep* Sdowncase(const StrRep*, StrRep*);
+StrRep* Scapitalize(const StrRep*, StrRep*);
+
+// These classes need to be defined in the order given
+
+class String;
+class SubString;
+
+class SubString
+{
+ friend class String;
+protected:
+
+ String& S; // The String I'm a substring of
+ unsigned short pos; // starting position in S's rep
+ unsigned short len; // length of substring
+
+ void assign(const StrRep*, const char*, int = -1);
+ SubString(String& x, int p, int l);
+ SubString(const SubString& x);
+
+public:
+
+// Note there are no public constructors. SubStrings are always
+// created via String operations
+
+ ~SubString();
+
+ SubString& operator = (const String& y);
+ SubString& operator = (const SubString& y);
+ SubString& operator = (const char* t);
+ SubString& operator = (char c);
+
+// return 1 if target appears anywhere in SubString; else 0
+
+ int contains(char c) const;
+ int contains(const String& y) const;
+ int contains(const SubString& y) const;
+ int contains(const char* t) const;
+ int contains(const Regex& r) const;
+
+// return 1 if target matches entire SubString
+
+ int matches(const Regex& r) const;
+
+// IO
+
+ friend ostream& operator<<(ostream& s, const SubString& x);
+
+// status
+
+ unsigned int length() const;
+ int empty() const;
+ const char* chars() const;
+
+ int OK() const;
+
+};
+
+
+class String
+{
+ friend class SubString;
+
+protected:
+ StrRep* rep; // Strings are pointers to their representations
+
+// some helper functions
+
+ int search(int, int, const char*, int = -1) const;
+ int search(int, int, char) const;
+ int match(int, int, int, const char*, int = -1) const;
+ int _gsub(const char*, int, const char* ,int);
+ int _gsub(const Regex&, const char*, int);
+ SubString _substr(int, int);
+
+public:
+
+// constructors & assignment
+
+ String();
+ String(const String& x);
+ String(const SubString& x);
+ String(const char* t);
+ String(const char* t, int len);
+ String(char c);
+
+ ~String();
+
+ String& operator = (const String& y);
+ String& operator = (const char* y);
+ String& operator = (char c);
+ String& operator = (const SubString& y);
+
+// concatenation
+
+ String& operator += (const String& y);
+ String& operator += (const SubString& y);
+ String& operator += (const char* t);
+ String& operator += (char c);
+
+ void prepend(const String& y);
+ void prepend(const SubString& y);
+ void prepend(const char* t);
+ void prepend(char c);
+
+
+// procedural versions:
+// concatenate first 2 args, store result in last arg
+
+ friend void cat(const String&, const String&, String&);
+ friend void cat(const String&, const SubString&, String&);
+ friend void cat(const String&, const char*, String&);
+ friend void cat(const String&, char, String&);
+
+ friend void cat(const SubString&, const String&, String&);
+ friend void cat(const SubString&, const SubString&, String&);
+ friend void cat(const SubString&, const char*, String&);
+ friend void cat(const SubString&, char, String&);
+
+ friend void cat(const char*, const String&, String&);
+ friend void cat(const char*, const SubString&, String&);
+ friend void cat(const char*, const char*, String&);
+ friend void cat(const char*, char, String&);
+
+// double concatenation, by request. (yes, there are too many versions,
+// but if one is supported, then the others should be too...)
+// Concatenate first 3 args, store in last arg
+
+ friend void cat(const String&,const String&, const String&,String&);
+ friend void cat(const String&,const String&,const SubString&,String&);
+ friend void cat(const String&,const String&, const char*, String&);
+ friend void cat(const String&,const String&, char, String&);
+ friend void cat(const String&,const SubString&,const String&,String&);
+ friend void cat(const String&,const SubString&,const SubString&,String&);
+ friend void cat(const String&,const SubString&, const char*, String&);
+ friend void cat(const String&,const SubString&, char, String&);
+ friend void cat(const String&,const char*, const String&, String&);
+ friend void cat(const String&,const char*, const SubString&, String&);
+ friend void cat(const String&,const char*, const char*, String&);
+ friend void cat(const String&,const char*, char, String&);
+
+ friend void cat(const char*, const String&, const String&,String&);
+ friend void cat(const char*,const String&,const SubString&,String&);
+ friend void cat(const char*,const String&, const char*, String&);
+ friend void cat(const char*,const String&, char, String&);
+ friend void cat(const char*,const SubString&,const String&,String&);
+ friend void cat(const char*,const SubString&,const SubString&,String&);
+ friend void cat(const char*,const SubString&, const char*, String&);
+ friend void cat(const char*,const SubString&, char, String&);
+ friend void cat(const char*,const char*, const String&, String&);
+ friend void cat(const char*,const char*, const SubString&, String&);
+ friend void cat(const char*,const char*, const char*, String&);
+ friend void cat(const char*,const char*, char, String&);
+
+
+// searching & matching
+
+// return position of target in string or -1 for failure
+
+ int index(char c, int startpos = 0) const;
+ int index(const String& y, int startpos = 0) const;
+ int index(const SubString& y, int startpos = 0) const;
+ int index(const char* t, int startpos = 0) const;
+ int index(const Regex& r, int startpos = 0) const;
+
+// return 1 if target appears anyhere in String; else 0
+
+ int contains(char c) const;
+ int contains(const String& y) const;
+ int contains(const SubString& y) const;
+ int contains(const char* t) const;
+ int contains(const Regex& r) const;
+
+// return 1 if target appears anywhere after position pos
+// (or before, if pos is negative) in String; else 0
+
+ int contains(char c, int pos) const;
+ int contains(const String& y, int pos) const;
+ int contains(const SubString& y, int pos) const;
+ int contains(const char* t, int pos) const;
+ int contains(const Regex& r, int pos) const;
+
+// return 1 if target appears at position pos in String; else 0
+
+ int matches(char c, int pos = 0) const;
+ int matches(const String& y, int pos = 0) const;
+ int matches(const SubString& y, int pos = 0) const;
+ int matches(const char* t, int pos = 0) const;
+ int matches(const Regex& r, int pos = 0) const;
+
+// return number of occurences of target in String
+
+ int freq(char c) const;
+ int freq(const String& y) const;
+ int freq(const SubString& y) const;
+ int freq(const char* t) const;
+
+// SubString extraction
+
+// Note that you can't take a substring of a const String, since
+// this leaves open the possiblility of indirectly modifying the
+// String through the SubString
+
+ SubString at(int pos, int len);
+ SubString operator () (int pos, int len); // synonym for at
+
+ SubString at(const String& x, int startpos = 0);
+ SubString at(const SubString& x, int startpos = 0);
+ SubString at(const char* t, int startpos = 0);
+ SubString at(char c, int startpos = 0);
+ SubString at(const Regex& r, int startpos = 0);
+
+ SubString before(int pos);
+ SubString before(const String& x, int startpos = 0);
+ SubString before(const SubString& x, int startpos = 0);
+ SubString before(const char* t, int startpos = 0);
+ SubString before(char c, int startpos = 0);
+ SubString before(const Regex& r, int startpos = 0);
+
+ SubString through(int pos);
+ SubString through(const String& x, int startpos = 0);
+ SubString through(const SubString& x, int startpos = 0);
+ SubString through(const char* t, int startpos = 0);
+ SubString through(char c, int startpos = 0);
+ SubString through(const Regex& r, int startpos = 0);
+
+ SubString from(int pos);
+ SubString from(const String& x, int startpos = 0);
+ SubString from(const SubString& x, int startpos = 0);
+ SubString from(const char* t, int startpos = 0);
+ SubString from(char c, int startpos = 0);
+ SubString from(const Regex& r, int startpos = 0);
+
+ SubString after(int pos);
+ SubString after(const String& x, int startpos = 0);
+ SubString after(const SubString& x, int startpos = 0);
+ SubString after(const char* t, int startpos = 0);
+ SubString after(char c, int startpos = 0);
+ SubString after(const Regex& r, int startpos = 0);
+
+
+// deletion
+
+// delete len chars starting at pos
+ void del(int pos, int len);
+
+// delete the first occurrence of target after startpos
+
+ void del(const String& y, int startpos = 0);
+ void del(const SubString& y, int startpos = 0);
+ void del(const char* t, int startpos = 0);
+ void del(char c, int startpos = 0);
+ void del(const Regex& r, int startpos = 0);
+
+// global substitution: substitute all occurrences of pat with repl
+
+ int gsub(const String& pat, const String& repl);
+ int gsub(const SubString& pat, const String& repl);
+ int gsub(const char* pat, const String& repl);
+ int gsub(const char* pat, const char* repl);
+ int gsub(const Regex& pat, const String& repl);
+
+// friends & utilities
+
+// split string into array res at separators; return number of elements
+
+ friend int split(const String& x, String res[], int maxn,
+ const String& sep);
+ friend int split(const String& x, String res[], int maxn,
+ const Regex& sep);
+
+ friend String common_prefix(const String& x, const String& y,
+ int startpos = 0);
+ friend String common_suffix(const String& x, const String& y,
+ int startpos = -1);
+ friend String replicate(char c, int n);
+ friend String replicate(const String& y, int n);
+ friend String join(String src[], int n, const String& sep);
+
+// simple builtin transformations
+
+ friend String reverse(const String& x);
+ friend String upcase(const String& x);
+ friend String downcase(const String& x);
+ friend String capitalize(const String& x);
+
+// in-place versions of above
+
+ void reverse();
+ void upcase();
+ void downcase();
+ void capitalize();
+
+// element extraction
+
+ char& operator [] (int i);
+ char elem(int i) const;
+ char firstchar() const;
+ char lastchar() const;
+
+// conversion
+
+ operator const char*() const;
+ const char* chars() const;
+
+
+// IO
+
+ friend ostream& operator<<(ostream& s, const String& x);
+ friend ostream& operator<<(ostream& s, const SubString& x);
+ friend istream& operator>>(istream& s, String& x);
+
+ friend int readline(istream& s, String& x,
+ char terminator = '\n',
+ int discard_terminator = 1);
+
+// status
+
+ unsigned int length() const;
+ int empty() const;
+
+// preallocate some space for String
+ void alloc(int newsize);
+
+// report current allocation (not length!)
+
+ int allocation() const;
+
+
+ void error(const char* msg) const;
+
+ int OK() const;
+};
+
+typedef String StrTmp; // for backward compatibility
+
+// other externs
+
+int compare(const String& x, const String& y);
+int compare(const String& x, const SubString& y);
+int compare(const String& x, const char* y);
+int compare(const SubString& x, const String& y);
+int compare(const SubString& x, const SubString& y);
+int compare(const SubString& x, const char* y);
+int fcompare(const String& x, const String& y); // ignore case
+
+extern StrRep _nilStrRep;
+extern String _nilString;
+
+// other inlines
+
+String operator + (const String& x, const String& y);
+String operator + (const String& x, const SubString& y);
+String operator + (const String& x, const char* y);
+String operator + (const String& x, char y);
+String operator + (const SubString& x, const String& y);
+String operator + (const SubString& x, const SubString& y);
+String operator + (const SubString& x, const char* y);
+String operator + (const SubString& x, char y);
+String operator + (const char* x, const String& y);
+String operator + (const char* x, const SubString& y);
+
+int operator==(const String& x, const String& y);
+int operator!=(const String& x, const String& y);
+int operator> (const String& x, const String& y);
+int operator>=(const String& x, const String& y);
+int operator< (const String& x, const String& y);
+int operator<=(const String& x, const String& y);
+int operator==(const String& x, const SubString& y);
+int operator!=(const String& x, const SubString& y);
+int operator> (const String& x, const SubString& y);
+int operator>=(const String& x, const SubString& y);
+int operator< (const String& x, const SubString& y);
+int operator<=(const String& x, const SubString& y);
+int operator==(const String& x, const char* t);
+int operator!=(const String& x, const char* t);
+int operator> (const String& x, const char* t);
+int operator>=(const String& x, const char* t);
+int operator< (const String& x, const char* t);
+int operator<=(const String& x, const char* t);
+int operator==(const SubString& x, const String& y);
+int operator!=(const SubString& x, const String& y);
+int operator> (const SubString& x, const String& y);
+int operator>=(const SubString& x, const String& y);
+int operator< (const SubString& x, const String& y);
+int operator<=(const SubString& x, const String& y);
+int operator==(const SubString& x, const SubString& y);
+int operator!=(const SubString& x, const SubString& y);
+int operator> (const SubString& x, const SubString& y);
+int operator>=(const SubString& x, const SubString& y);
+int operator< (const SubString& x, const SubString& y);
+int operator<=(const SubString& x, const SubString& y);
+int operator==(const SubString& x, const char* t);
+int operator!=(const SubString& x, const char* t);
+int operator> (const SubString& x, const char* t);
+int operator>=(const SubString& x, const char* t);
+int operator< (const SubString& x, const char* t);
+int operator<=(const SubString& x, const char* t);
+
+
+// status reports, needed before defining other things
+
+inline unsigned int String::length() const { return rep->len; }
+inline int String::empty() const { return rep->len == 0; }
+inline const char* String::chars() const { return &(rep->s[0]); }
+inline int String::allocation() const { return rep->sz; }
+inline void String::alloc(int newsize) { rep = Sresize(rep, newsize); }
+
+inline unsigned int SubString::length() const { return len; }
+inline int SubString::empty() const { return len == 0; }
+inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
+
+
+// constructors
+
+inline String::String()
+ : rep(&_nilStrRep) {}
+inline String::String(const String& x)
+ : rep(Scopy(0, x.rep)) {}
+inline String::String(const char* t)
+ : rep(Salloc(0, t, -1, -1)) {}
+inline String::String(const char* t, int tlen)
+ : rep(Salloc(0, t, tlen, tlen)) {}
+inline String::String(const SubString& y)
+ : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
+inline String::String(char c)
+ : rep(Salloc(0, &c, 1, 1)) {}
+
+inline String::~String() { if (rep != &_nilStrRep) delete rep; }
+
+inline SubString::SubString(const SubString& x)
+ :S(x.S), pos(x.pos), len(x.len) {}
+inline SubString::SubString(String& x, int first, int l)
+ :S(x), pos(first), len(l) {}
+
+inline SubString::~SubString() {}
+
+// assignment
+
+inline String& String::operator = (const String& y)
+{
+ rep = Scopy(rep, y.rep);
+ return *this;
+}
+
+inline String& String::operator=(const char* t)
+{
+ rep = Salloc(rep, t, -1, -1);
+ return *this;
+}
+
+inline String& String::operator=(const SubString& y)
+{
+ rep = Salloc(rep, y.chars(), y.length(), y.length());
+ return *this;
+}
+
+inline String& String::operator=(char c)
+{
+ rep = Salloc(rep, &c, 1, 1);
+ return *this;
+}
+
+
+inline SubString& SubString::operator = (const char* ys)
+{
+ assign(0, ys);
+ return *this;
+}
+
+inline SubString& SubString::operator = (char ch)
+{
+ assign(0, &ch, 1);
+ return *this;
+}
+
+inline SubString& SubString::operator = (const String& y)
+{
+ assign(y.rep, y.chars(), y.length());
+ return *this;
+}
+
+inline SubString& SubString::operator = (const SubString& y)
+{
+ assign(y.S.rep, y.chars(), y.length());
+ return *this;
+}
+
+// Zillions of cats...
+
+inline void cat(const String& x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const String& x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const String& x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
+}
+
+inline void cat(const String& x, char y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
+}
+
+inline void cat(const SubString& x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const SubString& x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const SubString& x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), y, -1);
+}
+
+inline void cat(const SubString& x, char y, String& r)
+{
+ r.rep = Scat(r.rep, x.chars(), x.length(), &y, 1);
+}
+
+inline void cat(const char* x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
+}
+
+inline void cat(const char* x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, x, -1, y.chars(), y.length());
+}
+
+inline void cat(const char* x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, x, -1, y, -1);
+}
+
+inline void cat(const char* x, char y, String& r)
+{
+ r.rep = Scat(r.rep, x, -1, &y, 1);
+}
+
+inline void cat(const String& a, const String& x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const String& a, const String& x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const String& a, const String& x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
+}
+
+inline void cat(const String& a, const String& x, char y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
+}
+
+inline void cat(const String& a, const SubString& x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const String& a, const SubString& x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const String& a, const SubString& x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), y, -1);
+}
+
+inline void cat(const String& a, const SubString& x, char y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x.chars(), x.length(), &y, 1);
+}
+
+inline void cat(const String& a, const char* x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
+}
+
+inline void cat(const String& a, const char* x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y.chars(), y.length());
+}
+
+inline void cat(const String& a, const char* x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, y, -1);
+}
+
+inline void cat(const String& a, const char* x, char y, String& r)
+{
+ r.rep = Scat(r.rep, a.chars(), a.length(), x, -1, &y, 1);
+}
+
+
+inline void cat(const char* a, const String& x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const char* a, const String& x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const char* a, const String& x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
+}
+
+inline void cat(const char* a, const String& x, char y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
+}
+
+inline void cat(const char* a, const SubString& x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const char* a, const SubString& x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y.chars(), y.length());
+}
+
+inline void cat(const char* a, const SubString& x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), y, -1);
+}
+
+inline void cat(const char* a, const SubString& x, char y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x.chars(), x.length(), &y, 1);
+}
+
+inline void cat(const char* a, const char* x, const String& y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
+}
+
+inline void cat(const char* a, const char* x, const SubString& y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x, -1, y.chars(), y.length());
+}
+
+inline void cat(const char* a, const char* x, const char* y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x, -1, y, -1);
+}
+
+inline void cat(const char* a, const char* x, char y, String& r)
+{
+ r.rep = Scat(r.rep, a, -1, x, -1, &y, 1);
+}
+
+
+// operator versions
+
+inline String& String::operator +=(const String& y)
+{
+ cat(*this, y, *this);
+ return *this;
+}
+
+inline String& String::operator +=(const SubString& y)
+{
+ cat(*this, y, *this);
+ return *this;
+}
+
+inline String& String::operator += (const char* y)
+{
+ cat(*this, y, *this);
+ return *this;
+}
+
+inline String& String:: operator +=(char y)
+{
+ cat(*this, y, *this);
+ return *this;
+}
+
+// constructive concatenation
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+inline String operator + (const String& x, const String& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const String& x, const SubString& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const String& x, const char* y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const String& x, char y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, const String& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, const SubString& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, const char* y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, char y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const char* x, const String& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const char* x, const SubString& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String reverse(const String& x) return r;
+{
+ r.rep = Sreverse(x.rep, r.rep);
+}
+
+inline String upcase(const String& x) return r;
+{
+ r.rep = Supcase(x.rep, r.rep);
+}
+
+inline String downcase(const String& x) return r;
+{
+ r.rep = Sdowncase(x.rep, r.rep);
+}
+
+inline String capitalize(const String& x) return r;
+{
+ r.rep = Scapitalize(x.rep, r.rep);
+}
+
+#else /* NO_NRV */
+
+inline String operator + (const String& x, const String& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const String& x, const SubString& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const String& x, const char* y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const String& x, char y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, const String& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, const SubString& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, const char* y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, char y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const char* x, const String& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const char* x, const SubString& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String reverse(const String& x)
+{
+ String r; r.rep = Sreverse(x.rep, r.rep); return r;
+}
+
+inline String upcase(const String& x)
+{
+ String r; r.rep = Supcase(x.rep, r.rep); return r;
+}
+
+inline String downcase(const String& x)
+{
+ String r; r.rep = Sdowncase(x.rep, r.rep); return r;
+}
+
+inline String capitalize(const String& x)
+{
+ String r; r.rep = Scapitalize(x.rep, r.rep); return r;
+}
+
+#endif
+
+// prepend
+
+inline void String::prepend(const String& y)
+{
+ rep = Sprepend(rep, y.chars(), y.length());
+}
+
+inline void String::prepend(const char* y)
+{
+ rep = Sprepend(rep, y, -1);
+}
+
+inline void String::prepend(char y)
+{
+ rep = Sprepend(rep, &y, 1);
+}
+
+inline void String::prepend(const SubString& y)
+{
+ rep = Sprepend(rep, y.chars(), y.length());
+}
+
+// misc transformations
+
+
+inline void String::reverse()
+{
+ rep = Sreverse(rep, rep);
+}
+
+
+inline void String::upcase()
+{
+ rep = Supcase(rep, rep);
+}
+
+
+inline void String::downcase()
+{
+ rep = Sdowncase(rep, rep);
+}
+
+
+inline void String::capitalize()
+{
+ rep = Scapitalize(rep, rep);
+}
+
+// element extraction
+
+inline char& String::operator [] (int i)
+{
+ if (((unsigned)i) >= length()) error("invalid index");
+ return rep->s[i];
+}
+
+inline char String::elem (int i) const
+{
+ if (((unsigned)i) >= length()) error("invalid index");
+ return rep->s[i];
+}
+
+inline char String::firstchar() const
+{
+ return elem(0);
+}
+
+inline char String::lastchar() const
+{
+ return elem(length() - 1);
+}
+
+// searching
+
+inline int String::index(char c, int startpos) const
+{
+ return search(startpos, length(), c);
+}
+
+inline int String::index(const char* t, int startpos) const
+{
+ return search(startpos, length(), t);
+}
+
+inline int String::index(const String& y, int startpos) const
+{
+ return search(startpos, length(), y.chars(), y.length());
+}
+
+inline int String::index(const SubString& y, int startpos) const
+{
+ return search(startpos, length(), y.chars(), y.length());
+}
+
+inline int String::index(const Regex& r, int startpos) const
+{
+ int unused; return r.search(chars(), length(), unused, startpos);
+}
+
+inline int String::contains(char c) const
+{
+ return search(0, length(), c) >= 0;
+}
+
+inline int String::contains(const char* t) const
+{
+ return search(0, length(), t) >= 0;
+}
+
+inline int String::contains(const String& y) const
+{
+ return search(0, length(), y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(const SubString& y) const
+{
+ return search(0, length(), y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(char c, int p) const
+{
+ return match(p, length(), 0, &c, 1) >= 0;
+}
+
+inline int String::contains(const char* t, int p) const
+{
+ return match(p, length(), 0, t) >= 0;
+}
+
+inline int String::contains(const String& y, int p) const
+{
+ return match(p, length(), 0, y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(const SubString& y, int p) const
+{
+ return match(p, length(), 0, y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(const Regex& r) const
+{
+ int unused; return r.search(chars(), length(), unused, 0) >= 0;
+}
+
+inline int String::contains(const Regex& r, int p) const
+{
+ return r.match(chars(), length(), p) >= 0;
+}
+
+
+inline int String::matches(const SubString& y, int p) const
+{
+ return match(p, length(), 1, y.chars(), y.length()) >= 0;
+}
+
+inline int String::matches(const String& y, int p) const
+{
+ return match(p, length(), 1, y.chars(), y.length()) >= 0;
+}
+
+inline int String::matches(const char* t, int p) const
+{
+ return match(p, length(), 1, t) >= 0;
+}
+
+inline int String::matches(char c, int p) const
+{
+ return match(p, length(), 1, &c, 1) >= 0;
+}
+
+inline int String::matches(const Regex& r, int p) const
+{
+ int l = (p < 0)? -p : length() - p;
+ return r.match(chars(), length(), p) == l;
+}
+
+
+inline int SubString::contains(const char* t) const
+{
+ return S.search(pos, pos+len, t) >= 0;
+}
+
+inline int SubString::contains(const String& y) const
+{
+ return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
+}
+
+inline int SubString::contains(const SubString& y) const
+{
+ return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
+}
+
+inline int SubString::contains(char c) const
+{
+ return S.search(pos, pos+len, c) >= 0;
+}
+
+inline int SubString::contains(const Regex& r) const
+{
+ int unused; return r.search(chars(), len, unused, 0) >= 0;
+}
+
+inline int SubString::matches(const Regex& r) const
+{
+ return r.match(chars(), len, 0) == len;
+}
+
+
+inline int String::gsub(const String& pat, const String& r)
+{
+ return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
+}
+
+inline int String::gsub(const SubString& pat, const String& r)
+{
+ return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
+}
+
+inline int String::gsub(const Regex& pat, const String& r)
+{
+ return _gsub(pat, r.chars(), r.length());
+}
+
+inline int String::gsub(const char* pat, const String& r)
+{
+ return _gsub(pat, -1, r.chars(), r.length());
+}
+
+inline int String::gsub(const char* pat, const char* r)
+{
+ return _gsub(pat, -1, r, -1);
+}
+
+
+
+inline ostream& operator<<(ostream& s, const String& x)
+{
+ s << x.chars(); return s;
+}
+
+// a zillion comparison operators
+
+inline int operator==(const String& x, const String& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator!=(const String& x, const String& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator>(const String& x, const String& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator>=(const String& x, const String& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator<(const String& x, const String& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator<=(const String& x, const String& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator==(const String& x, const SubString& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator!=(const String& x, const SubString& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator>(const String& x, const SubString& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator>=(const String& x, const SubString& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator<(const String& x, const SubString& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator<=(const String& x, const SubString& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator==(const String& x, const char* t)
+{
+ return compare(x, t) == 0;
+}
+
+inline int operator!=(const String& x, const char* t)
+{
+ return compare(x, t) != 0;
+}
+
+inline int operator>(const String& x, const char* t)
+{
+ return compare(x, t) > 0;
+}
+
+inline int operator>=(const String& x, const char* t)
+{
+ return compare(x, t) >= 0;
+}
+
+inline int operator<(const String& x, const char* t)
+{
+ return compare(x, t) < 0;
+}
+
+inline int operator<=(const String& x, const char* t)
+{
+ return compare(x, t) <= 0;
+}
+
+inline int operator==(const SubString& x, const String& y)
+{
+ return compare(y, x) == 0;
+}
+
+inline int operator!=(const SubString& x, const String& y)
+{
+ return compare(y, x) != 0;
+}
+
+inline int operator>(const SubString& x, const String& y)
+{
+ return compare(y, x) < 0;
+}
+
+inline int operator>=(const SubString& x, const String& y)
+{
+ return compare(y, x) <= 0;
+}
+
+inline int operator<(const SubString& x, const String& y)
+{
+ return compare(y, x) > 0;
+}
+
+inline int operator<=(const SubString& x, const String& y)
+{
+ return compare(y, x) >= 0;
+}
+
+inline int operator==(const SubString& x, const SubString& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator!=(const SubString& x, const SubString& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator>(const SubString& x, const SubString& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator>=(const SubString& x, const SubString& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator<(const SubString& x, const SubString& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator<=(const SubString& x, const SubString& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator==(const SubString& x, const char* t)
+{
+ return compare(x, t) == 0;
+}
+
+inline int operator!=(const SubString& x, const char* t)
+{
+ return compare(x, t) != 0;
+}
+
+inline int operator>(const SubString& x, const char* t)
+{
+ return compare(x, t) > 0;
+}
+
+inline int operator>=(const SubString& x, const char* t)
+{
+ return compare(x, t) >= 0;
+}
+
+inline int operator<(const SubString& x, const char* t)
+{
+ return compare(x, t) < 0;
+}
+
+inline int operator<=(const SubString& x, const char* t)
+{
+ return compare(x, t) <= 0;
+}
+
+
+// a helper needed by at, before, etc.
+
+inline SubString String::_substr(int first, int l)
+{
+ if (first < 0 || (unsigned)(first + l) > length() )
+ return SubString(_nilString, 0, 0) ;
+ else
+ return SubString(*this, first, l);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Uniform.h b/gnu/lib/libg++/include/Uniform.h
new file mode 100644
index 0000000..5933f6b
--- /dev/null
+++ b/gnu/lib/libg++/include/Uniform.h
@@ -0,0 +1,71 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Uniform_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Uniform_h 1
+
+#include <Random.h>
+
+//
+// The interval [lo..hi]
+//
+
+class Uniform: public Random {
+ double pLow;
+ double pHigh;
+ double delta;
+public:
+ Uniform(double low, double high, RNG *gen);
+
+ double low();
+ double low(double x);
+ double high();
+ double high(double x);
+
+ virtual double operator()();
+};
+
+
+inline Uniform::Uniform(double low, double high, RNG *gen) : Random(gen)
+{
+ pLow = (low < high) ? low : high;
+ pHigh = (low < high) ? high : low;
+ delta = pHigh - pLow;
+}
+
+inline double Uniform::low() { return pLow; }
+
+inline double Uniform::low(double x) {
+ double tmp = pLow;
+ pLow = x;
+ delta = pHigh - pLow;
+ return tmp;
+}
+
+inline double Uniform::high() { return pHigh; }
+
+inline double Uniform::high(double x) {
+ double tmp = pHigh;
+ pHigh = x;
+ delta = pHigh - pLow;
+ return tmp;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/Weibull.h b/gnu/lib/libg++/include/Weibull.h
new file mode 100644
index 0000000..d03567a
--- /dev/null
+++ b/gnu/lib/libg++/include/Weibull.h
@@ -0,0 +1,74 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef _Weibull_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Weibull_h
+
+#include <Random.h>
+
+class Weibull: public Random {
+protected:
+ double pAlpha;
+ double pInvAlpha;
+ double pBeta;
+
+ void setState();
+
+public:
+ Weibull(double alpha, double beta, RNG *gen);
+
+ double alpha();
+ double alpha(double x);
+
+ double beta();
+ double beta(double x);
+
+ virtual double operator()();
+};
+
+
+inline void Weibull::setState() {
+ pInvAlpha = 1.0 / pAlpha;
+}
+
+inline Weibull::Weibull(double alpha, double beta, RNG *gen) : Random(gen)
+{
+ pAlpha = alpha;
+ pBeta = beta;
+ setState();
+}
+
+inline double Weibull::alpha() { return pAlpha; }
+
+inline double Weibull::alpha(double x) {
+ double tmp = pAlpha;
+ pAlpha = x;
+ setState();
+ return tmp;
+}
+
+inline double Weibull::beta() { return pBeta; };
+inline double Weibull::beta(double x) {
+ double tmp = pBeta;
+ pBeta = x;
+ return tmp;
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/_G_config.h b/gnu/lib/libg++/include/_G_config.h
new file mode 100644
index 0000000..2b73e90
--- /dev/null
+++ b/gnu/lib/libg++/include/_G_config.h
@@ -0,0 +1,70 @@
+/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
+#ifndef _G_config_h
+#define _G_config_h
+#define _G_LIB_VERSION "0.65"
+#define _G_NAMES_HAVE_UNDERSCORE 1
+#define _G_VTABLE_LABEL_HAS_LENGTH 0
+#define _G_VTABLE_LABEL_PREFIX "__vt$"
+#define _G_HAVE_ST_BLKSIZE 1
+typedef unsigned long _G_clock_t;
+typedef unsigned long _G_dev_t;
+typedef quad_t _G_fpos_t;
+typedef unsigned long _G_gid_t;
+typedef unsigned long _G_ino_t;
+typedef unsigned short _G_mode_t;
+typedef unsigned short _G_nlink_t;
+typedef long long _G_off_t;
+typedef long _G_pid_t;
+#ifndef __PTRDIFF_TYPE__
+#define __PTRDIFF_TYPE__ int
+#endif
+typedef __PTRDIFF_TYPE__ _G_ptrdiff_t;
+typedef unsigned int _G_sigset_t;
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ unsigned int
+#endif
+typedef __SIZE_TYPE__ _G_size_t;
+typedef long _G_time_t;
+typedef unsigned long _G_uid_t;
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ int
+#endif
+typedef __WCHAR_TYPE__ _G_wchar_t;
+typedef int _G_ssize_t;
+typedef int _G_wint_t;
+typedef char* /* default */ _G_va_list;
+#define _G_signal_return_type void
+#define _G_sprintf_return_type int
+#ifdef __STDC__
+typedef signed char _G_int8_t;
+#endif
+typedef unsigned char _G_uint8_t;
+typedef short _G_int16_t;
+typedef unsigned short _G_uint16_t;
+typedef int _G_int32_t;
+typedef unsigned long _G_uint32_t;
+#define HAVE_INT64
+typedef long long _G_int64_t;
+typedef unsigned _G_uint64_t;
+#define _G_BUFSIZ 1024
+#define _G_FOPEN_MAX 20
+#define _G_FILENAME_MAX 1024
+#define _G_NULL 0 /* default */
+#if defined (__cplusplus) || defined (__STDC__)
+#define _G_ARGS(ARGLIST) ARGLIST
+#else
+#define _G_ARGS(ARGLIST) ()
+#endif
+#if defined (__GNUG__) && defined (__STRICT_ANSI__)
+#define _G_NO_NRV
+#endif
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_RESOURCE 0
+#define _G_HAVE_SYS_SOCKET 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_HAVE_UNISTD 1
+#define _G_HAVE_DIRENT 1
+#define _G_HAVE_CURSES 1
+#define _G_MATH_H_INLINES 0
+#define _G_HAVE_BOOL 0
+#endif /* !_G_config_h */
diff --git a/gnu/lib/libg++/include/ansidecl.h b/gnu/lib/libg++/include/ansidecl.h
new file mode 100644
index 0000000..3c0dcb3
--- /dev/null
+++ b/gnu/lib/libg++/include/ansidecl.h
@@ -0,0 +1,141 @@
+/* ANSI and traditional C compatability macros
+ Copyright 1991, 1992 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+This program 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 of the License, or
+(at your option) any later version.
+
+This program 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 program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ANSI and traditional C compatibility macros
+
+ ANSI C is assumed if __STDC__ is #defined.
+
+ Macro ANSI C definition Traditional C definition
+ ----- ---- - ---------- ----------- - ----------
+ PTR `void *' `char *'
+ LONG_DOUBLE `long double' `double'
+ VOLATILE `volatile' `'
+ SIGNED `signed' `'
+ PTRCONST `void *const' `char *'
+ ANSI_PROTOTYPES 1 not defined
+
+ CONST is also defined, but is obsolete. Just use const.
+
+ DEFUN (name, arglist, args)
+
+ Defines function NAME.
+
+ ARGLIST lists the arguments, separated by commas and enclosed in
+ parentheses. ARGLIST becomes the argument list in traditional C.
+
+ ARGS list the arguments with their types. It becomes a prototype in
+ ANSI C, and the type declarations in traditional C. Arguments should
+ be separated with `AND'. For functions with a variable number of
+ arguments, the last thing listed should be `DOTS'.
+
+ DEFUN_VOID (name)
+
+ Defines a function NAME, which takes no arguments.
+
+ obsolete -- EXFUN (name, (prototype)) -- obsolete.
+
+ Replaced by PARAMS. Do not use; will disappear someday soon.
+ Was used in external function declarations.
+ In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
+ parentheses). In traditional C it is `NAME()'.
+ For a function that takes no arguments, PROTOTYPE should be `(void)'.
+
+ PARAMS ((args))
+
+ We could use the EXFUN macro to handle prototype declarations, but
+ the name is misleading and the result is ugly. So we just define a
+ simple macro to handle the parameter lists, as in:
+
+ static int foo PARAMS ((int, char));
+
+ This produces: `static int foo();' or `static int foo (int, char);'
+
+ EXFUN would have done it like this:
+
+ static int EXFUN (foo, (int, char));
+
+ but the function is not external...and it's hard to visually parse
+ the function name out of the mess. EXFUN should be considered
+ obsolete; new code should be written to use PARAMS.
+
+ For example:
+ extern int printf PARAMS ((CONST char *format DOTS));
+ int DEFUN(fprintf, (stream, format),
+ FILE *stream AND CONST char *format DOTS) { ... }
+ void DEFUN_VOID(abort) { ... }
+*/
+
+#ifndef _ANSIDECL_H
+
+#define _ANSIDECL_H 1
+
+
+/* Every source file includes this file,
+ so they will all get the switch for lint. */
+/* LINTLIBRARY */
+
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4))
+/* All known AIX compilers implement these things (but don't always
+ define __STDC__). The RISC/OS MIPS compiler defines these things
+ in SVR4 mode, but does not define __STDC__. */
+
+#define PTR void *
+#define PTRCONST void *CONST
+#define LONG_DOUBLE long double
+
+#define AND ,
+#define NOARGS void
+#define CONST const
+#define VOLATILE volatile
+#define SIGNED signed
+#define DOTS , ...
+
+#define EXFUN(name, proto) name proto
+#define DEFUN(name, arglist, args) name(args)
+#define DEFUN_VOID(name) name(void)
+
+#define PROTO(type, name, arglist) type name arglist
+#define PARAMS(paramlist) paramlist
+#define ANSI_PROTOTYPES 1
+
+#else /* Not ANSI C. */
+
+#define PTR char *
+#define PTRCONST PTR
+#define LONG_DOUBLE double
+
+#define AND ;
+#define NOARGS
+#define CONST
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define const
+#endif
+#define VOLATILE
+#define SIGNED
+#define DOTS
+
+#define EXFUN(name, proto) name()
+#define DEFUN(name, arglist, args) name arglist args;
+#define DEFUN_VOID(name) name()
+#define PROTO(type, name, arglist) type name ()
+#define PARAMS(paramlist) ()
+
+#endif /* ANSI C. */
+
+#endif /* ansidecl.h */
diff --git a/gnu/lib/libg++/include/bitdo1.h b/gnu/lib/libg++/include/bitdo1.h
new file mode 100644
index 0000000..c234d41
--- /dev/null
+++ b/gnu/lib/libg++/include/bitdo1.h
@@ -0,0 +1,32 @@
+#ifndef ONES
+#define ONES ((_BS_word)(~0L))
+#endif
+ register int nwords;
+ register _BS_word mask;
+ if (offset == 0)
+ ;
+ else if (offset + length >= _BS_BITS_PER_WORD)
+ {
+ mask = ONES _BS_RIGHT offset;
+ DOIT(*ptr++, mask);
+ length -= _BS_BITS_PER_WORD - offset;
+ }
+ else
+ {
+ mask = (ONES _BS_RIGHT (_BS_BITS_PER_WORD - length))
+ _BS_LEFT (_BS_BITS_PER_WORD - length - offset);
+ DOIT(*ptr, mask);
+ goto done;
+ }
+ nwords = _BS_INDEX(length);
+ while (--nwords >= 0)
+ {
+ DOIT(*ptr++, ONES);
+ }
+ length = _BS_POS (length);
+ if (length)
+ {
+ mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - length);
+ DOIT(*ptr, mask);
+ }
+ done: ;
diff --git a/gnu/lib/libg++/include/bitdo2.h b/gnu/lib/libg++/include/bitdo2.h
new file mode 100644
index 0000000..6e99523
--- /dev/null
+++ b/gnu/lib/libg++/include/bitdo2.h
@@ -0,0 +1,184 @@
+#ifndef ONES
+#define ONES ((_BS_word)(~0L))
+#endif
+
+#ifndef DOIT_SOLID
+#ifdef DOIT
+#define DOIT_SOLID(dst, src) DOIT(dst, src, (_BS_word)(~0))
+#else
+#define DOIT_SOLID(dst, src) (dst) = (COMBINE(dst, src))
+#endif
+#endif
+
+#ifndef DOIT
+#define DOIT(dst, src, mask) \
+ (dst) = ((COMBINE(dst, src)) & (mask)) | ((dst) & ~(mask))
+#endif
+
+ _BS_word word0, mask;
+ int shift0, shift1;
+
+ if (length == 0)
+ goto done;
+
+ shift0 = srcbit - dstbit;
+
+ /* First handle the case that only one destination word is touched. */
+ if (length + dstbit <= _BS_BITS_PER_WORD)
+ {
+ _BS_word mask
+ = (ONES _BS_LEFT (_BS_BITS_PER_WORD - length)) _BS_RIGHT dstbit;
+ _BS_word word0 = *psrc++;
+ if (shift0 <= 0) /* dstbit >= srcbit */
+ {
+ word0 = word0 _BS_RIGHT (-shift0);
+ }
+ else
+ {
+ word0 = word0 _BS_LEFT shift0;
+ if (length + srcbit > _BS_BITS_PER_WORD)
+ word0 = word0 | (*psrc _BS_RIGHT (_BS_BITS_PER_WORD - shift0));
+ }
+ DOIT(*pdst, word0, mask);
+ goto done;
+ }
+
+ /* Next optimize the case that the source and destination are aligned. */
+ if (shift0 == 0)
+ {
+ _BS_word mask;
+ if (psrc > pdst)
+ {
+ if (srcbit)
+ {
+ mask = ONES _BS_RIGHT srcbit;
+ DOIT(*pdst, *psrc, mask);
+ pdst++; psrc++;
+ length -= _BS_BITS_PER_WORD - srcbit;
+ }
+ for (; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
+ {
+ DOIT_SOLID(*pdst, *psrc);
+ pdst++; psrc++;
+ }
+ if (length)
+ {
+ mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - length);
+ DOIT(*pdst, *psrc, mask);
+ }
+ }
+ else if (psrc < pdst)
+ {
+ _BS_size_t span = srcbit + length;
+ pdst += span / (_BS_size_t)_BS_BITS_PER_WORD;
+ psrc += span / (_BS_size_t)_BS_BITS_PER_WORD;
+ span %= (_BS_size_t)_BS_BITS_PER_WORD;
+ if (span)
+ {
+ mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - span);
+ DOIT(*pdst, *psrc, mask);
+ length -= span;
+ }
+ pdst--; psrc--;
+ for (; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
+ {
+ DOIT_SOLID(*pdst, *psrc);
+ pdst--; psrc--;
+ }
+ if (srcbit)
+ {
+ mask = ONES _BS_RIGHT srcbit;
+ DOIT(*pdst, *psrc, mask);
+ }
+ }
+ /* else if (psrc == pdst) --nothing to do--; */
+ goto done;
+ }
+
+ /* Now we assume shift!=0, and more than on destination word is changed. */
+ if (psrc >= pdst) /* Do the updates in forward direction. */
+ {
+ _BS_word word0 = *psrc++;
+ _BS_word mask = ONES _BS_RIGHT dstbit;
+ if (shift0 > 0)
+ {
+ _BS_word word1 = *psrc++;
+ shift1 = _BS_BITS_PER_WORD - shift0;
+ DOIT(*pdst, (word0 _BS_LEFT shift0) | (word1 _BS_RIGHT shift1), mask);
+ word0 = word1;
+ }
+ else /* dstbit > srcbit */
+ {
+ shift1 = -shift0;
+ shift0 += _BS_BITS_PER_WORD;
+ DOIT(*pdst, word0 _BS_RIGHT shift1, mask);
+ }
+ pdst++;
+ length -= _BS_BITS_PER_WORD - dstbit;
+
+ for ( ; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
+ {
+ register _BS_word word1 = *psrc++;
+ DOIT_SOLID(*pdst,
+ (word0 _BS_LEFT shift0) | (word1 _BS_RIGHT shift1));
+ pdst++;
+ word0 = word1;
+ }
+ if (length > 0)
+ {
+ _BS_size_t mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - length);
+ word0 = word0 _BS_LEFT shift0;
+ if (length > shift1)
+ word0 = word0 | (*psrc _BS_RIGHT shift1) ;
+ DOIT (*pdst, word0, mask);
+ }
+ }
+ else /* Do the updates in backward direction. */
+ {
+ _BS_word word0;
+
+ /* Make (psrc, srcbit) and (pdst, dstbit) point to *last* bit. */
+ psrc += (srcbit + length - 1) / _BS_BITS_PER_WORD;
+ srcbit = (srcbit + length - 1) % _BS_BITS_PER_WORD;
+ pdst += (dstbit + length - 1) / _BS_BITS_PER_WORD;
+ dstbit = (dstbit + length - 1) % _BS_BITS_PER_WORD;
+
+ shift0 = srcbit - dstbit;
+
+ word0 = *psrc--;
+ mask = ONES _BS_LEFT (_BS_BITS_PER_WORD - 1 - dstbit);
+ if (shift0 < 0)
+ {
+ _BS_word word1 = *psrc--;
+ shift1 = -shift0;
+ shift0 += _BS_BITS_PER_WORD;
+ DOIT (*pdst, (word0 _BS_RIGHT shift1) | (word1 _BS_LEFT shift0),
+ mask);
+ word0 = word1;
+ }
+ else
+ {
+ shift1 = _BS_BITS_PER_WORD - shift0;
+ DOIT(*pdst, word0 _BS_LEFT shift0, mask);
+ }
+ pdst--;
+ length -= dstbit + 1;
+
+ for ( ; length >= _BS_BITS_PER_WORD; length -= _BS_BITS_PER_WORD)
+ {
+ register _BS_word word1 = *psrc--;
+ DOIT_SOLID(*pdst,
+ (word0 _BS_RIGHT shift1) | (word1 _BS_LEFT shift0));
+ pdst--;
+ word0 = word1;
+ }
+ if (length > 0)
+ {
+ _BS_size_t mask = ONES _BS_RIGHT (_BS_BITS_PER_WORD - length);
+ word0 = word0 _BS_RIGHT shift1;
+ if (length > shift0)
+ word0 = word0 | (*psrc _BS_LEFT shift0) ;
+ DOIT (*pdst, word0, mask);
+ }
+ }
+ done: ;
diff --git a/gnu/lib/libg++/include/bitprims.h b/gnu/lib/libg++/include/bitprims.h
new file mode 100644
index 0000000..771acd9
--- /dev/null
+++ b/gnu/lib/libg++/include/bitprims.h
@@ -0,0 +1,125 @@
+#ifndef _BS_PRIMS
+#define _BS_PRIMS
+
+/* For now, use unsigned short for compatibility with old libg++ code.
+ Later, change to unsigned long as the default. */
+typedef unsigned long _BS_word;
+
+#define _BS_CHAR_BIT 8
+#define _BS_BITS_PER_WORD (_BS_CHAR_BIT*sizeof(_BS_word))
+#define _BS_WORDS_NEEDED(NBITS) ((NBITS+_BS_BITS_PER_WORD-1)/_BS_BITS_PER_WORD)
+
+/* For now, we number the bits in a _BS_word in little-endian order.
+ Later, might use machine order. */
+#ifdef CHILL_LIB
+#ifndef BITS_BIG_ENDIAN
+#include "config.h"
+#endif
+#define _BS_BIGENDIAN BITS_BIG_ENDIAN
+#else
+#define _BS_BIGENDIAN 0
+#endif
+
+/* By "left" we mean where bit number 0 is.
+ Hence, so left shift is << if we're numbering the bits in big-endian oder,
+ and >> if we're numbering the bits in little-endian order.
+ Currently, we always use little-endian order.
+ Later, we might use machine-endian order. */
+#if _BS_BIGENDIAN
+#define _BS_LEFT <<
+#define _BS_RIGHT >>
+#else
+#define _BS_LEFT >>
+#define _BS_RIGHT <<
+#endif
+
+#if _BS_BIGENDIAN
+#define _BS_BITMASK(BITNO) (1 << (_BS_BITS_PER_WORD - 1 - (BITNO)))
+#else
+#define _BS_BITMASK(BITNO) (1 << (BITNO))
+#endif
+
+/* Given a PTR which may not be aligned on a _BS_word boundary,
+ set NEW_PTR to point to (the beginning of) the corresponding _BS_word.
+ Adjust the bit-offset OFFSET to compensate for the difference. */
+#define _BS_ADJUST_ALIGNED(NEW_PTR, PTR, OFFSET) \
+ ( (NEW_PTR) = (_BS_word*)(((char*)(PTR)-(char*)0) & ~(sizeof(_BS_word)-1)), \
+ (OFFSET) += (char*)(PTR) - (char*)(NEW_PTR) )
+
+/* Given a bit point (PTR, OFFSET) normalize it so that
+ OFFSET < _BS_BITS_PER_WORD. */
+#define _BS_NORMALIZE(PTR, OFFSET) \
+{ _BS_size_t __tmp_ind = _BS_INDEX (OFFSET); \
+ (PTR) += __tmp_ind; \
+ (OFFSET) -= __tmp_ind * _BS_BITS_PER_WORD; }
+
+#define _BS_INDEX(I) ((unsigned)(I) / _BS_BITS_PER_WORD)
+#define _BS_POS(I) ((I) & (_BS_BITS_PER_WORD -1 ))
+
+#ifndef _BS_size_t
+#ifdef __GNUC__
+#define _BS_size_t __SIZE_TYPE__
+#else
+#define _BS_size_t unsigned long
+#endif
+#endif
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(paramlist) paramlist
+#else
+#define __P(paramlist) ()
+#endif
+#endif /*!__P*/
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+#if !defined(__STDC__) && !defined(void)
+#define void int
+#endif
+
+/* The 16 2-operand raster-ops:
+ These match the correspodning GX codes in X11. */
+enum _BS_alu {
+ _BS_alu_clear = 0 /* 0 */,
+ _BS_alu_and = 1 /* src & dst */,
+ _BS_alu_andReverse = 2 /* src & ~dst */,
+ _BS_alu_copy = 3 /* src */,
+ _BS_alu_andInverted = 4 /* ~src & dst */,
+ _BS_alu_noop = 5 /* dst */,
+ _BS_alu_xor = 6 /* src ^ dst */,
+ _BS_alu_or = 7 /* src | dst */,
+ _BS_alu_nor = 8 /* ~src & ~dst */,
+ _BS_alu_equiv = 9 /* ~(src ^ dst) */,
+ _BS_alu_invert = 10 /* ~dst */,
+ _BS_alu_orReverse = 11 /* src | ~dst */,
+ _BS_alu_copyInverted = 12 /* ~src */,
+ _BS_alu_orInverted = 13 /* ~src | dst */,
+ _BS_alu_nand = 14 /* ~src | d~st */,
+ _BS_alu_set = 15 /* ~src | dst */
+};
+#define _BS
+#define _BS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void _BS_and __P((_BS_word*,int, const _BS_word*, int, _BS_size_t));
+extern void _BS_blt __P((enum _BS_alu,
+ _BS_word*,int, const _BS_word*,int, _BS_size_t));
+extern void _BS_copy __P((_BS_word*,int, const _BS_word*,int, _BS_size_t));
+#define _BS_copy_0(DS, SS, LENGTH) _BS_copy(DS, 0, SS, 0, LENGTH)
+extern int _BS_count __P((const _BS_word*, int, _BS_size_t));
+extern int _BS_any __P((const _BS_word*, int, _BS_size_t));
+extern void _BS_clear __P((_BS_word*, int, _BS_size_t));
+extern void _BS_set __P((_BS_word*, int, _BS_size_t));
+extern void _BS_invert __P((_BS_word*, int, _BS_size_t));
+int _BS_lcompare_0 __P((_BS_word*, _BS_size_t, _BS_word*, _BS_size_t));
+extern void _BS_xor __P((_BS_word*,int, const _BS_word*,int, _BS_size_t));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif _BS_PRIMS
diff --git a/gnu/lib/libg++/include/builtin.h b/gnu/lib/libg++/include/builtin.h
new file mode 100644
index 0000000..7f8299c
--- /dev/null
+++ b/gnu/lib/libg++/include/builtin.h
@@ -0,0 +1,159 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+Copyright (C) 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ arithmetic, etc. functions on built in types
+*/
+
+
+#ifndef _builtin_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _builtin_h 1
+
+#include <stddef.h>
+#include <std.h>
+#include <math.h>
+
+#ifdef __GNUG__
+#define _VOLATILE_VOID volatile void
+#else
+#define _VOLATILE_VOID void
+#endif
+
+typedef void (*one_arg_error_handler_t)(const char*);
+typedef void (*two_arg_error_handler_t)(const char*, const char*);
+
+long gcd(long, long);
+long lg(unsigned long);
+double pow(double, long);
+long pow(long, long);
+
+extern "C" double start_timer();
+extern "C" double return_elapsed_time(double last_time = 0.0);
+
+char* dtoa(double x, char cvt = 'g', int width = 0, int prec = 6);
+
+unsigned int hashpjw(const char*);
+unsigned int multiplicativehash(int);
+unsigned int foldhash(double);
+
+extern _VOLATILE_VOID default_one_arg_error_handler(const char*);
+extern _VOLATILE_VOID default_two_arg_error_handler(const char*, const char*);
+
+extern two_arg_error_handler_t lib_error_handler;
+
+extern two_arg_error_handler_t
+ set_lib_error_handler(two_arg_error_handler_t f);
+
+
+double abs(double arg);
+float abs(float arg);
+short abs(short arg);
+long abs(long arg);
+int sign(long arg);
+int sign(double arg);
+long sqr(long arg);
+double sqr(double arg);
+int even(long arg);
+int odd(long arg);
+long lcm(long x, long y);
+void (setbit)(long& x, long b);
+void clearbit(long& x, long b);
+int testbit(long x, long b);
+
+#if !defined(IV)
+
+#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
+inline double abs(double arg)
+{
+ return (arg < 0.0)? -arg : arg;
+}
+#endif
+
+inline float abs(float arg)
+{
+ return (arg < 0.0)? -arg : arg;
+}
+
+inline short abs(short arg)
+{
+ return (arg < 0)? -arg : arg;
+}
+
+inline long abs(long arg)
+{
+ return (arg < 0)? -arg : arg;
+}
+
+inline int sign(long arg)
+{
+ return (arg == 0) ? 0 : ( (arg > 0) ? 1 : -1 );
+}
+
+inline int sign(double arg)
+{
+ return (arg == 0.0) ? 0 : ( (arg > 0.0) ? 1 : -1 );
+}
+
+inline long sqr(long arg)
+{
+ return arg * arg;
+}
+
+#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
+inline double sqr(double arg)
+{
+ return arg * arg;
+}
+#endif
+
+inline int even(long arg)
+{
+ return !(arg & 1);
+}
+
+inline int odd(long arg)
+{
+ return (arg & 1);
+}
+
+inline long lcm(long x, long y)
+{
+ return x / gcd(x, y) * y;
+}
+
+inline void (setbit)(long& x, long b)
+{
+ x |= (1 << b);
+}
+
+inline void clearbit(long& x, long b)
+{
+ x &= ~(1 << b);
+}
+
+inline int testbit(long x, long b)
+{
+ return ((x & (1 << b)) != 0);
+}
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/include/builtinbuf.h b/gnu/lib/libg++/include/builtinbuf.h
new file mode 100644
index 0000000..fb91e6a
--- /dev/null
+++ b/gnu/lib/libg++/include/builtinbuf.h
@@ -0,0 +1,63 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+// A builtinbuf a a streambuf where all the virtual operations
+// call the _IO_jump_t table.
+
+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() { }
+};
+#endif /* _BUILTINBUF_H */
diff --git a/gnu/lib/libg++/include/compare.h b/gnu/lib/libg++/include/compare.h
new file mode 100644
index 0000000..bd13614
--- /dev/null
+++ b/gnu/lib/libg++/include/compare.h
@@ -0,0 +1,91 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _compare_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _compare_h 1
+
+#include <builtin.h>
+
+int compare(int a, int b);
+int compare(short a, short b);
+int compare(unsigned long a, unsigned long b);
+int compare(unsigned int a, unsigned int b);
+int compare(unsigned short a, unsigned short b);
+int compare(unsigned char a, unsigned char b);
+int compare(signed char a, signed char b);
+int compare(float a, float b);
+int compare(double a, double b);
+int compare(const char* a, const char* b);
+
+
+inline int compare(int a, int b)
+{
+ return a - b;
+}
+
+inline int compare(short a, short b)
+{
+ return a - b;
+}
+
+
+inline int compare(signed char a, signed char b)
+{
+ return a - b;
+}
+
+inline int compare(unsigned long a, unsigned long b)
+{
+ return (a < b)? -1 : (a > b)? 1 : 0;
+}
+
+inline int compare(unsigned int a, unsigned int b)
+{
+ return (a < b)? -1 : (a > b)? 1 : 0;
+}
+
+inline int compare(unsigned short a, unsigned short b)
+{
+ return (a < b)? -1 : (a > b)? 1 : 0;
+}
+
+inline int compare(unsigned char a, unsigned char b)
+{
+ return (a < b)? -1 : (a > b)? 1 : 0;
+}
+
+inline int compare(float a, float b)
+{
+ return (a < b)? -1 : (a > b)? 1 : 0;
+}
+
+inline int compare(double a, double b)
+{
+ return (a < b)? -1 : (a > b)? 1 : 0;
+}
+
+inline int compare(const char* a, const char* b)
+{
+ return strcmp(a,b);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/config.h b/gnu/lib/libg++/include/config.h
new file mode 100644
index 0000000..b37ee84
--- /dev/null
+++ b/gnu/lib/libg++/include/config.h
@@ -0,0 +1 @@
+/* !Automatically generated from ./functions.def - DO NOT EDIT! */
diff --git a/gnu/lib/libg++/include/defines.h b/gnu/lib/libg++/include/defines.h
new file mode 100644
index 0000000..ddb76e9
--- /dev/null
+++ b/gnu/lib/libg++/include/defines.h
@@ -0,0 +1,33 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1994 Free Software Foundation
+ written by Jason Merrill (jason@cygnus.com)
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _defines_h
+#define _defines_h
+
+#include <_G_config.h>
+#include <stddef.h>
+
+const size_t NPOS = (size_t)(-1);
+typedef void fvoid_t();
+
+#ifndef _WINT_T
+#define _WINT_T
+typedef _G_wint_t wint_t;
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/include/editbuf.h b/gnu/lib/libg++/include/editbuf.h
new file mode 100644
index 0000000..8535155
--- /dev/null
+++ b/gnu/lib/libg++/include/editbuf.h
@@ -0,0 +1,183 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+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 *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);
+}
+#endif /* !_EDITBUF_H*/
+
diff --git a/gnu/lib/libg++/include/floatio.h b/gnu/lib/libg++/include/floatio.h
new file mode 100644
index 0000000..edfe297
--- /dev/null
+++ b/gnu/lib/libg++/include/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/include/fstream.h b/gnu/lib/libg++/include/fstream.h
new file mode 100644
index 0000000..20dfbf2
--- /dev/null
+++ b/gnu/lib/libg++/include/fstream.h
@@ -0,0 +1,81 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+class fstreambase : virtual public ios {
+ public:
+ fstreambase();
+ fstreambase(int fd);
+ fstreambase(int fd, char *p, int l); /* Deprecated */
+ fstreambase(const char *name, int mode, int prot=0664);
+ void close();
+ filebuf* rdbuf() const { return (filebuf*) ios::rdbuf(); }
+ 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); }
+#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); }
+};
+#endif /*!_FSTREAM_H*/
diff --git a/gnu/lib/libg++/include/indstream.h b/gnu/lib/libg++/include/indstream.h
new file mode 100644
index 0000000..8047b82
--- /dev/null
+++ b/gnu/lib/libg++/include/indstream.h
@@ -0,0 +1,74 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+// 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 int xsputn(const char* s, int n);
+ virtual int xsgetn(char* s, int n);
+ virtual int underflow();
+ 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);
+};
+
+#endif /* !_INDSTREAM_H */
diff --git a/gnu/lib/libg++/include/iolibio.h b/gnu/lib/libg++/include/iolibio.h
new file mode 100644
index 0000000..2a7c145
--- /dev/null
+++ b/gnu/lib/libg++/include/iolibio.h
@@ -0,0 +1,46 @@
+#include "libio.h"
+
+/* These emulate stdio functionality, but with a different name
+ (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */
+
+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_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_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));
+#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_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
+#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+#define _IO_fseek(__fp, __offset, __whence) \
+ (_IO_seekoff(__fp, __offset, (_IO_off_t)(__whence)) == _IO_pos_BAD ? EOF : 0)
+#define _IO_rewind(FILE) (void)_IO_seekoff(FILE, 0, 0)
+#define _IO_vprintf(FORMAT, ARGS) _IO_vfprintf(_IO_stdout, FORMAT, ARGS)
+#define _IO_freopen(FILENAME, MODE, FP) \
+ (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE))
+#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)
+
diff --git a/gnu/lib/libg++/include/iomanip.h b/gnu/lib/libg++/include/iomanip.h
new file mode 100644
index 0000000..cab4b97
--- /dev/null
+++ b/gnu/lib/libg++/include/iomanip.h
@@ -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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+//-----------------------------------------------------------------------------
+// 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> 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> 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)
+ { 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> 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, 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)
+
+#endif /*!_IOMANIP_H*/
diff --git a/gnu/lib/libg++/include/iostream.h b/gnu/lib/libg++/include/iostream.h
new file mode 100644
index 0000000..7348ce2
--- /dev/null
+++ b/gnu/lib/libg++/include/iostream.h
@@ -0,0 +1,227 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+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(); return 1;} }
+ void osfx() { 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, int n);
+ ostream& write(const unsigned char *s, int n) { return write((const char*)s, n);}
+ ostream& write(const signed char *s, int n) { return write((const char*)s, n);}
+ ostream& write(const void *s, int 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__) && !defined(__STRICT_ANSI__)
+ ostream& operator<<(long long n);
+ 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); }
+ 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!
+ _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, int n);
+ istream& read(unsigned char *ptr, int n) { return read((char*)ptr, n); }
+ istream& read(signed char *ptr, int n) { return read((char*)ptr, n); }
+ istream& read(void *ptr, int n) { return read((char*)ptr, n); }
+ istream& get(streambuf& sb, char delim = '\n');
+ istream& gets(char **s, char delim = '\n');
+ int ipfx(int need) {
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ 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 {
+ 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 {
+ if (_tie && rdbuf()->in_avail() == 0) _tie->flush();
+ return 1;
+ }
+ }
+ void isfx() { }
+ 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);
+ 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__) && !defined(__STRICT_ANSI__)
+ istream& operator>>(long long&);
+ 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>>( __manip func) {(*func)(*this); return *this;}
+ istream& operator>>(__imanip func) { return (*func)(*this); }
+ istream& operator>>(streambuf*);
+};
+
+
+class iostream : public istream, public ostream
+{
+ _IO_size_t _gcount;
+ public:
+ iostream() { _gcount = 0; }
+ iostream(streambuf* sb, ostream*tied=NULL);
+};
+
+extern istream cin;
+extern ostream cout, cerr, clog; // clog->rdbuf() == cerr->rdbuf()
+
+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; }
+
+#endif /*!_IOSTREAM_H*/
diff --git a/gnu/lib/libg++/include/iostreamP.h b/gnu/lib/libg++/include/iostreamP.h
new file mode 100644
index 0000000..720deb3
--- /dev/null
+++ b/gnu/lib/libg++/include/iostreamP.h
@@ -0,0 +1,34 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
+
+inline _IO_seekflags
+convert_to_seekflags(int dir, int mode)
+{
+ return (_IO_seekflags)((int)dir
+ | (mode & ios::in ? _IO_seek_set : _IO_seek_not_in)
+ | (mode & ios::out ? _IO_seek_set : _IO_seek_not_out));
+}
diff --git a/gnu/lib/libg++/include/libiberty.h b/gnu/lib/libg++/include/libiberty.h
new file mode 100644
index 0000000..9854b4c
--- /dev/null
+++ b/gnu/lib/libg++/include/libiberty.h
@@ -0,0 +1,107 @@
+/* Function declarations for libiberty.
+ Written by Cygnus Support, 1994.
+
+ The libiberty library provides a number of functions which are
+ missing on some operating systems. We do not declare those here,
+ to avoid conflicts with the system header files on operating
+ systems that do support those functions. In this file we only
+ declare those functions which are specific to libiberty. */
+
+#ifndef LIBIBERTY_H
+#define LIBIBERTY_H
+
+#include "ansidecl.h"
+
+/* Build an argument vector from a string. Allocates memory using
+ malloc. Use freeargv to free the vector. */
+
+extern char **buildargv PARAMS ((char *));
+
+/* Free a vector returned by buildargv. */
+
+extern void freeargv PARAMS ((char **));
+
+/* Return the last component of a path name. */
+
+extern char *basename PARAMS ((char *));
+
+/* Concatenate an arbitrary number of strings, up to (char *) NULL.
+ Allocates memory using xmalloc. */
+
+extern char *concat PARAMS ((const char *, ...));
+
+/* Check whether two file descriptors refer to the same file. */
+
+extern int fdmatch PARAMS ((int fd1, int fd2));
+
+/* Get the amount of time the process has run, in microseconds. */
+
+extern long get_run_time PARAMS ((void));
+
+/* Allocate memory filled with spaces. Allocates using malloc. */
+
+extern const char *spaces PARAMS ((int count));
+
+/* Return the maximum error number for which strerror will return a
+ string. */
+
+extern int errno_max PARAMS ((void));
+
+/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
+ "EINVAL"). */
+
+extern const char *strerrno PARAMS ((int));
+
+/* Given the name of an errno value, return the value. */
+
+extern int strtoerrno PARAMS ((const char *));
+
+/* Return the maximum signal number for which strsignal will return a
+ string. */
+
+extern int signo_max PARAMS ((void));
+
+/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
+ "SIGHUP"). */
+
+extern const char *strsigno PARAMS ((int));
+
+/* Given the name of a signal, return its number. */
+
+extern int strtosigno PARAMS ((const char *));
+
+/* Register a function to be run by xexit. Returns 0 on success. */
+
+extern int xatexit PARAMS ((void (*fn) (void)));
+
+/* Exit, calling all the functions registered with xatexit. */
+
+#ifndef __GNUC__
+extern void xexit PARAMS ((int status));
+#else
+typedef void libiberty_voidfn PARAMS ((int status));
+__volatile__ libiberty_voidfn xexit;
+#endif
+
+/* Set the program name used by xmalloc. */
+
+extern void xmalloc_set_program_name PARAMS ((const char *));
+
+/* Allocate memory without fail. If malloc fails, this will print a
+ message to stderr (using the name set by xmalloc_set_program_name,
+ if any) and then call xexit.
+
+ FIXME: We do not declare the parameter type (size_t) in order to
+ avoid conflicts with other declarations of xmalloc that exist in
+ programs which use libiberty. */
+
+extern PTR xmalloc ();
+
+/* Reallocate memory without fail. This works like xmalloc.
+
+ FIXME: We do not declare the parameter types for the same reason as
+ xmalloc. */
+
+extern PTR xrealloc ();
+
+#endif /* ! defined (LIBIBERTY_H) */
diff --git a/gnu/lib/libg++/include/libio.h b/gnu/lib/libg++/include/libio.h
new file mode 100644
index 0000000..a064197
--- /dev/null
+++ b/gnu/lib/libg++/include/libio.h
@@ -0,0 +1,254 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 is part of the iostream library.
+ Copyright (C) 1991, 1992 Per Bothner. */
+
+#ifndef _IO_STDIO_H
+#define _IO_STDIO_H
+
+#if 1
+#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
+
+#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
+
+#else
+#include <_IO_config.h>
+typedef _IO_fpos_t _IO_pos_t;
+#endif
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(paramlist) paramlist
+#else
+#define __P(paramlist) ()
+#endif
+#endif /*!__P*/
+
+/* For backward compatibility */
+#ifndef _PARAMS
+#define _PARAMS(paramlist) __P(paramlist)
+#endif /*!_PARAMS*/
+
+#ifndef __STDC__
+#define const
+#endif
+#define USE_DTOA
+
+#if 0
+#ifdef _IO_NEED_STDARG_H
+#include <stdarg.h>
+#endif
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#if !defined(__cplusplus) || defined(__GNUC__)
+#define NULL ((void*)0)
+#else
+#define NULL (0)
+#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 abailable 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
+#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
+
+/* 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
+
+/* A streammarker remembers a position in a buffer. */
+
+struct _IO_jump_t; struct _IO_FILE;
+
+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. */
+ 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;
+
+ struct _IO_jump_t *_jumps; /* Jump table */
+
+ int _fileno;
+ int _blksize;
+ _IO_off_t _offset;
+
+#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; */
+};
+
+#ifndef __cplusplus
+typedef struct _IO_FILE _IO_FILE;
+#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_))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int __underflow __P((_IO_FILE*));
+extern int __uflow __P((_IO_FILE*));
+extern int __overflow __P((_IO_FILE*, int));
+
+extern unsigned __adjust_column __P((unsigned start, const char *line, int count));
+
+#define _IO_getc(_fp) \
+ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow(_fp) \
+ : *(unsigned char*)(_fp)->_IO_read_ptr++)
+#define _IO_peekc(_fp) \
+ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \
+ && __underflow(_fp) == EOF ? EOF \
+ : *(unsigned char*)(_fp)->_IO_read_ptr)
+
+#define _IO_putc(_ch, _fp) \
+ (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \
+ ? __overflow(_fp, (unsigned char)(_ch)) \
+ : (unsigned char)(*(_fp)->_IO_write_ptr++ = (_ch)))
+
+/* This one is for Emacs. */
+#define _IO_PENDING_OUTPUT_COUNT(_fp) \
+ ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)
+
+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));
+
+extern void _IO_free_backup_area __P((_IO_FILE*));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IO_STDIO_H */
diff --git a/gnu/lib/libg++/include/libioP.h b/gnu/lib/libg++/include/libioP.h
new file mode 100644
index 0000000..11d90f5
--- /dev/null
+++ b/gnu/lib/libg++/include/libioP.h
@@ -0,0 +1,308 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 errno
+extern int errno;
+#endif
+
+#include "iolibio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _IO_seekflags_ {
+ _IO_seek_set = 0,
+ _IO_seek_cur = 1,
+ _IO_seek_end = 2,
+
+ /* These bits are ignored unless the _IO_FILE has independent
+ read and write positions. */
+ _IO_seek_not_in = 4, /* Don't move read posistion. */
+ _IO_seek_not_out = 8, /* Don't move write posistion. */
+ _IO_seek_pos_ignored = 16 /* Result is ignored (except EOF) */
+} _IO_seekflags;
+
+typedef int (*_IO_overflow_t) __P((_IO_FILE*, int));
+typedef int (*_IO_underflow_t) __P((_IO_FILE*));
+typedef _IO_size_t (*_IO_xsputn_t) __P((_IO_FILE*,const void*,_IO_size_t));
+typedef _IO_size_t (*_IO_xsgetn_t) __P((_IO_FILE*, void*, _IO_size_t));
+typedef _IO_ssize_t (*_IO_read_t) __P((_IO_FILE*, void*, _IO_ssize_t));
+typedef _IO_ssize_t (*_IO_write_t) __P((_IO_FILE*,const void*,_IO_ssize_t));
+typedef int (*_IO_stat_t) __P((_IO_FILE*, void*));
+typedef _IO_fpos_t (*_IO_seek_t) __P((_IO_FILE*, _IO_off_t, int));
+typedef int (*_IO_doallocate_t) __P((_IO_FILE*));
+typedef int (*_IO_pbackfail_t) __P((_IO_FILE*, int));
+typedef int (*_IO_setbuf_t) __P((_IO_FILE*, char *, _IO_ssize_t));
+typedef int (*_IO_sync_t) __P((_IO_FILE*));
+typedef void (*_IO_finish_t) __P((_IO_FILE*)); /* finalize */
+typedef int (*_IO_close_t) __P((_IO_FILE*)); /* finalize */
+typedef _IO_fpos_t (*_IO_seekoff_t) __P((_IO_FILE*, _IO_off_t, _IO_seekflags));
+
+/* The _IO_seek_cur and _IO_seek_end options are not allowed. */
+typedef _IO_fpos_t (*_IO_seekpos_t) __P((_IO_FILE*, _IO_fpos_t, _IO_seekflags));
+
+struct _IO_jump_t {
+ _IO_overflow_t __overflow;
+ _IO_underflow_t __underflow;
+ _IO_xsputn_t __xsputn;
+ _IO_xsgetn_t __xsgetn;
+ _IO_read_t __read;
+ _IO_write_t __write;
+ _IO_doallocate_t __doallocate;
+ _IO_pbackfail_t __pbackfail;
+ _IO_setbuf_t __setbuf;
+ _IO_sync_t __sync;
+ _IO_finish_t __finish;
+ _IO_close_t __close;
+ _IO_stat_t __stat;
+ _IO_seek_t __seek;
+ _IO_seekoff_t __seekoff;
+ _IO_seekpos_t __seekpos;
+ _IO_underflow_t __uflow;
+#if 0
+ get_column;
+ set_column;
+#endif
+};
+
+/* We always allocate an extra word following an _IO_FILE.
+ 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 void *vtable;
+};
+
+/* Generic functions */
+
+extern _IO_fpos_t _IO_seekoff __P((_IO_FILE*, _IO_off_t, _IO_seekflags));
+extern _IO_fpos_t _IO_seekpos __P((_IO_FILE*, _IO_fpos_t, _IO_seekflags));
+
+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) (__fp->_jumps->__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 _PARAMS((_IO_FILE*));
+extern int _IO_default_doallocate __P((_IO_FILE*));
+extern void _IO_default_finish __P((_IO_FILE *));
+extern int _IO_default_pbackfail __P((_IO_FILE*, int));
+extern int _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));
+extern _IO_fpos_t _IO_default_seekoff __P((_IO_FILE*, _IO_off_t, _IO_seekflags));
+extern _IO_fpos_t _IO_default_seekpos __P((_IO_FILE*, _IO_fpos_t, _IO_seekflags));
+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*));
+extern _IO_fpos_t _IO_default_seek __P((_IO_FILE*, _IO_off_t, int));
+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(());
+extern void _IO_cleanup __P(());
+extern void _IO_flush_all_linebuffered __P(());
+
+#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(p) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
+
+/* Jumptable functions for files. */
+
+extern int _IO_file_doallocate __P((_IO_FILE*));
+extern int _IO_file_setbuf __P((_IO_FILE *, char*, _IO_ssize_t));
+extern _IO_fpos_t _IO_file_seekoff __P((_IO_FILE*, _IO_off_t, _IO_seekflags));
+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_fopen __P((_IO_FILE*, const char*, const char*));
+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 _IO_fpos_t _IO_file_seek __P((_IO_FILE *, _IO_off_t, int));
+extern void _IO_file_finish __P((_IO_FILE*));
+
+/* Other file functions. */
+extern _IO_FILE* _IO_file_attach __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));
+extern _IO_fpos_t _IO_str_seekoff __P((_IO_FILE*,_IO_off_t,_IO_seekflags));
+
+/* 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 _IO_size_t _IO_getline __P((_IO_FILE*,char*,_IO_size_t,int,int));
+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)();
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#if !defined(__cplusplus) || defined(__GNUC__)
+#define NULL ((void*)0)
+#else
+#define NULL (0)
+#endif
+#endif
+
+#define FREE_BUF(_B) free(_B)
+#define ALLOC_BUF(_S) (char*)malloc(_S)
+
+#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 *));
+
+/* 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
+#define _IO_pos_BAD ((_IO_fpos_t)(-1))
+#endif
+/* _IO_pos_as_off converts an _IO_fpos_t value to an _IO_off_t value. */
+#ifndef _IO_pos_as_off
+#define _IO_pos_as_off(__pos) ((_IO_off_t)(__pos))
+#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
+#define _IO_pos_0 ((_IO_fpos_t)0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* 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, &_IO_file_jumps, FD}
+
+/* Define builtinbuf_vtable as a name for the virtual function table
+ of the builtinbuf class. */
+#if !defined(builtinbuf_vtable) && defined(__cplusplus)
+#ifdef __GNUC__
+extern char builtinbuf_vtable[]
+ asm (_G_VTABLE_LABEL_PREFIX
+#if _G_VTABLE_LABEL_HAS_LENGTH
+ "10"
+#endif
+ "builtinbuf");
+#else /* !__GNUC__ */
+#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
+extern char builtinbuf_vtable[];
+#endif /* !__GNUC__ */
+#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
diff --git a/gnu/lib/libg++/include/new.h b/gnu/lib/libg++/include/new.h
new file mode 100644
index 0000000..61bbba5
--- /dev/null
+++ b/gnu/lib/libg++/include/new.h
@@ -0,0 +1,27 @@
+#ifndef _new_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _new_h 1
+
+#include <defines.h>
+
+#ifndef NO_LIBGXX_MALLOC
+#define MALLOC_ALIGN_MASK 7 /* ptrs aligned at 8 byte boundaries */
+#define MALLOC_MIN_OVERHEAD 8 /* 8 bytes of overhead per pointer */
+#endif
+
+extern "C" fvoid_t *set_new_handler(fvoid_t *);
+
+#ifdef __GNUG__
+extern fvoid_t *__new_handler;
+extern "C" void __default_new_handler();
+
+#define NEW(where) new ( where )
+#endif
+
+// default placement version of operator new
+inline void *operator new(size_t, void *place) { return place; }
+inline void *operator new[](size_t, void *place) { return place; }
+
+#endif
diff --git a/gnu/lib/libg++/include/parsestream.h b/gnu/lib/libg++/include/parsestream.h
new file mode 100644
index 0000000..b168707
--- /dev/null
+++ b/gnu/lib/libg++/include/parsestream.h
@@ -0,0 +1,154 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
+
+// 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
+#endif /*!defined(PARSESTREAM_H)*/
diff --git a/gnu/lib/libg++/include/pfstream.h b/gnu/lib/libg++/include/pfstream.h
new file mode 100644
index 0000000..687faf6
--- /dev/null
+++ b/gnu/lib/libg++/include/pfstream.h
@@ -0,0 +1,57 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+// 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);
+};
+#endif /*!_PFSTREAM_H*/
+
diff --git a/gnu/lib/libg++/include/procbuf.h b/gnu/lib/libg++/include/procbuf.h
new file mode 100644
index 0000000..092d9cf
--- /dev/null
+++ b/gnu/lib/libg++/include/procbuf.h
@@ -0,0 +1,39 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 <streambuf.h>
+
+class procbuf : public filebuf {
+ /* Following fields must match those in struct _IO_proc_file */
+ _IO_pid_t _pid;
+ 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();
+};
diff --git a/gnu/lib/libg++/include/regex.h b/gnu/lib/libg++/include/regex.h
new file mode 100644
index 0000000..9e404e8
--- /dev/null
+++ b/gnu/lib/libg++/include/regex.h
@@ -0,0 +1,272 @@
+/* Definitions for data structures callers pass the regex library.
+
+ Copyright (C) 1985, 1989-92 Free Software Foundation, Inc.
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __REGEXP_LIBRARY
+#define __REGEXP_LIBRARY
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define re_compile_pattern recmppat
+#define re_pattern_buffer repatbuf
+#define re_registers reregs
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define number of parens for which we record the beginnings and ends.
+ This affects how much space the `struct re_registers' type takes up. */
+#ifndef RE_NREGS
+#define RE_NREGS 10
+#endif
+
+#define BYTEWIDTH 8
+
+
+/* Maximum number of duplicates an interval can allow. */
+#ifndef RE_DUP_MAX /* kludge for AIX, which defines it */
+#define RE_DUP_MAX ((1 << 15) - 1)
+#endif
+
+/* This defines the various regexp syntaxes. */
+extern int obscure_syntax;
+
+
+/* The following bits are used in the obscure_syntax variable to choose among
+ alternative regexp syntaxes. */
+
+/* If this bit is set, plain parentheses serve as grouping, and backslash
+ parentheses are needed for literal searching.
+ If not set, backslash-parentheses are grouping, and plain parentheses
+ are for literal searching. */
+#define RE_NO_BK_PARENS 1
+
+/* If this bit is set, plain | serves as the `or'-operator, and \| is a
+ literal.
+ If not set, \| serves as the `or'-operator, and | is a literal. */
+#define RE_NO_BK_VBAR (1 << 1)
+
+/* If this bit is not set, plain + or ? serves as an operator, and \+, \? are
+ literals.
+ If set, \+, \? are operators and plain +, ? are literals. */
+#define RE_BK_PLUS_QM (1 << 2)
+
+/* If this bit is set, | binds tighter than ^ or $.
+ If not set, the contrary. */
+#define RE_TIGHT_VBAR (1 << 3)
+
+/* If this bit is set, then treat newline as an OR operator.
+ If not set, treat it as a normal character. */
+#define RE_NEWLINE_OR (1 << 4)
+
+/* If this bit is set, then special characters may act as normal
+ characters in some contexts. Specifically, this applies to:
+ ^ -- only special at the beginning, or after ( or |;
+ $ -- only special at the end, or before ) or |;
+ *, +, ? -- only special when not after the beginning, (, or |.
+ If this bit is not set, special characters (such as *, ^, and $)
+ always have their special meaning regardless of the surrounding
+ context. */
+#define RE_CONTEXT_INDEP_OPS (1 << 5)
+
+/* If this bit is not set, then \ before anything inside [ and ] is taken as
+ a real \.
+ If set, then such a \ escapes the following character. This is a
+ special case for awk. */
+#define RE_AWK_CLASS_HACK (1 << 6)
+
+/* If this bit is set, then \{ and \} or { and } serve as interval operators.
+ If not set, then \{ and \} and { and } are treated as literals. */
+#define RE_INTERVALS (1 << 7)
+
+/* If this bit is not set, then \{ and \} serve as interval operators and
+ { and } are literals.
+ If set, then { and } serve as interval operators and \{ and \} are
+ literals. */
+#define RE_NO_BK_CURLY_BRACES (1 << 8)
+
+/* If this bit is set, then character classes are supported; they are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (1 << 9)
+
+/* If this bit is set, then the dot re doesn't match a null byte.
+ If not set, it does. */
+#define RE_DOT_NOT_NULL (1 << 10)
+
+/* If this bit is set, then [^...] doesn't match a newline.
+ If not set, it does. */
+#define RE_HAT_NOT_NEWLINE (1 << 11)
+
+/* If this bit is set, back references are recognized.
+ If not set, they aren't. */
+#define RE_NO_BK_REFS (1 << 12)
+
+/* If this bit is set, back references must refer to a preceding
+ subexpression. If not set, a back reference to a nonexistent
+ subexpression is treated as literal characters. */
+#define RE_NO_EMPTY_BK_REF (1 << 13)
+
+/* If this bit is set, bracket expressions can't be empty.
+ If it is set, they can be empty. */
+#define RE_NO_EMPTY_BRACKETS (1 << 14)
+
+/* If this bit is set, then *, +, ? and { cannot be first in an re or
+ immediately after a |, or a (. Furthermore, a | cannot be first or
+ last in an re, or immediately follow another | or a (. Also, a ^
+ cannot appear in a nonleading position and a $ cannot appear in a
+ nontrailing position (outside of bracket expressions, that is). */
+#define RE_CONTEXTUAL_INVALID_OPS (1 << 15)
+
+/* If this bit is set, then +, ? and | aren't recognized as operators.
+ If it's not, they are. */
+#define RE_LIMITED_OPS (1 << 16)
+
+/* If this bit is set, then an ending range point has to collate higher
+ or equal to the starting range point.
+ If it's not set, then when the ending range point collates higher
+ than the starting range point, the range is just considered empty. */
+#define RE_NO_EMPTY_RANGES (1 << 17)
+
+/* If this bit is set, then a hyphen (-) can't be an ending range point.
+ If it isn't, then it can. */
+#define RE_NO_HYPHEN_RANGE_END (1 << 18)
+
+
+/* Define combinations of bits for the standard possibilities. */
+#define RE_SYNTAX_POSIX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS)
+#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS | RE_AWK_CLASS_HACK)
+#define RE_SYNTAX_EGREP (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS | RE_NEWLINE_OR)
+#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
+#define RE_SYNTAX_EMACS 0
+#define RE_SYNTAX_POSIX_BASIC (RE_INTERVALS | RE_BK_PLUS_QM \
+ | RE_CHAR_CLASSES | RE_DOT_NOT_NULL \
+ | RE_HAT_NOT_NEWLINE | RE_NO_EMPTY_BK_REF \
+ | RE_NO_EMPTY_BRACKETS | RE_LIMITED_OPS \
+ | RE_NO_EMPTY_RANGES | RE_NO_HYPHEN_RANGE_END)
+
+#define RE_SYNTAX_POSIX_EXTENDED (RE_INTERVALS | RE_NO_BK_CURLY_BRACES \
+ | RE_NO_BK_VBAR | RE_NO_BK_PARENS \
+ | RE_HAT_NOT_NEWLINE | RE_CHAR_CLASSES \
+ | RE_NO_EMPTY_BRACKETS | RE_CONTEXTUAL_INVALID_OPS \
+ | RE_NO_BK_REFS | RE_NO_EMPTY_RANGES \
+ | RE_NO_HYPHEN_RANGE_END)
+
+
+/* This data structure is used to represent a compiled pattern. */
+
+struct re_pattern_buffer
+ {
+ char *buffer; /* Space holding the compiled pattern commands. */
+ long allocated; /* Size of space that `buffer' points to. */
+ long used; /* Length of portion of buffer actually occupied */
+ char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
+ /* re_search uses the fastmap, if there is one,
+ to skip over totally implausible characters. */
+ char *translate; /* Translate table to apply to all characters before
+ comparing, or zero for no translation.
+ The translation is applied to a pattern when it is
+ compiled and to data when it is matched. */
+ char fastmap_accurate;
+ /* Set to zero when a new pattern is stored,
+ set to one when the fastmap is updated from it. */
+ char can_be_null; /* Set to one by compiling fastmap
+ if this pattern might match the null string.
+ It does not necessarily match the null string
+ in that case, but if this is zero, it cannot.
+ 2 as value means can match null string
+ but at end of range or before a character
+ listed in the fastmap. */
+ };
+
+
+/* search.c (search_buffer) needs this one value. It is defined both in
+ regex.c and here. */
+#define RE_EXACTN_VALUE 1
+
+
+/* Structure to store register contents data in.
+
+ Pass the address of such a structure as an argument to re_match, etc.,
+ if you want this information back.
+
+ For i from 1 to RE_NREGS - 1, start[i] records the starting index in
+ the string of where the ith subexpression matched, and end[i] records
+ one after the ending index. start[0] and end[0] are analogous, for
+ the entire pattern. */
+
+struct re_registers
+ {
+ int start[RE_NREGS];
+ int end[RE_NREGS];
+ };
+
+
+
+#if defined(__STDC__) || defined(__cplusplus)
+
+extern char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);
+/* Is this really advertised? */
+extern void re_compile_fastmap (struct re_pattern_buffer *);
+extern int re_search (struct re_pattern_buffer *, char*, int, int, int,
+ struct re_registers *);
+extern int re_search_2 (struct re_pattern_buffer *, char *, int,
+ char *, int, int, int,
+ struct re_registers *, int);
+extern int re_match (struct re_pattern_buffer *, char *, int, int,
+ struct re_registers *);
+extern int re_match_2 (struct re_pattern_buffer *, char *, int,
+ char *, int, int, struct re_registers *, int);
+
+#if 0
+/* 4.2 bsd compatibility. */
+extern char *re_comp (char *);
+extern int re_exec (char *);
+#endif
+
+#else /* !__STDC__ */
+
+#define const /* nothing */
+extern char *re_compile_pattern ();
+/* Is this really advertised? */
+extern void re_compile_fastmap ();
+extern int re_search (), re_search_2 ();
+extern int re_match (), re_match_2 ();
+
+#if 0
+/* 4.2 bsd compatibility. */
+extern char *re_comp ();
+extern int re_exec ();
+#endif
+
+#endif /* __STDC__ */
+
+
+#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
+#endif
+
+#ifdef __cplusplus
+extern int re_max_failures;
+}
+#endif
+
+#endif /* !__REGEXP_LIBRARY */
diff --git a/gnu/lib/libg++/include/std.h b/gnu/lib/libg++/include/std.h
new file mode 100644
index 0000000..069b522
--- /dev/null
+++ b/gnu/lib/libg++/include/std.h
@@ -0,0 +1,35 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _std_h
+#define _std_h 1
+
+#include <_G_config.h>
+#include <defines.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+
+extern "C" {
+int strcasecmp _G_ARGS((const char*, const char*));
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/stdiostream.h b/gnu/lib/libg++/include/stdiostream.h
new file mode 100644
index 0000000..8c8215e
--- /dev/null
+++ b/gnu/lib/libg++/include/stdiostream.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+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) : _file(__f), istream() { 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) : _file(__f), ostream() { init(&_file); }
+ stdiobuf* rdbuf() /* const */ { return &_file; }
+ int buffered () const { return _file.buffered (); }
+ void buffered (int _i) { _file.buffered (_i); }
+};
+
+#endif /* !_STDIOSTREAM_H */
diff --git a/gnu/lib/libg++/include/stream.h b/gnu/lib/libg++/include/stream.h
new file mode 100644
index 0000000..488f367
--- /dev/null
+++ b/gnu/lib/libg++/include/stream.h
@@ -0,0 +1,55 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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.
+
+#define _STREAM_COMPAT
+#include <iostream.h>
+
+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); }
+
+#endif /* !_COMPAT_STREAM_H */
diff --git a/gnu/lib/libg++/include/streambuf.h b/gnu/lib/libg++/include/streambuf.h
new file mode 100644
index 0000000..60181a4
--- /dev/null
+++ b/gnu/lib/libg++/include/streambuf.h
@@ -0,0 +1,455 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 */
+
+extern "C" {
+#include <libio.h>
+}
+//#include <_G_config.h>
+#ifdef _IO_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 __GNUC__
+#define NULL ((void*)0)
+#else
+#define NULL (0)
+#endif
+#endif
+
+#ifndef _IO_wchar_t
+#define _IO_wchar_t short
+#endif
+
+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
+
+extern "C" int __underflow(struct _IO_FILE*);
+extern "C" int __overflow(struct _IO_FILE*, int);
+
+typedef _IO_off_t streamoff;
+typedef _IO_fpos_t streampos;
+typedef _IO_ssize_t streamsize;
+
+typedef unsigned long __fmtflags;
+typedef unsigned char __iostate;
+
+struct _ios_fields
+{ // The data members of an ios.
+ // Directly using _strbuf is dangerous, because the vtable
+ // pointer can be NULL. Use rdbuf() when in doubt.
+ 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 {
+ 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 };
+ enum seek_dir { beg, cur, end};
+ // ANSI: typedef enum seek_dir seekdir; etc
+ // 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,
+ dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction
+ };
+ 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 (_IO_wchar_t)_fill; }
+ _IO_wchar_t fill(_IO_wchar_t newf)
+ {_IO_wchar_t oldf = (_IO_wchar_t)_fill; _fill = (char)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
+ streambuf* rdbuf() const { return _strbuf; }
+#ifdef _STREAM_COMPAT
+ void _IO_fix_vtable(); /* TEMPORARY - for binary compatibility */
+ void _IO_fix_vtable() const; /* TEMPORARY - for binary compatibility */
+#endif
+#if 0
+ streambuf* rdbuf(streambuf *_s) {
+ streambuf *_old = _strbuf; _strbuf = _s; return _old; }
+#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(); }
+
+ 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:
+ ios(streambuf* sb = 0, ostream* tie_to = 0) { init(sb, tie_to); }
+ virtual ~ios();
+ 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();
+};
+
+extern unsigned __adjust_column(unsigned start, const char *line, int count);
+
+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 int underflow(); // Leave public for now
+ virtual int overflow(int c = EOF); // Leave public for now
+ virtual int doallocate();
+ streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ streampos sseekpos(streampos pos, int mode = ios::in|ios::out);
+
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ int seekmark(streammarker& mark, int delta = 0);
+ int sputbackc(char c);
+ int sungetc();
+ virtual ~streambuf();
+ 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();
+ virtual int sync();
+ virtual int pbackfail(int c);
+ virtual streambuf* setbuf(char* p, int len);
+ int in_avail() { return _IO_read_end - _IO_read_ptr; }
+ int out_waiting() { return _IO_write_ptr - _IO_write_base; }
+ virtual streamsize xsputn(const char* s, streamsize n);
+ streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); }
+ streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); }
+ virtual streamsize xsgetn(char* s, streamsize n);
+ streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); }
+ int ignore(int);
+ virtual int get_column();
+ virtual 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 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();
+};
+
+// 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);
+ static filebuf *__new();
+ ~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(); }
+ int do_write(const char *data, int to_do);
+ // 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();
+};
+
+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=' ';
+ _flags=ios::skipws|ios::dec; _precision=6; _arrays = 0; }
+
+inline ios::~ios() {
+ if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf(); }
+#endif /* _STREAMBUF_H */
diff --git a/gnu/lib/libg++/include/strfile.h b/gnu/lib/libg++/include/strfile.h
new file mode 100644
index 0000000..bff25b1
--- /dev/null
+++ b/gnu/lib/libg++/include/strfile.h
@@ -0,0 +1,46 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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
+{
+ /* The current length is max(_len, _IO_write_ptr-_IO_write_base). */
+ _IO_size_t _len;
+ _IO_alloc_type _allocate_buffer;
+ _IO_free_type _free_buffer;
+};
+
+typedef struct _IO_strfile_
+{
+ struct _IO_FILE _f;
+ const void *_vtable;
+ struct _IO_str_fields _s;
+} _IO_strfile;
diff --git a/gnu/lib/libg++/include/strstream.h b/gnu/lib/libg++/include/strstream.h
new file mode 100644
index 0000000..3c8fd54
--- /dev/null
+++ b/gnu/lib/libg++/include/strstream.h
@@ -0,0 +1,109 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+class strstreambuf : public streambuf
+{
+ struct _IO_str_fields _s;
+
+ void init_dynamic(_IO_alloc_type alloc, _IO_free_type free,
+ int initial_size = 128);
+ void init_static(char *ptr, int size, char *pstart);
+ void init_readonly(const char *ptr, int size);
+ protected:
+ int is_static() const { return _s._allocate_buffer == (_IO_alloc_type)0; }
+ 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 is_static().
+ int frozen() { return _flags & _IO_USER_BUF ? 1 : 0; }
+ void freeze(int n=1)
+ { if (!is_static())
+ { 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 {
+ public:
+ strstreambuf* rdbuf() { return (strstreambuf*)ios::rdbuf(); }
+ protected:
+ strstreambase() { }
+ 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() : strstreambase() { init(new strstreambuf()); }
+ 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(); }
+};
+
+#endif /*!__STRSTREAM_H*/
diff --git a/gnu/lib/libg++/libg++/ACG.cc b/gnu/lib/libg++/libg++/ACG.cc
new file mode 100644
index 0000000..27e7aa2
--- /dev/null
+++ b/gnu/lib/libg++/libg++/ACG.cc
@@ -0,0 +1,291 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <ACG.h>
+#include <assert.h>
+
+//
+// This is an extension of the older implementation of Algorithm M
+// which I previously supplied. The main difference between this
+// version and the old code are:
+//
+// + Andres searched high & low for good constants for
+// the LCG.
+//
+// + theres more bit chopping going on.
+//
+// The following contains his comments.
+//
+// agn@UNH.CS.CMU.EDU sez..
+//
+// The generator below is based on 2 well known
+// methods: Linear Congruential (LCGs) and Additive
+// Congruential generators (ACGs).
+//
+// The LCG produces the longest possible sequence
+// of 32 bit random numbers, each being unique in
+// that sequence (it has only 32 bits of state).
+// It suffers from 2 problems: a) Independence
+// isnt great, that is the (n+1)th number is
+// somewhat related to the preceding one, unlike
+// flipping a coin where knowing the past outcomes
+// dont help to predict the next result. b)
+// Taking parts of a LCG generated number can be
+// quite non-random: for example, looking at only
+// the least significant byte gives a permuted
+// 8-bit counter (that has a period length of only
+// 256). The advantage of an LCA is that it is
+// perfectly uniform when run for the entire period
+// length (and very uniform for smaller sequences
+// too, if the parameters are chosen carefully).
+//
+// ACGs have extremly long period lengths and
+// provide good independence. Unfortunately,
+// uniformity isnt not too great. Furthermore, I
+// didnt find any theoretically analysis of ACGs
+// that addresses uniformity.
+//
+// The RNG given below will return numbers
+// generated by an LCA that are permuted under
+// control of a ACG. 2 permutations take place: the
+// 4 bytes of one LCG generated number are
+// subjected to one of 16 permutations selected by
+// 4 bits of the ACG. The permutation a such that
+// byte of the result may come from each byte of
+// the LCG number. This effectively destroys the
+// structure within a word. Finally, the sequence
+// of such numbers is permuted within a range of
+// 256 numbers. This greatly improves independence.
+//
+//
+// Algorithm M as describes in Knuths "Art of Computer Programming",
+// Vol 2. 1969
+// is used with a linear congruential generator (to get a good uniform
+// distribution) that is permuted with a Fibonacci additive congruential
+// generator to get good independence.
+//
+// Bit, byte, and word distributions were extensively tested and pass
+// Chi-squared test near perfect scores (>7E8 numbers tested, Uniformity
+// assumption holds with probability > 0.999)
+//
+// Run-up tests for on 7E8 numbers confirm independence with
+// probability > 0.97.
+//
+// Plotting random points in 2d reveals no apparent structure.
+//
+// Autocorrelation on sequences of 5E5 numbers (A(i) = SUM X(n)*X(n-i),
+// i=1..512)
+// results in no obvious structure (A(i) ~ const).
+//
+// Except for speed and memory requirements, this generator outperforms
+// random() for all tests. (random() scored rather low on uniformity tests,
+// while independence test differences were less dramatic).
+//
+// AGN would like to..
+// thanks to M.Mauldin, H.Walker, J.Saxe and M.Molloy for inspiration & help.
+//
+// And I would (DGC) would like to thank Donald Kunth for AGN for letting me
+// use his extensions in this implementation.
+//
+
+//
+// Part of the table on page 28 of Knuth, vol II. This allows us
+// to adjust the size of the table at the expense of shorter sequences.
+//
+
+static randomStateTable[][3] = {
+{3,7,16}, {4,9, 32}, {3,10, 32}, {1,11, 32}, {1,15,64}, {3,17,128},
+{7,18,128}, {3,20,128}, {2,21, 128}, {1,22, 128}, {5,23, 128}, {3,25, 128},
+{2,29, 128}, {3,31, 128}, {13,33, 256}, {2,35, 256}, {11,36, 256},
+{14,39,256}, {3,41,256}, {9,49,256}, {3,52,256}, {24,55,256}, {7,57, 256},
+{19,58,256}, {38,89,512}, {17,95,512}, {6,97,512}, {11,98,512}, {-1,-1,-1} };
+
+//
+// spatial permutation table
+// RANDOM_PERM_SIZE must be a power of two
+//
+
+#define RANDOM_PERM_SIZE 64
+unsigned long randomPermutations[RANDOM_PERM_SIZE] = {
+0xffffffff, 0x00000000, 0x00000000, 0x00000000, // 3210
+0x0000ffff, 0x00ff0000, 0x00000000, 0xff000000, // 2310
+0xff0000ff, 0x0000ff00, 0x00000000, 0x00ff0000, // 3120
+0x00ff00ff, 0x00000000, 0xff00ff00, 0x00000000, // 1230
+
+0xffff0000, 0x000000ff, 0x00000000, 0x0000ff00, // 3201
+0x00000000, 0x00ff00ff, 0x00000000, 0xff00ff00, // 2301
+0xff000000, 0x00000000, 0x000000ff, 0x00ffff00, // 3102
+0x00000000, 0x00000000, 0x00000000, 0xffffffff, // 2103
+
+0xff00ff00, 0x00000000, 0x00ff00ff, 0x00000000, // 3012
+0x0000ff00, 0x00000000, 0x00ff0000, 0xff0000ff, // 2013
+0x00000000, 0x00000000, 0xffffffff, 0x00000000, // 1032
+0x00000000, 0x0000ff00, 0xffff0000, 0x000000ff, // 1023
+
+0x00000000, 0xffffffff, 0x00000000, 0x00000000, // 0321
+0x00ffff00, 0xff000000, 0x00000000, 0x000000ff, // 0213
+0x00000000, 0xff000000, 0x0000ffff, 0x00ff0000, // 0132
+0x00000000, 0xff00ff00, 0x00000000, 0x00ff00ff // 0123
+};
+
+//
+// SEED_TABLE_SIZE must be a power of 2
+//
+#define SEED_TABLE_SIZE 32
+static unsigned long seedTable[SEED_TABLE_SIZE] = {
+0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
+0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
+0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
+0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
+0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
+0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
+0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
+0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf
+};
+
+//
+// The LCG used to scramble the ACG
+//
+//
+// LC-parameter selection follows recommendations in
+// "Handbook of Mathematical Functions" by Abramowitz & Stegun 10th, edi.
+//
+// LC_A = 251^2, ~= sqrt(2^32) = 66049
+// LC_C = result of a long trial & error series = 3907864577
+//
+
+static const unsigned long LC_A = 66049;
+static const unsigned long LC_C = 3907864577;
+static inline unsigned long LCG(unsigned long x)
+{
+ return( x * LC_A + LC_C );
+}
+
+
+ACG::ACG(unsigned long seed, int size)
+{
+
+ initialSeed = seed;
+
+ //
+ // Determine the size of the state table
+ //
+
+ for (register int l = 0;
+ randomStateTable[l][0] != -1 && randomStateTable[l][1] < size;
+ l++);
+
+ if (randomStateTable[l][1] == -1) {
+ l--;
+ }
+
+ initialTableEntry = l;
+
+ stateSize = randomStateTable[ initialTableEntry ][ 1 ];
+ auxSize = randomStateTable[ initialTableEntry ][ 2 ];
+
+ //
+ // Allocate the state table & the auxillary table in a single malloc
+ //
+
+ state = new unsigned long[stateSize + auxSize];
+ auxState = &state[stateSize];
+
+ reset();
+}
+
+//
+// Initialize the state
+//
+void
+ACG::reset()
+{
+ register unsigned long u;
+
+ if (initialSeed < SEED_TABLE_SIZE) {
+ u = seedTable[ initialSeed ];
+ } else {
+ u = initialSeed ^ seedTable[ initialSeed & (SEED_TABLE_SIZE-1) ];
+ }
+
+
+ j = randomStateTable[ initialTableEntry ][ 0 ] - 1;
+ k = randomStateTable[ initialTableEntry ][ 1 ] - 1;
+
+ register int i;
+ for(i = 0; i < stateSize; i++) {
+ state[i] = u = LCG(u);
+ }
+
+ for (i = 0; i < auxSize; i++) {
+ auxState[i] = u = LCG(u);
+ }
+
+ k = u % stateSize;
+ int tailBehind = (stateSize - randomStateTable[ initialTableEntry ][ 0 ]);
+ j = k - tailBehind;
+ if (j < 0) {
+ j += stateSize;
+ }
+
+ lcgRecurr = u;
+
+ assert(sizeof(double) == 2 * sizeof(long));
+}
+
+ACG::~ACG()
+{
+ if (state) delete state;
+ state = 0;
+ // don't delete auxState, it's really an alias for state.
+}
+
+//
+// Returns 32 bits of random information.
+//
+
+unsigned long ACG::asLong()
+{
+ unsigned long result = state[k] + state[j];
+ state[k] = result;
+ j = (j <= 0) ? (stateSize-1) : (j-1);
+ k = (k <= 0) ? (stateSize-1) : (k-1);
+
+ short int auxIndex = (result >> 24) & (auxSize - 1);
+ register unsigned long auxACG = auxState[auxIndex];
+ auxState[auxIndex] = lcgRecurr = LCG(lcgRecurr);
+
+ //
+ // 3c is a magic number. We are doing four masks here, so we
+ // do not want to run off the end of the permutation table.
+ // This insures that we have always got four entries left.
+ //
+ register unsigned long *perm = & randomPermutations[result & 0x3c];
+
+ result = *(perm++) & auxACG;
+ result |= *(perm++) & ((auxACG << 24)
+ | ((auxACG >> 8)& 0xffffff));
+ result |= *(perm++) & ((auxACG << 16)
+ | ((auxACG >> 16) & 0xffff));
+ result |= *(perm++) & ((auxACG << 8)
+ | ((auxACG >> 24) & 0xff));
+
+ return(result);
+}
diff --git a/gnu/lib/libg++/libg++/AllocRing.cc b/gnu/lib/libg++/libg++/AllocRing.cc
new file mode 100644
index 0000000..5be1ff0
--- /dev/null
+++ b/gnu/lib/libg++/libg++/AllocRing.cc
@@ -0,0 +1,110 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <AllocRing.h>
+#include <new.h>
+
+AllocRing::AllocRing(int max)
+ :n(max), current(0), nodes(new AllocQNode[max])
+{
+ for (int i = 0; i < n; ++i)
+ {
+ nodes[i].ptr = 0;
+ nodes[i].sz = 0;
+ }
+}
+
+int AllocRing::find(void* p)
+{
+ if (p == 0) return -1;
+
+ for (int i = 0; i < n; ++i)
+ if (nodes[i].ptr == p)
+ return i;
+
+ return -1;
+}
+
+
+void AllocRing::clear()
+{
+ for (int i = 0; i < n; ++i)
+ {
+ if (nodes[i].ptr != 0)
+ {
+ delete(nodes[i].ptr);
+ nodes[i].ptr = 0;
+ }
+ nodes[i].sz = 0;
+ }
+ current = 0;
+}
+
+
+void AllocRing::free(void* p)
+{
+ int idx = find(p);
+ if (idx >= 0)
+ {
+ delete nodes[idx].ptr;
+ nodes[idx].ptr = 0;
+ }
+}
+
+AllocRing::~AllocRing()
+{
+ clear();
+}
+
+int AllocRing::contains(void* p)
+{
+ return find(p) >= 0;
+}
+
+static inline unsigned int good_size(unsigned int s)
+{
+ unsigned int req = s + 4;
+ unsigned int good = 8;
+ while (good < req) good <<= 1;
+ return good - 4;
+}
+
+void* AllocRing::alloc(int s)
+{
+ unsigned int size = good_size(s);
+
+ void* p;
+ if (nodes[current].ptr != 0 &&
+ nodes[current].sz >= int(size) &&
+ nodes[current].sz < int(4 * size))
+ p = nodes[current].ptr;
+ else
+ {
+ if (nodes[current].ptr != 0) delete nodes[current].ptr;
+ p = new char[size];
+ nodes[current].ptr = p;
+ nodes[current].sz = size;
+ }
+ ++current;
+ if (current >= n) current = 0;
+ return p;
+}
diff --git a/gnu/lib/libg++/libg++/Binomial.cc b/gnu/lib/libg++/libg++/Binomial.cc
new file mode 100644
index 0000000..7166e55
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Binomial.cc
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Binomial.h>
+
+double Binomial::operator()()
+{
+ int s = 0;
+ for (int i = 0; i < pN; i++) {
+ if (pGenerator -> asDouble() < pU) {
+ s++;
+ }
+ }
+ return(double(s));
+}
+
diff --git a/gnu/lib/libg++/libg++/BitSet.cc b/gnu/lib/libg++/libg++/BitSet.cc
new file mode 100644
index 0000000..397c750
--- /dev/null
+++ b/gnu/lib/libg++/libg++/BitSet.cc
@@ -0,0 +1,1006 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ BitSet class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <BitSet.h>
+#include <std.h>
+#include <limits.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <new.h>
+#include <builtin.h>
+#include <string.h>
+#include <strstream.h>
+
+void BitSet::error(const char* msg) const
+{
+ (*lib_error_handler)("BitSet", msg);
+}
+
+// globals & constants
+
+BitSetRep _nilBitSetRep = { 0, 1, 0, {0} }; // nil BitSets point here
+
+#define ONES ((unsigned short)(~0L))
+#define MAXBitSetRep_SIZE ((1 << (sizeof(short)*CHAR_BIT - 1)) - 1)
+#define MINBitSetRep_SIZE 16
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
+
+// break things up into .s indices and positions
+
+
+// mask out bits from left
+
+static inline unsigned short lmask(int p)
+{
+ return ONES << p;
+}
+
+// mask out high bits
+
+static inline unsigned short rmask(int p)
+{
+ return ONES >> (BITSETBITS - 1 - p);
+}
+
+
+inline static BitSetRep* BSnew(int newlen)
+{
+ unsigned int siz = sizeof(BitSetRep) + newlen * sizeof(short)
+ + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINBitSetRep_SIZE;;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXBitSetRep_SIZE * sizeof(short))
+ (*lib_error_handler)("BitSet", "Requested length out of range");
+
+ BitSetRep* rep = (BitSetRep *) new char[allocsiz];
+ memset(rep, 0, allocsiz);
+ rep->sz = (allocsiz - sizeof(BitSetRep) + sizeof(short)) / sizeof(short);
+ return rep;
+}
+
+BitSetRep* BitSetalloc(BitSetRep* old, const unsigned short* src, int srclen,
+ int newvirt, int newlen)
+{
+ if (old == &_nilBitSetRep) old = 0;
+ BitSetRep* rep;
+ if (old == 0 || newlen >= old->sz)
+ rep = BSnew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->virt = newvirt;
+
+ if (srclen != 0 && src != rep->s)
+ memcpy(rep->s, src, srclen * sizeof(short));
+ // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
+ if (rep->virt)
+ memset(&rep->s[srclen], ONES, (newlen - srclen) * sizeof(short));
+ if (old != rep && old != 0) delete old;
+ return rep;
+}
+
+BitSetRep* BitSetresize(BitSetRep* old, int newlen)
+{
+ BitSetRep* rep;
+ if (old == 0 || old == &_nilBitSetRep)
+ {
+ rep = BSnew(newlen);
+ rep->virt = 0;
+ }
+ else if (newlen >= old->sz)
+ {
+ rep = BSnew(newlen);
+ memcpy(rep->s, old->s, old->len * sizeof(short));
+ rep->virt = old->virt;
+ // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
+ if (rep->virt)
+ memset(&rep->s[old->len], ONES, (newlen - old->len) * sizeof(short));
+ delete old;
+ }
+ else
+ {
+ rep = old;
+ if (rep->len < newlen)
+ memset(&rep->s[rep->len],
+ rep->virt ? ONES : 0,
+ (newlen - rep->len) * sizeof(short));
+ }
+
+ rep->len = newlen;
+
+ return rep;
+}
+
+// same, for straight copy
+
+BitSetRep* BitSetcopy(BitSetRep* old, const BitSetRep* src)
+{
+ BitSetRep* rep;
+ if (old == &_nilBitSetRep) old = 0;
+ if (src == 0 || src == &_nilBitSetRep)
+ {
+ if (old == 0)
+ rep = BSnew(0);
+ else
+ rep = old;
+ rep->len = 0;
+ rep->virt = 0;
+ }
+ else if (old == src)
+ return old;
+ else
+ {
+ int newlen = src->len;
+ if (old == 0 || newlen > old->sz)
+ {
+ rep = BSnew(newlen);
+ if (old != 0) delete old;
+ }
+ else
+ rep = old;
+
+ memcpy(rep->s, src->s, newlen * sizeof(short));
+ rep->len = newlen;
+ rep->virt = src->virt;
+ }
+ return rep;
+}
+
+
+// remove unneeded top bits
+
+inline static void trim(BitSetRep* rep)
+{
+ int l = rep->len;
+ unsigned short* s = &(rep->s[l - 1]);
+
+ if (rep->virt == 0)
+ while (l > 0 && *s-- == 0) --l;
+ else
+ while (l > 0 && *s-- == ONES) --l;
+ rep->len = l;
+}
+
+int operator == (const BitSet& x, const BitSet& y)
+{
+ if (x.rep->virt != y.rep->virt)
+ return 0;
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ unsigned short* xs = x.rep->s;
+ unsigned short* ys = y.rep->s;
+ if (xl<=yl)
+ {
+ if (memcmp((void*)xs, (void*)ys, xl * sizeof(short)))
+ return 0;
+ for (register int i=xl; i<yl; i++)
+ if (ys[i])
+ return 0;
+ return 1;
+ }
+ else
+ {
+ if (memcmp((void*)xs, (void*)ys, yl * sizeof(short)))
+ return 0;
+ for (register int i=yl; i<xl; i++)
+ if (xs[i])
+ return 0;
+ return 1;
+ }
+}
+
+int operator <= (const BitSet& x, const BitSet& y)
+{
+ if (x.rep->virt > y.rep->virt)
+ return 0;
+
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ unsigned short* xs = x.rep->s;
+ unsigned short* ys = y.rep->s;
+ unsigned short* topx = &(xs[xl]);
+ unsigned short* topy = &(ys[yl]);
+
+ while (xs < topx && ys < topy)
+ {
+ unsigned short a = *xs++;
+ unsigned short b = *ys++;
+ if ((a | b) != b)
+ return 0;
+ }
+ if (xl == yl)
+ return x.rep->virt <= y.rep->virt;
+ else if (xl < yl)
+ return !x.rep->virt;
+ else
+ return y.rep->virt;
+}
+
+
+int operator < (const BitSet& x, const BitSet& y)
+{
+ if (x.rep->virt > y.rep->virt)
+ return 0;
+
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ unsigned short* xs = x.rep->s;
+ unsigned short* ys = y.rep->s;
+ unsigned short* topx = &(xs[xl]);
+ unsigned short* topy = &(ys[yl]);
+ int one_diff = 0;
+ while (xs < topx && ys < topy)
+ {
+ unsigned short a = *xs++;
+ unsigned short b = *ys++;
+ unsigned short c = a | b;
+ if (c != b)
+ return 0;
+ else if (c != a)
+ one_diff = 1;
+ }
+ if (xl == yl)
+ return x.rep->virt < y.rep->virt ||
+ (one_diff && x.rep->virt == y.rep->virt);
+ else if (xl < yl)
+ return !x.rep->virt;
+ else
+ return y.rep->virt;
+}
+
+
+
+int BitSet::empty() const
+{
+ if (rep->virt == 1)
+ return 0;
+
+ unsigned short* bots = rep->s;
+ unsigned short* s = &(bots[rep->len - 1]);
+ while (s >= bots) if (*s-- != 0) return 0;
+ return 1;
+}
+
+
+int BitSet::count(int b) const
+{
+ if (b == rep->virt)
+ return -1;
+ int l = 0;
+ unsigned short* s = rep->s;
+ unsigned short* tops = &(s[rep->len]);
+ if (b == 1)
+ {
+ while (s < tops)
+ {
+ unsigned short a = *s++;
+ for (int i = 0; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ ++l;
+ a >>= 1;
+ }
+ }
+ }
+ else
+ {
+ unsigned short maxbit = 1 << (BITSETBITS - 1);
+ while (s < tops)
+ {
+ unsigned short a = *s++;
+ for (int i = 0; i < BITSETBITS; ++i)
+ {
+ if ((a & maxbit) == 0)
+ ++l;
+ a <<= 1;
+ }
+ }
+ }
+ return l;
+}
+
+BitSetRep* BitSetcmpl(const BitSetRep* src, BitSetRep* r)
+{
+ r = BitSetcopy(r, src);
+ r->virt = !src->virt;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[r->len]);
+ if (r->len == 0)
+ *rs = ONES;
+ else
+ {
+ while (rs < topr)
+ {
+ unsigned short cmp = ~(*rs);
+ *rs++ = cmp;
+ }
+ }
+ trim(r);
+ return r;
+}
+
+
+BitSetRep* BitSetop(const BitSetRep* x, const BitSetRep* y,
+ BitSetRep* r, char op)
+{
+ int xrsame = x == r;
+ int yrsame = y == r;
+ int xv = x->virt;
+ int yv = y->virt;
+ int xl = x->len;
+ int yl = y->len;
+ int rl = (xl >= yl)? xl : yl;
+
+ r = BitSetresize(r, rl);
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+
+ int av, bv;
+ const unsigned short* as;
+ const unsigned short* topa;
+ const unsigned short* bs;
+ const unsigned short* topb;
+
+ if (xl <= yl)
+ {
+ as = (xrsame)? r->s : x->s;
+ av = xv;
+ topa = &(as[xl]);
+ bs = (yrsame)? r->s : y->s;
+ bv = yv;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ as = (yrsame)? r->s : y->s;
+ av = yv;
+ topa = &(as[yl]);
+ bs = (xrsame)? r->s : x->s;
+ bv = xv;
+ topb = &(bs[xl]);
+ if (op == '-') // reverse sense of difference
+ op = 'D';
+ }
+
+ switch (op)
+ {
+ case '&':
+ r->virt = av & bv;
+ while (as < topa) *rs++ = *as++ & *bs++;
+ if (av)
+ while (rs < topr) *rs++ = *bs++;
+ else
+ while (rs < topr) *rs++ = 0;
+ break;
+ case '|':
+ r->virt = av | bv;
+ while (as < topa) *rs++ = *as++ | *bs++;
+ if (av)
+ while (rs < topr) *rs++ = ONES;
+ else
+ while (rs < topr) *rs++ = *bs++;
+ break;
+ case '^':
+ r->virt = av ^ bv;
+ while (as < topa) *rs++ = *as++ ^ *bs++;
+ if (av)
+ while (rs < topr) *rs++ = ~(*bs++);
+ else
+ while (rs < topr) *rs++ = *bs++;
+ break;
+ case '-':
+ r->virt = av & ~(bv);
+ while (as < topa) *rs++ = *as++ & ~(*bs++);
+ if (av)
+ while (rs < topr) *rs++ = ~(*bs++);
+ else
+ while (rs < topr) *rs++ = 0;
+ break;
+ case 'D':
+ r->virt = ~(av) & (bv);
+ while (as < topa) *rs++ = ~(*as++) & (*bs++);
+ if (av)
+ while (rs < topr) *rs++ = 0;
+ else
+ while (rs < topr) *rs++ = *bs++;
+ break;
+ }
+ trim(r);
+ return r;
+}
+
+
+void BitSet::set(int p)
+{
+ if (p < 0) error("Illegal bit index");
+
+ int index = BitSet_index(p);
+ int pos = BitSet_pos(p);
+
+ if (index >= rep->len)
+ {
+ if (rep->virt)
+ return;
+ else
+ rep = BitSetresize(rep, index+1);
+ }
+
+ rep->s[index] |= (1 << pos);
+}
+
+void BitSet::clear()
+{
+ if (rep->len > 0) memset(rep->s, 0, rep->sz * sizeof(short));
+ rep->len = rep->virt = 0;
+}
+
+void BitSet::clear(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ int index = BitSet_index(p);
+ if (index >= rep->len)
+ {
+ if (rep->virt == 0)
+ return;
+ else
+ rep = BitSetresize(rep, index+1);
+ }
+ rep->s[index] &= ~(1 << BitSet_pos(p));
+}
+
+void BitSet::invert(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ int index = BitSet_index(p);
+ if (index >= rep->len) rep = BitSetresize(rep, index+1);
+ rep->s[index] ^= (1 << BitSet_pos(p));
+}
+
+void BitSet::set(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+
+ if (rep->virt && index1 >= rep->len)
+ return;
+
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ rep = BitSetresize(rep, index2+1);
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (index2 == index1)
+ *s |= m1 & m2;
+ else
+ {
+ *s++ |= m1;
+ unsigned short* top = &(rep->s[index2]);
+ *top |= m2;
+ while (s < top)
+ *s++ = ONES;
+ }
+}
+
+void BitSet::clear(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+
+ if (!rep->virt && index1 >= rep->len)
+ return;
+
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ rep = BitSetresize(rep, index2+1);
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (index2 == index1)
+ *s &= ~(m1 & m2);
+ else
+ {
+ *s++ &= ~m1;
+ unsigned short* top = &(rep->s[index2]);
+ *top &= ~m2;
+ while (s < top)
+ *s++ = 0;
+ }
+}
+
+void BitSet::invert(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ rep = BitSetresize(rep, index2+1);
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (index2 == index1)
+ *s ^= m1 & m2;
+ else
+ {
+ *s++ ^= m1;
+ unsigned short* top = &(rep->s[index2]);
+ *top ^= m2;
+ while (s < top)
+ {
+ unsigned short cmp = ~(*s);
+ *s++ = cmp;
+ }
+ }
+}
+
+
+int BitSet::test(int from, int to) const
+{
+ if (from < 0 || from > to) return 0;
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+
+ if (index1 >= rep->len)
+ return rep->virt;
+
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ {
+ if (rep->virt)
+ return 1;
+ else
+ {
+ index2 = rep->len - 1;
+ pos2 = BITSETBITS - 1;
+ }
+ }
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+
+ if (index2 == index1)
+ return (*s & m1 & m2) != 0;
+ else
+ {
+ if (*s++ & m1)
+ return 1;
+ unsigned short* top = &(rep->s[index2]);
+ if (*top & m2)
+ return 1;
+ while (s < top)
+ if (*s++ != 0)
+ return 1;
+ return 0;
+ }
+}
+
+int BitSet::next(int p, int b) const
+{
+ ++p;
+ int index = BitSet_index(p);
+ int pos = BitSet_pos(p);
+
+ int l = rep->len;
+
+ if (index >= l)
+ {
+ if (rep->virt == b)
+ return p;
+ else
+ return -1;
+ }
+ int j = index;
+ unsigned short* s = rep->s;
+ unsigned short a = s[j] >> pos;
+ int i = pos;
+
+ if (b == 1)
+ {
+ for (; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ for (++j; j < l; ++j)
+ {
+ a = s[j];
+ for (i = 0; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ }
+ if (rep->virt)
+ return j * BITSETBITS;
+ else
+ return -1;
+ }
+ else
+ {
+ for (; i < BITSETBITS; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ for (++j; j < l; ++j)
+ {
+ a = s[j];
+ if (a != ONES)
+ {
+ for (i = 0; i < BITSETBITS; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ }
+ }
+ if (!rep->virt)
+ return j * BITSETBITS;
+ else
+ return -1;
+ }
+}
+
+int BitSet::prev(int p, int b) const
+{
+ if (--p < 0)
+ return -1;
+
+ int index = BitSet_index(p);
+ int pos = BitSet_pos(p);
+
+ unsigned short* s = rep->s;
+ int l = rep->len;
+
+ if (index >= l)
+ {
+ if (rep->virt == b)
+ return p;
+ else
+ {
+ index = l - 1;
+ pos = BITSETBITS - 1;
+ }
+ }
+
+ int j = index;
+ unsigned short a = s[j];
+
+ int i = pos;
+ unsigned short maxbit = 1 << pos;
+
+ if (b == 1)
+ {
+ for (; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ maxbit = 1 << (BITSETBITS - 1);
+ for (--j; j >= 0; --j)
+ {
+ a = s[j];
+ for (i = BITSETBITS - 1; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ }
+ return -1;
+ }
+ else
+ {
+ if (a != ONES)
+ {
+ for (; i >= 0; --i)
+ {
+ if ((a & maxbit) == 0)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ }
+ maxbit = 1 << (BITSETBITS - 1);
+ for (--j; j >= 0; --j)
+ {
+ a = s[j];
+ if (a != ONES)
+ {
+ for (i = BITSETBITS - 1; i >= 0; --i)
+ {
+ if ((a & maxbit) == 0)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ }
+ }
+ return -1;
+ }
+}
+
+int BitSet::last(int b) const
+{
+ if (b == rep->virt)
+ return -1;
+ else
+ return prev((rep->len) * BITSETBITS, b);
+}
+
+
+extern AllocRing _libgxx_fmtq;
+
+const char* BitSettoa(const BitSet& x, char f, char t, char star)
+{
+ trim(x.rep);
+ int wrksiz = (x.rep->len + 1) * BITSETBITS + 2;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ ostrstream stream(fmtbase, wrksiz);
+
+ x.printon(stream, f, t, star);
+ stream << ends;
+ return fmtbase;
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+BitSet shorttoBitSet(unsigned short w) return r
+{
+ r.rep = BitSetalloc(0, &w, 1, 0, 2); trim(r.rep);
+}
+
+BitSet longtoBitSet(unsigned long w) return r;
+{
+ unsigned short u[2];
+ u[0] = w & ((unsigned short)(~(0)));
+ u[1] = w >> BITSETBITS;
+ r.rep = BitSetalloc(0, &u[0], 2, 0, 3);
+ trim(r.rep);
+}
+
+BitSet atoBitSet(const char* s, char f, char t, char star) return r
+{
+ int sl = strlen(s);
+ if (sl != 0)
+ {
+ r.rep = BitSetresize(r.rep, sl / BITSETBITS + 1);
+ unsigned short* rs = r.rep->s;
+ unsigned short a = 0;
+ unsigned short m = 1;
+ char lastch = 0;
+ unsigned int i = 0;
+ unsigned int l = 1;
+ for(;;)
+ {
+ char ch = s[i];
+ if (ch == t)
+ a |= m;
+ else if (ch == star)
+ {
+ if (r.rep->virt = lastch == t)
+ *rs = a | ~(m - 1);
+ else
+ *rs = a;
+ break;
+ }
+ else if (ch != f)
+ {
+ *rs = a;
+ break;
+ }
+ lastch = ch;
+ if (++i == sl)
+ {
+ *rs = a;
+ break;
+ }
+ else if (i % BITSETBITS == 0)
+ {
+ *rs++ = a;
+ a = 0;
+ m = 1;
+ ++l;
+ }
+ else
+ m <<= 1;
+ }
+ r.rep->len = l;
+ trim(r.rep);
+ }
+ return;
+}
+
+#else
+
+BitSet shorttoBitSet(unsigned short w)
+{
+ BitSet r;
+ r.rep = BitSetalloc(0, &w, 1, 0, 2); trim(r.rep);
+ return r;
+}
+
+BitSet longtoBitSet(unsigned long w)
+{
+ BitSet r;
+ unsigned short u[2];
+ u[0] = w & ((unsigned short)(~(0)));
+ u[1] = w >> BITSETBITS;
+ r.rep = BitSetalloc(0, &u[0], 2, 0, 3);
+ trim(r.rep);
+ return r;
+}
+
+BitSet atoBitSet(const char* s, char f, char t, char star)
+{
+ BitSet r;
+ int sl = strlen(s);
+ if (sl != 0)
+ {
+ r.rep = BitSetresize(r.rep, sl / BITSETBITS + 1);
+ unsigned short* rs = r.rep->s;
+ unsigned short a = 0;
+ unsigned short m = 1;
+ char lastch = 0;
+ unsigned int i = 0;
+ unsigned int l = 1;
+ for(;;)
+ {
+ char ch = s[i];
+ if (ch == t)
+ a |= m;
+ else if (ch == star)
+ {
+ if (r.rep->virt = lastch == t)
+ *rs = a | ~(m - 1);
+ else
+ *rs = a;
+ break;
+ }
+ else if (ch != f)
+ {
+ *rs = a;
+ break;
+ }
+ lastch = ch;
+ if (++i == sl)
+ {
+ *rs = a;
+ break;
+ }
+ else if (i % BITSETBITS == 0)
+ {
+ *rs++ = a;
+ a = 0;
+ m = 1;
+ ++l;
+ }
+ else
+ m <<= 1;
+ }
+ r.rep->len = l;
+ trim(r.rep);
+ }
+ return r;
+}
+
+#endif
+
+ostream& operator << (ostream& s, const BitSet& x)
+{
+ if (s.opfx())
+ x.printon(s);
+ return s;
+}
+
+void BitSet::printon(ostream& os, char f, char t, char star) const
+// FIXME: Does not respect s.width()!
+{
+ trim(rep);
+ register streambuf* sb = os.rdbuf();
+ const unsigned short* s = rep->s;
+ const unsigned short* top = &(s[rep->len - 1]);
+
+ while (s < top)
+ {
+ unsigned short a = *s++;
+ for (int j = 0; j < BITSETBITS; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a >>= 1;
+ }
+ }
+
+ if (!rep->virt)
+ {
+ unsigned short a = *s;
+ if (rep->len != 0)
+ {
+ for (int j = 0; j < BITSETBITS && a != 0; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a >>= 1;
+ }
+ }
+ sb->sputc(f);
+ }
+ else
+ {
+ unsigned short a = *s;
+ unsigned short mask = ONES;
+ unsigned short himask = (1 << (BITSETBITS - 1)) - 1;
+ if (rep->len != 0)
+ {
+ for (int j = 0; j < BITSETBITS && a != mask; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a = (a >> 1) & himask;
+ mask = (mask >> 1) & himask;
+ }
+ }
+ sb->sputc(t);
+ }
+
+ sb->sputc(star);
+}
+
+int BitSet::OK() const
+{
+ int v = rep != 0; // have a rep
+ v &= rep->len <= rep->sz; // within bounds
+ v &= rep->virt == 0 || rep->virt == 1; // valid virtual bit
+ if (!v) error("invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/libg++/BitString.cc b/gnu/lib/libg++/libg++/BitString.cc
new file mode 100644
index 0000000..26331ae
--- /dev/null
+++ b/gnu/lib/libg++/libg++/BitString.cc
@@ -0,0 +1,1606 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ BitString class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <BitString.h>
+#include <std.h>
+#include <limits.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <new.h>
+#include <builtin.h>
+#include <strstream.h>
+
+void BitString::error(const char* msg) const
+{
+ (*lib_error_handler)("BitString", msg);
+}
+
+// globals
+
+BitStrRep _nilBitStrRep = { 0, 1, {0} };
+
+BitString _nil_BitString;
+
+#define MINBitStrRep_SIZE 8
+#define MAXBitStrRep_SIZE ((1 << (sizeof(short)*CHAR_BIT - 1)) - 1)
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
+
+#define ONES ((_BS_word)(~0L))
+#define MAXBIT (((_BS_word)1) << (BITSTRBITS - 1))
+
+/*
+ * bit manipulation utilities
+*/
+
+// break things up into .s indices and positions
+
+inline static int BitStr_len(int l)
+{
+ return (unsigned)(l) / BITSTRBITS + 1;
+}
+
+
+// mask out low bits
+
+static inline _BS_word lmask(int p)
+{
+ return ONES _BS_RIGHT p;
+}
+
+// mask out high bits
+
+static inline _BS_word rmask(int p)
+{
+ int s = BITSTRBITS - 1 - p;
+ if (s <= 0)
+ return ONES;
+ else
+ return ONES _BS_LEFT s;
+}
+
+
+// mask out unused bits in last word of rep
+
+inline static void check_last(BitStrRep* r)
+{
+ int bit_len_mod = r->len & (BITSTRBITS - 1);
+ if (bit_len_mod)
+ r->s[r->len / BITSTRBITS] &= ONES _BS_LEFT (BITSTRBITS - bit_len_mod);
+}
+
+// merge bits from next word
+
+static inline _BS_word borrow_hi(const _BS_word a[], int ind,
+ int maxind, int p)
+{
+ if (p == 0)
+ return a[ind];
+ else if (ind < maxind)
+ return (a[ind] _BS_LEFT p) | (a[ind+1] _BS_RIGHT (BITSTRBITS - p));
+ else
+ return (a[ind] _BS_LEFT p);
+}
+
+// merge bits from prev word
+
+static inline _BS_word borrow_lo(const _BS_word a[], int ind,
+ int minind, int p)
+{
+ _BS_word word = a[ind] _BS_RIGHT (BITSTRBITS - 1 - p);
+ if (ind > minind)
+ word |= (a[ind-1] _BS_LEFT (p + 1));
+ return word;
+}
+
+// same with bounds check (for masks shorter than patterns)
+
+static inline _BS_word safe_borrow_hi(const _BS_word a[], int ind,
+ int maxind, int p)
+{
+ if (ind > maxind)
+ return 0;
+ else if (p == 0)
+ return a[ind];
+ else if (ind == maxind)
+ return a[ind] _BS_LEFT p;
+ else
+ return (a[ind] _BS_LEFT p) | (a[ind+1] _BS_RIGHT (BITSTRBITS - p));
+}
+
+
+// allocate a new rep; pad to near a power of two
+
+inline static BitStrRep* BSnew(int newlen)
+{
+ unsigned int siz = sizeof(BitStrRep) + BitStr_len(newlen) * sizeof(_BS_word)
+ + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINBitStrRep_SIZE;;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXBitStrRep_SIZE * sizeof(_BS_word))
+ (*lib_error_handler)("BitString", "Requested length out of range");
+
+ BitStrRep* rep = (BitStrRep *) new char[allocsiz];
+ memset(rep, 0, allocsiz);
+ rep->sz =
+ (allocsiz - sizeof(BitStrRep) + sizeof(_BS_word)) / sizeof(_BS_word);
+ return rep;
+}
+
+inline void
+copy_bits (_BS_word* pdst, _BS_size_t dstbit,
+ const _BS_word* psrc, _BS_size_t srcbit,
+ _BS_size_t length)
+{
+ _BS_NORMALIZE (pdst, dstbit);
+ _BS_NORMALIZE (psrc, srcbit);
+ _BS_copy (pdst, dstbit, psrc, srcbit, length);
+}
+
+BitStrRep* BStr_alloc(BitStrRep* old, const _BS_word* src,
+ int startpos, int endp, int newlen)
+{
+ if (old == &_nilBitStrRep) old = 0;
+ if (newlen < 0) newlen = 0;
+ int news = BitStr_len(newlen);
+ BitStrRep* rep;
+ if (old == 0 || news > old->sz)
+ rep = BSnew(newlen);
+ else
+ rep = old;
+ rep->len = newlen;
+
+ if (src != 0 && endp > 0 && (src != rep->s || startpos > 0))
+ copy_bits (rep->s, 0, src, startpos, endp - startpos);
+
+ check_last(rep);
+
+ if (old != rep && old != 0) delete old;
+
+ return rep;
+}
+
+BitStrRep* BStr_resize(BitStrRep* old, int newlen)
+{
+ BitStrRep* rep;
+ if (newlen < 0) newlen = 0;
+ int news = BitStr_len(newlen);
+ if (old == 0 || old == &_nilBitStrRep)
+ {
+ rep = BSnew(newlen);
+ }
+ else if (news > old->sz)
+ {
+ rep = BSnew(newlen);
+ memcpy(rep->s, old->s, BitStr_len(old->len) * sizeof(_BS_word));
+ delete old;
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+ check_last(rep);
+ return rep;
+}
+
+BitStrRep* BStr_copy(BitStrRep* old, const BitStrRep* src)
+{
+ BitStrRep* rep;
+ if (old == src && old != &_nilBitStrRep) return old;
+ if (old == &_nilBitStrRep) old = 0;
+ if (src == &_nilBitStrRep) src = 0;
+ if (src == 0)
+ {
+ if (old == 0)
+ rep = BSnew(0);
+ else
+ rep = old;
+ rep->len = 0;
+ }
+ else
+ {
+ int newlen = src->len;
+ int news = BitStr_len(newlen);
+ if (old == 0 || news > old->sz)
+ {
+ rep = BSnew(newlen);
+ if (old != 0) delete old;
+ }
+ else
+ rep = old;
+
+ memcpy(rep->s, src->s, news * sizeof(_BS_word));
+ rep->len = newlen;
+ }
+ check_last(rep);
+ return rep;
+}
+
+
+int operator == (const BitString& x, const BitString& y)
+{
+ return x.rep->len == y.rep->len &&
+ memcmp((void*)x.rep->s, (void*)y.rep->s,
+ BitStr_len(x.rep->len) * sizeof(_BS_word)) == 0;
+}
+
+int operator <= (const BitString& x, const BitString& y)
+{
+ unsigned int xl = x.rep->len;
+ unsigned int yl = y.rep->len;
+ if (xl > yl)
+ return 0;
+
+ const _BS_word* xs = x.rep->s;
+ const _BS_word* topx = &(xs[BitStr_len(xl)]);
+ const _BS_word* ys = y.rep->s;
+
+ while (xs < topx)
+ {
+ _BS_word a = *xs++;
+ _BS_word b = *ys++;
+ if ((a | b) != b)
+ return 0;
+ }
+ return 1;
+}
+
+int operator < (const BitString& x, const BitString& y)
+{
+ unsigned short xl = x.rep->len;
+ unsigned short yl = y.rep->len;
+ if (xl > yl)
+ return 0;
+
+ const _BS_word* xs = x.rep->s;
+ const _BS_word* ys = y.rep->s;
+ const _BS_word* topx = &(xs[BitStr_len(xl)]);
+ const _BS_word* topy = &(ys[BitStr_len(yl)]);
+ int one_diff = 0;
+ while (xs < topx)
+ {
+ _BS_word a = *xs++;
+ _BS_word b = *ys++;
+ _BS_word c = a | b;
+ if (c != b)
+ return 0;
+ else if (c != a)
+ one_diff = 1;
+ }
+ if (one_diff)
+ return 1;
+ else
+ {
+ while (ys < topy)
+ if (*ys++ != 0)
+ return 1;
+ return 0;
+ }
+}
+
+int lcompare(const BitString& x, const BitString& y)
+{
+ return _BS_lcompare_0 (x.rep->s, x.rep->len, y.rep->s, y.rep->len);
+}
+
+int BitString::count(unsigned int b) const
+{
+ int count = _BS_count (rep->s, 0, rep->len);
+ if (!b)
+ count = rep->len - count;
+ return count;
+}
+
+
+BitStrRep* cmpl(const BitStrRep* src, BitStrRep* r)
+{
+ r = BStr_copy(r, src);
+ _BS_word* rs = r->s;
+ _BS_word* topr = &(rs[BitStr_len(r->len)]);
+ while (rs < topr)
+ {
+ _BS_word cmp = ~(*rs);
+ *rs++ = cmp;
+ }
+ check_last(r);
+ return r;
+}
+
+
+BitStrRep* and(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
+{
+ int xrsame = x == r;
+ int yrsame = y == r;
+
+ unsigned int xl = x->len;
+ unsigned int yl = y->len;
+ unsigned int rl = (xl <= yl)? xl : yl;
+
+ r = BStr_resize(r, rl);
+
+ _BS_word* rs = r->s;
+ _BS_word* topr = &(rs[BitStr_len(rl)]);
+ const _BS_word* xs = (xrsame)? rs : x->s;
+ const _BS_word* ys = (yrsame)? rs : y->s;
+
+ while (rs < topr) *rs++ = *xs++ & *ys++;
+ check_last(r);
+ return r;
+}
+
+BitStrRep* or(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
+{
+ unsigned int xl = x->len;
+ unsigned int yl = y->len;
+ unsigned int rl = (xl >= yl)? xl : yl;
+ int xrsame = x == r;
+ int yrsame = y == r;
+
+ r = BStr_resize(r, rl);
+
+ _BS_word* rs = r->s;
+ const _BS_word* xs = (xrsame)? rs : x->s;
+ const _BS_word* topx = &(xs[BitStr_len(xl)]);
+ const _BS_word* ys = (yrsame)? rs : y->s;
+ const _BS_word* topy = &(ys[BitStr_len(yl)]);
+
+ if (xl <= yl)
+ {
+ while (xs < topx) *rs++ = *xs++ | *ys++;
+ if (rs != ys) while (ys < topy) *rs++ = *ys++;
+ }
+ else
+ {
+ while (ys < topy) *rs++ = *xs++ | *ys++;
+ if (rs != xs) while (xs < topx) *rs++ = *xs++;
+ }
+ check_last(r);
+ return r;
+}
+
+
+BitStrRep* xor(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
+{
+ unsigned int xl = x->len;
+ unsigned int yl = y->len;
+ unsigned int rl = (xl >= yl)? xl : yl;
+ int xrsame = x == r;
+ int yrsame = y == r;
+
+ r = BStr_resize(r, rl);
+
+ _BS_word* rs = r->s;
+ const _BS_word* xs = (xrsame)? rs : x->s;
+ const _BS_word* topx = &(xs[BitStr_len(xl)]);
+ const _BS_word* ys = (yrsame)? rs : y->s;
+ const _BS_word* topy = &(ys[BitStr_len(yl)]);
+
+ if (xl <= yl)
+ {
+ while (xs < topx) *rs++ = *xs++ ^ *ys++;
+ if (rs != ys) while (ys < topy) *rs++ = *ys++;
+ }
+ else
+ {
+ while (ys < topy) *rs++ = *xs++ ^ *ys++;
+ if (rs != xs) while (xs < topx) *rs++ = *xs++;
+ }
+ check_last(r);
+ return r;
+}
+
+
+BitStrRep* diff(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
+{
+ unsigned int xl = x->len;
+ unsigned int yl = y->len;
+ int xrsame = x == y;
+ int yrsame = y == r;
+
+ r = BStr_resize(r, xl);
+
+ _BS_word* rs = r->s;
+ const _BS_word* xs = (xrsame)? rs : x->s;
+ const _BS_word* topx = &(xs[BitStr_len(xl)]);
+ const _BS_word* ys = (yrsame)? rs : y->s;
+ const _BS_word* topy = &(ys[BitStr_len(yl)]);
+
+ if (xl <= yl)
+ {
+ while (xs < topx) *rs++ = *xs++ & ~(*ys++);
+ }
+ else
+ {
+ while (ys < topy) *rs++ = *xs++ & ~(*ys++);
+ if (rs != xs) while (xs < topx) *rs++ = *xs++;
+ }
+ check_last(r);
+ return r;
+}
+
+
+BitStrRep* cat(const BitStrRep* x, const BitStrRep* y, BitStrRep* r)
+{
+ unsigned int xl = x->len;
+ unsigned int yl = y->len;
+ unsigned int rl = xl + yl;
+ int xrsame = x == r;
+ int yrsame = y == r;
+
+ if (yrsame)
+ {
+ if (xrsame)
+ {
+ r = BStr_resize(r, rl);
+ copy_bits (r->s, xl, r->s, 0, yl);
+ }
+ else
+ {
+ BitStrRep* tmp = BStr_copy(0, y);
+ r = BStr_resize(r, rl);
+ _BS_copy_0(r->s, x->s, xl);
+ copy_bits (r->s, xl, tmp->s, 0, yl);
+ delete tmp;
+ }
+ }
+ else
+ {
+ r = BStr_resize(r, rl);
+ if (!xrsame) _BS_copy_0(r->s, x->s, xl);
+ copy_bits (r->s, xl, y->s, 0, yl);
+ }
+ check_last(r);
+ return r;
+}
+
+BitStrRep* cat(const BitStrRep* x, unsigned int bit, BitStrRep* r)
+{
+ unsigned int xl = x->len;
+ int xrsame = x == r;
+ r = BStr_resize(r, xl+1);
+ if (!xrsame)
+ _BS_copy_0(r->s, x->s, xl);
+ if (bit)
+ r->s[BitStr_index(xl)] |= _BS_BITMASK(BitStr_pos(xl));
+ else
+ r->s[BitStr_index(xl)] &= ~(_BS_BITMASK(BitStr_pos(xl)));
+ check_last(r);
+ return r;
+}
+
+BitStrRep* lshift(const BitStrRep* x, int s, BitStrRep* r)
+{
+ int xrsame = x == r;
+ int xl = x->len;
+ int rl = xl + s;
+ if (s == 0)
+ r = BStr_copy(r, x);
+ else if (rl <= 0)
+ {
+ r = BStr_resize(r, 0);
+ r->len = 0;
+ r->s[0] = 0;
+ }
+ else if (s > 0)
+ {
+ r = BStr_resize(r, rl);
+ const _BS_word* xs = (xrsame)? r->s : x->s;
+ copy_bits (r->s, s, xs, 0, xl);
+ _BS_clear (r->s, 0, s);
+ }
+ else if (xrsame)
+ {
+ r = BStr_resize(r, xl);
+ r->len = rl;
+ copy_bits (r->s, 0, r->s, -s, xl + s);
+ }
+ else
+ {
+ r = BStr_resize(r, rl);
+ copy_bits (r->s, 0, x->s, -s, xl + s);
+ }
+ check_last(r);
+ return r;
+}
+
+
+void BitString::set(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ if ((unsigned)(p) >= rep->len) rep = BStr_resize(rep, p + 1);
+ rep->s[BitStr_index(p)] |= _BS_BITMASK(BitStr_pos(p));
+}
+
+void BitString::assign(int p, unsigned int bit)
+{
+ if (p < 0) error("Illegal bit index");
+ if ((unsigned)(p) >= rep->len) rep = BStr_resize(rep, p + 1);
+ if (bit)
+ rep->s[BitStr_index(p)] |= _BS_BITMASK(BitStr_pos(p));
+ else
+ rep->s[BitStr_index(p)] &= ~(_BS_BITMASK(BitStr_pos(p)));
+}
+
+void BitString::clear(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ if ((unsigned)(p) >= rep->len) rep = BStr_resize(rep, p + 1);
+ rep->s[BitStr_index(p)] &= ~(_BS_BITMASK(BitStr_pos(p)));
+}
+
+void BitString::clear()
+{
+ if (rep == &_nilBitStrRep) return;
+ _BS_clear (rep->s, 0, rep->len);
+}
+
+void BitString::set()
+{
+ if (rep == &_nilBitStrRep) return;
+ _BS_word* s = rep->s;
+ _BS_word* tops = &(s[BitStr_len(rep->len)]);
+ while (s < tops) *s++ = ONES;
+ check_last(rep);
+}
+
+void BitString::invert(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ if ((unsigned)(p) >= rep->len) rep = BStr_resize(rep, p + 1);
+ rep->s[BitStr_index(p)] ^= _BS_BITMASK(BitStr_pos(p));
+}
+
+void BitString::set(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+ if ((unsigned)(to) >= rep->len) rep = BStr_resize(rep, to+1);
+
+ _BS_size_t len = to - from + 1;
+ _BS_word* xs = rep->s;
+ _BS_NORMALIZE (xs, from);
+ _BS_invert (xs, from, len);
+}
+
+void BitString::clear(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+ if ((unsigned)(to) >= rep->len) rep = BStr_resize(rep, to+1);
+
+ _BS_size_t len = to - from + 1;
+ _BS_word* xs = rep->s;
+ _BS_NORMALIZE (xs, from);
+ _BS_clear (xs, from, len);
+}
+
+void BitString::invert(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+ if ((unsigned)(to) >= rep->len) rep = BStr_resize(rep, to+1);
+ _BS_size_t len = to - from + 1;
+ _BS_word* xs = rep->s;
+ _BS_NORMALIZE (xs, from);
+ _BS_invert (xs, from, len);
+}
+
+
+int BitString::test(int from, int to) const
+{
+ if (from < 0 || from > to || (unsigned)(from) >= rep->len) return 0;
+
+ _BS_size_t len = to - from + 1;
+ _BS_word* xs = rep->s;
+ _BS_NORMALIZE (xs, from);
+ return _BS_any (xs, from, len);
+}
+
+int BitString::next(int p, unsigned int b) const
+{
+ if ((unsigned)(++p) >= rep->len)
+ return -1;
+
+ int ind = BitStr_index(p);
+ int pos = BitStr_pos(p);
+ int l = BitStr_len(rep->len);
+
+ int j = ind;
+ const _BS_word* s = rep->s;
+ _BS_word a = s[j] >> pos;
+ int i = pos;
+
+ if (b != 0)
+ {
+ for (; i < BITSTRBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ return j * BITSTRBITS + i;
+ a >>= 1;
+ }
+ for (++j; j < l; ++j)
+ {
+ a = s[j];
+ for (i = 0; i < BITSTRBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ return j * BITSTRBITS + i;
+ a >>= 1;
+ }
+ }
+ return -1;
+ }
+ else
+ {
+ int last = BitStr_pos(rep->len);
+ if (j == l - 1)
+ {
+ for (; i < last; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSTRBITS + i;
+ a >>= 1;
+ }
+ return -1;
+ }
+
+ for (; i < BITSTRBITS; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSTRBITS + i;
+ a >>= 1;
+ }
+ for (++j; j < l - 1; ++j)
+ {
+ a = s[j];
+ if (a != ONES)
+ {
+ for (i = 0; i < BITSTRBITS; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSTRBITS + i;
+ a >>= 1;
+ }
+ }
+ }
+ a = s[j];
+ for (i = 0; i < last; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSTRBITS + i;
+ a >>= 1;
+ }
+ return -1;
+ }
+}
+
+int BitString::prev(int p, unsigned int b) const
+{
+ if (--p < 0)
+ return -1;
+
+ int ind = BitStr_index(p);
+ int pos = BitStr_pos(p);
+
+ const _BS_word* s = rep->s;
+
+ if ((unsigned)(p) >= rep->len)
+ {
+ ind = BitStr_index(rep->len - 1);
+ pos = BitStr_pos(rep->len - 1);
+ }
+
+ int j = ind;
+ _BS_word a = s[j];
+
+ int i = pos;
+ _BS_word maxbit = ((_BS_word)1) << pos;
+
+ if (b != 0)
+ {
+ for (; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSTRBITS + i;
+ a <<= 1;
+ }
+ maxbit = ((_BS_word)1) << (BITSTRBITS - 1);
+ for (--j; j >= 0; --j)
+ {
+ a = s[j];
+ for (i = BITSTRBITS - 1; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSTRBITS + i;
+ a <<= 1;
+ }
+ }
+ return -1;
+ }
+ else
+ {
+ if (a != ONES)
+ {
+ for (; i >= 0; --i)
+ {
+ if ((a & maxbit) == 0)
+ return j * BITSTRBITS + i;
+ a <<= 1;
+ }
+ }
+ maxbit = ((_BS_word)1) << (BITSTRBITS - 1);
+ for (--j; j >= 0; --j)
+ {
+ a = s[j];
+ if (a != ONES)
+ {
+ for (i = BITSTRBITS - 1; i >= 0; --i)
+ {
+ if ((a & maxbit) == 0)
+ return j * BITSTRBITS + i;
+ a <<= 1;
+ }
+ }
+ }
+ return -1;
+ }
+}
+
+
+int BitString::search(int startx, int lengthx,
+ const _BS_word* ys, int starty, int lengthy) const
+{
+ const _BS_word* xs = rep->s;
+ int ylen = lengthy - starty;
+ int righty = lengthy - 1;
+ int rev = startx < 0;
+ if (rev)
+ {
+ int leftx = 0;
+ int rightx = lengthx + startx;
+ startx = rightx - ylen + 1;
+ if (ylen == 0) return startx;
+ if (starty < 0 || righty < 0 || startx < 0 || startx >= lengthx) return -1;
+
+ int xind = BitStr_index(startx);
+ int xpos = BitStr_pos(startx);
+ int yind = BitStr_index(starty);
+ int ypos = BitStr_pos(starty);
+
+ int rightxind = BitStr_index(rightx);
+
+ _BS_word x = borrow_hi(xs, xind, rightxind, xpos);
+
+ int rightyind = BitStr_index(righty);
+ int rightypos = BitStr_pos(righty);
+ _BS_word y = borrow_hi(ys, yind, rightyind, ypos);
+ _BS_word ymask;
+ if (yind == rightyind)
+ ymask = rmask(rightypos);
+ else if (yind+1 == rightyind)
+ ymask = rmask(BITSTRBITS - ypos + rightypos + 1);
+ else
+ ymask = ONES;
+
+ int p = startx;
+ for (;;)
+ {
+ if ((x & ymask) == y)
+ {
+ int xi = xind;
+ int yi = yind;
+ for (;;)
+ {
+ if (++yi > rightyind || ++xi > rightxind)
+ return p;
+ _BS_word tx = borrow_hi(xs, xi, rightxind, xpos);
+ _BS_word ty = borrow_hi(ys, yi, rightyind, ypos);
+ if (yi == rightyind)
+ tx &= rmask(rightypos);
+ else if (yi+1 == rightyind)
+ tx &= rmask(BITSTRBITS - ypos + rightypos + 1);
+ if (tx != ty)
+ break;
+ }
+ }
+ if (--p < leftx)
+ return -1;
+ if (--xpos < 0)
+ {
+ xpos = BITSTRBITS - 1;
+ --xind;
+ }
+ x = borrow_hi(xs, xind, rightxind, xpos);
+ }
+ }
+ else
+ {
+
+ int rightx = lengthx - 1;
+ if (ylen == 0) return startx;
+ if (starty < 0 || righty < 0 || startx < 0 || startx >= lengthx) return -1;
+
+ int xind = BitStr_index(startx);
+ int xpos = BitStr_pos(startx);
+ int yind = BitStr_index(starty);
+ int ypos = BitStr_pos(starty);
+
+ int rightxind = BitStr_index(rightx);
+
+ _BS_word x = borrow_hi(xs, xind, rightxind, xpos);
+ _BS_word nextx = (xind >= rightxind) ? 0 : (xs[xind+1] >> xpos);
+
+ int rightyind = BitStr_index(righty);
+ int rightypos = BitStr_pos(righty);
+ _BS_word y = borrow_hi(ys, yind, rightyind, ypos);
+ _BS_word ymask;
+ if (yind == rightyind)
+ ymask = rmask(rightypos);
+ else if (yind+1 == rightyind)
+ ymask = rmask(BITSTRBITS - ypos + rightypos + 1);
+ else
+ ymask = ONES;
+
+ int p = startx;
+ for (;;)
+ {
+ if ((x & ymask) == y)
+ {
+ int xi = xind;
+ int yi = yind;
+ for (;;)
+ {
+ if (++yi > rightyind || ++xi > rightxind)
+ return p;
+ _BS_word tx = borrow_hi(xs, xi, rightxind, xpos);
+ _BS_word ty = borrow_hi(ys, yi, rightyind, ypos);
+ if (yi == rightyind)
+ tx &= rmask(rightypos);
+ else if (yi+1 == rightyind)
+ tx &= rmask(BITSTRBITS - ypos + rightypos + 1);
+ if (tx != ty)
+ break;
+ }
+ }
+ if (++p > rightx)
+ return -1;
+ if (++xpos == BITSTRBITS)
+ {
+ xpos = 0;
+ x = xs[++xind];
+ nextx = (xind >= rightxind) ? 0 : xs[xind+1];
+ }
+ else
+ {
+ x >>= 1;
+ if (nextx & 1)
+ x |= MAXBIT;
+ nextx >>= 1;
+ }
+ }
+ }
+}
+
+
+int BitPattern::search(const _BS_word* xs, int startx, int lengthx) const
+{
+ const _BS_word* ys = pattern.rep->s;
+ const _BS_word* ms = mask.rep->s;
+ int righty = pattern.rep->len - 1;
+ int rightm = mask.rep->len - 1;
+
+ int rev = startx < 0;
+ if (rev)
+ {
+ int leftx = 0;
+ int rightx = lengthx + startx;
+ startx = rightx - righty;
+
+ if (righty < 0) return startx;
+ if (startx < 0 || startx >= lengthx) return -1;
+
+ int xind = BitStr_index(startx);
+ int xpos = BitStr_pos(startx);
+
+ int rightxind = BitStr_index(rightx);
+
+ int rightmind = BitStr_index(rightm);
+ int rightyind = BitStr_index(righty);
+
+ _BS_word x = safe_borrow_hi(xs, xind, rightxind, xpos);
+ _BS_word m = safe_borrow_hi(ms, 0, rightmind, 0);
+ _BS_word y = safe_borrow_hi(ys, 0, rightyind, 0) & m;
+
+ int p = startx;
+ for (;;)
+ {
+ if ((x & m) == y)
+ {
+ int xi = xind;
+ int yi = 0;
+ for (;;)
+ {
+ if (++yi > rightyind || ++xi > rightxind)
+ return p;
+ _BS_word tm = safe_borrow_hi(ms, yi, rightmind, 0);
+ _BS_word ty = safe_borrow_hi(ys, yi, rightyind, 0);
+ _BS_word tx = safe_borrow_hi(xs, xi, rightxind, xpos);
+ if ((tx & tm) != (ty & tm))
+ break;
+ }
+ }
+ if (--p < leftx)
+ return -1;
+ if (--xpos < 0)
+ {
+ xpos = BITSTRBITS - 1;
+ --xind;
+ }
+ x = safe_borrow_hi(xs, xind, rightxind, xpos);
+ }
+ }
+ else
+ {
+
+ int rightx = lengthx - 1;
+
+ if (righty < 0) return startx;
+ if (startx < 0 || startx >= lengthx) return -1;
+
+ int xind = BitStr_index(startx);
+ int xpos = BitStr_pos(startx);
+
+ int rightxind = BitStr_index(rightx);
+
+ int rightmind = BitStr_index(rightm);
+ int rightyind = BitStr_index(righty);
+
+ _BS_word x = safe_borrow_hi(xs, xind, rightxind, xpos);
+ _BS_word m = safe_borrow_hi(ms, 0, rightmind, 0);
+ _BS_word y = safe_borrow_hi(ys, 0, rightyind, 0) & m;
+
+ _BS_word nextx = (xind >= rightxind) ? 0 : (xs[xind+1] >> xpos);
+
+ int p = startx;
+ for (;;)
+ {
+ if ((x & m) == y)
+ {
+ int xi = xind;
+ int yi = 0;
+ for (;;)
+ {
+ if (++yi > rightyind || ++xi > rightxind)
+ return p;
+ _BS_word tm = safe_borrow_hi(ms, yi, rightmind, 0);
+ _BS_word ty = safe_borrow_hi(ys, yi, rightyind, 0);
+ _BS_word tx = safe_borrow_hi(xs, xi, rightxind, xpos);
+ if ((tx & tm) != (ty & tm))
+ break;
+ }
+ }
+ if (++p > rightx)
+ return -1;
+ if (++xpos == BITSTRBITS)
+ {
+ xpos = 0;
+ x = xs[++xind];
+ nextx = (xind >= rightxind) ? 0 : xs[xind+1];
+ }
+ else
+ {
+ x >>= 1;
+ if (nextx & 1)
+ x |= MAXBIT;
+ nextx >>= 1;
+ }
+ }
+ }
+}
+
+int BitString::match(int startx, int lengthx, int exact,
+ const _BS_word* ys, int starty, int yl) const
+{
+ const _BS_word* xs = rep->s;
+ int ylen = yl - starty;
+ int righty = yl - 1;
+
+ int rightx;
+ int rev = startx < 0;
+ if (rev)
+ {
+ rightx = lengthx + startx;
+ startx = rightx - ylen + 1;
+ if (exact && startx != 0)
+ return 0;
+ }
+ else
+ {
+ rightx = lengthx - 1;
+ if (exact && rightx - startx != righty)
+ return 0;
+ }
+
+ if (ylen == 0) return 1;
+ if (righty < 0 || startx < 0 || startx >= lengthx) return 0;
+
+ int xi = BitStr_index(startx);
+ int xpos = BitStr_pos(startx);
+ int yi = BitStr_index(starty);
+ int ypos = BitStr_pos(starty);
+
+ int rightxind = BitStr_index(rightx);
+ int rightyind = BitStr_index(righty);
+ int rightypos = BitStr_pos(righty);
+
+ for (;;)
+ {
+ _BS_word x = borrow_hi(xs, xi, rightxind, xpos);
+ _BS_word y = borrow_hi(ys, yi, rightyind, ypos);
+ if (yi == rightyind)
+ x &= rmask(rightypos);
+ else if (yi+1 == rightyind)
+ x &= rmask(BITSTRBITS - ypos + rightypos + 1);
+ if (x != y)
+ return 0;
+ else if (++yi > rightyind || ++xi > rightxind)
+ return 1;
+ }
+}
+
+int BitPattern::match(const _BS_word* xs, int startx,
+ int lengthx, int exact) const
+{
+ const _BS_word* ys = pattern.rep->s;
+ int righty = pattern.rep->len - 1;
+ _BS_word* ms = mask.rep->s;
+ int rightm = mask.rep->len - 1;
+
+ int rightx;
+ int rev = startx < 0;
+ if (rev)
+ {
+ rightx = lengthx + startx;
+ startx = rightx - righty;
+ if (exact && startx != 0)
+ return 0;
+ }
+ else
+ {
+ rightx = lengthx - 1;
+ if (exact && rightx - startx != righty)
+ return 0;
+ }
+
+ if (righty < 0) return 1;
+ if (startx < 0 || startx >= lengthx) return 0;
+
+ int xind = BitStr_index(startx);
+ int xpos = BitStr_pos(startx);
+ int yind = 0;
+
+ int rightxind = BitStr_index(rightx);
+ int rightyind = BitStr_index(righty);
+ int rightmind = BitStr_index(rightm);
+
+ for(;;)
+ {
+ _BS_word m = safe_borrow_hi(ms, yind, rightmind, 0);
+ _BS_word x = safe_borrow_hi(xs, xind, rightxind, xpos) & m;
+ _BS_word y = safe_borrow_hi(ys, yind, rightyind, 0) & m;
+ if (x != y)
+ return 0;
+ else if (++yind > rightyind || ++xind > rightxind)
+ return 1;
+ }
+}
+
+BitSubString& BitSubString::operator = (const BitString& y)
+{
+ if (&S == &_nil_BitString)
+ return *this;
+ BitStrRep* targ = S.rep;
+
+ unsigned int ylen = y.rep->len;
+ int sl = targ->len - len + ylen;
+
+ if (y.rep == targ || ylen > len)
+ {
+ BitStrRep* oldtarg = targ;
+ targ = BStr_alloc(0, 0, 0, 0, sl);
+ _BS_copy (targ->s, 0, oldtarg->s, 0, pos);
+ copy_bits (targ->s, pos, y.rep->s, 0, ylen);
+ copy_bits (targ->s, pos + ylen, oldtarg->s, pos+len, oldtarg->len-pos-len);
+ delete oldtarg;
+ }
+ else if (len == ylen)
+ copy_bits (targ->s, pos, y.rep->s, 0, len);
+ else if (ylen < len)
+ {
+ copy_bits (targ->s, pos, y.rep->s, 0, ylen);
+ copy_bits (targ->s, pos + ylen, targ->s, pos + len, targ->len - pos - len);
+ targ->len = sl;
+ }
+ check_last(targ);
+ S.rep = targ;
+ return *this;
+}
+
+BitSubString& BitSubString::operator = (const BitSubString& y)
+{
+ if (&S == &_nil_BitString)
+ return *this;
+ BitStrRep* targ = S.rep;
+
+ if (len == 0 || pos >= targ->len)
+ return *this;
+
+ int sl = targ->len - len + y.len;
+
+ if (y.S.rep == targ || y.len > len)
+ {
+ BitStrRep* oldtarg = targ;
+ targ = BStr_alloc(0, 0, 0, 0, sl);
+ _BS_copy_0(targ->s, oldtarg->s, pos);
+ copy_bits (targ->s, pos, y.S.rep->s, y.pos, y.len);
+ copy_bits (targ->s, pos + y.len, oldtarg->s, pos+len,
+ oldtarg->len-pos-len);
+ delete oldtarg;
+ }
+ else if (len == y.len)
+ copy_bits (targ->s, pos, y.S.rep->s, y.pos, y.len);
+ else if (y.len < len)
+ {
+ copy_bits (targ->s, pos, y.S.rep->s, y.pos, y.len);
+ copy_bits (targ->s, pos + y.len, targ->s, pos + len,
+ targ->len - pos - len);
+ targ->len = sl;
+ }
+ check_last(targ);
+ S.rep = targ;
+ return *this;
+}
+
+BitSubString BitString::at(int first, int len)
+{
+ return _substr(first, len);
+}
+
+BitSubString BitString::before(int pos)
+{
+ return _substr(0, pos);
+}
+
+BitSubString BitString::after(int pos)
+{
+ return _substr(pos + 1, rep->len - (pos + 1));
+}
+
+BitSubString BitString::at(const BitString& y, int startpos)
+{
+ int first = search(startpos, rep->len, y.rep->s, 0, y.rep->len);
+ return _substr(first, y.rep->len);
+}
+
+BitSubString BitString::before(const BitString& y, int startpos)
+{
+ int last = search(startpos, rep->len, y.rep->s, 0, y.rep->len);
+ return _substr(0, last);
+}
+
+BitSubString BitString::after(const BitString& y, int startpos)
+{
+ int first = search(startpos, rep->len, y.rep->s, 0, y.rep->len);
+ if (first >= 0) first += y.rep->len;
+ return _substr(first, rep->len - first);
+}
+
+
+BitSubString BitString::at(const BitSubString& y, int startpos)
+{
+ int first = search(startpos, rep->len, y.S.rep->s, y.pos, y.len);
+ return _substr(first, y.len);
+}
+
+BitSubString BitString::before(const BitSubString& y, int startpos)
+{
+ int last = search(startpos, rep->len, y.S.rep->s, y.pos, y.len);
+ return _substr(0, last);
+}
+
+BitSubString BitString::after(const BitSubString& y, int startpos)
+{
+ int first = search(startpos, rep->len, y.S.rep->s, y.pos, y.len);
+ if (first >= 0) first += y.len;
+ return _substr(first, rep->len - first);
+}
+
+BitSubString BitString::at(const BitPattern& r, int startpos)
+{
+ int first = r.search(rep->s, startpos, rep->len);
+ return _substr(first, r.pattern.rep->len);
+}
+
+
+BitSubString BitString::before(const BitPattern& r, int startpos)
+{
+ int first = r.search(rep->s, startpos, rep->len);
+ return _substr(0, first);
+}
+
+BitSubString BitString::after(const BitPattern& r, int startpos)
+{
+ int first = r.search(rep->s, startpos, rep->len);
+ if (first >= 0) first += r.pattern.rep->len;
+ return _substr(first, rep->len - first);
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+#define RETURN(r) return
+#define RETURNS(r) return r;
+#define RETURN_OBJECT(TYPE, NAME) /* nothing */
+#define USE_UNSIGNED 1 /* probably correct */
+#else /* _G_NO_NRV */
+#define RETURN(r) return r
+#define RETURNS(r) /* nothing */
+#define RETURN_OBJECT(TYPE, NAME) TYPE NAME;
+#define USE_UNSIGNED 0 /* probably old bug */
+#endif
+
+BitString
+common_prefix (const BitString& x, const BitString& y, int startpos)
+ RETURNS(r)
+{
+ RETURN_OBJECT(BitString, r);
+ unsigned int xl = x.rep->len;
+ unsigned int yl = y.rep->len;
+
+ unsigned int startx, starty;
+ if (startpos < 0)
+ {
+ startx = xl + startpos;
+ starty = yl + startpos;
+ }
+ else
+ startx = starty = startpos;
+
+ if (startx >= xl || starty >= yl)
+ RETURN(r);
+
+ const _BS_word* xs = &(x.rep->s[BitStr_index(startx)]);
+ _BS_word a = *xs++;
+ unsigned int xp = startx;
+
+ const _BS_word* ys = &(y.rep->s[BitStr_index(starty)]);
+ _BS_word b = *ys++;
+ unsigned int yp = starty;
+
+ for(; xp < xl && yp < yl; ++xp, ++yp)
+ {
+ _BS_word xbit = ((_BS_word)1) << (BitStr_pos(xp));
+ _BS_word ybit = ((_BS_word)1) << (BitStr_pos(yp));
+ if (((a & xbit) == 0) != ((b & ybit) == 0))
+ break;
+ if (xbit == MAXBIT)
+ a = *xs++;
+ if (ybit == MAXBIT)
+ b = *ys++;
+ }
+ r.rep = BStr_alloc(0, x.rep->s, startx, xp, xp - startx);
+ RETURN(r);
+}
+
+
+BitString
+common_suffix (const BitString& x, const BitString& y, int startpos)
+ RETURNS(r)
+{
+ RETURN_OBJECT(BitString, r);
+ unsigned int xl = x.rep->len;
+ unsigned int yl = y.rep->len;
+
+ unsigned int startx, starty;
+ if (startpos < 0)
+ {
+ startx = xl + startpos;
+ starty = yl + startpos;
+ }
+ else
+ startx = starty = startpos;
+
+ if (startx >= xl || starty >= yl)
+ RETURN(r);
+
+ const _BS_word* xs = &(x.rep->s[BitStr_index(startx)]);
+ _BS_word a = *xs--;
+ int xp = startx;
+
+ const _BS_word* ys = &(y.rep->s[BitStr_index(starty)]);
+ _BS_word b = *ys--;
+ int yp = starty;
+
+ for(; xp >= 0 && yp >= 0; --xp, --yp)
+ {
+ _BS_word xbit = ((_BS_word)1) << (BitStr_pos(xp));
+ _BS_word ybit = ((_BS_word)1) << (BitStr_pos(yp));
+ if (((a & xbit) == 0) != ((b & ybit) == 0))
+ break;
+ if (xbit == 1)
+ a = *xs--;
+ if (ybit == 1)
+ b = *ys--;
+ }
+ r.rep = BStr_alloc(0, x.rep->s, xp+1, startx+1, startx - xp);
+ RETURN(r);
+}
+
+BitString reverse (const BitString& x)
+ RETURNS(r)
+{
+ RETURN_OBJECT(BitString, r);
+ unsigned int yl = x.rep->len;
+ BitStrRep* y = BStr_resize(0, yl);
+ if (yl > 0)
+ {
+ const _BS_word* ls = x.rep->s;
+ _BS_word lm = 1;
+ _BS_word* rs = &(y->s[BitStr_index(yl - 1)]);
+ _BS_word rm = ((_BS_word)1) << (BitStr_pos(yl - 1));
+ for (unsigned int l = 0; l < yl; ++l)
+ {
+ if (*ls & lm)
+ *rs |= rm;
+ if (lm == MAXBIT)
+ {
+ ++ls;
+ lm = 1;
+ }
+ else
+ lm <<= 1;
+ if (rm == 1)
+ {
+ --rs;
+ rm = MAXBIT;
+ }
+ else
+ rm >>= 1;
+ }
+ }
+ r.rep = y;
+ RETURN(r);
+}
+
+BitString
+atoBitString (const char* s, char f, char t)
+ RETURNS(res)
+{
+ RETURN_OBJECT(BitString, res);
+ int sl = strlen(s);
+ BitStrRep* r = BStr_resize(0, sl);
+ if (sl != 0)
+ {
+ unsigned int rl = 0;
+ _BS_word* rs = r->s;
+ _BS_word a = 0;
+ _BS_word m = 1;
+ unsigned int i = 0;
+ for(;;)
+ {
+ char ch = s[i];
+ if (ch != t && ch != f)
+ {
+ *rs = a;
+ break;
+ }
+ ++rl;
+ if (ch == t)
+ a |= m;
+ if (++i == sl)
+ {
+ *rs = a;
+ break;
+ }
+ else if (i % BITSTRBITS == 0)
+ {
+ *rs++ = a;
+ a = 0;
+ m = 1;
+ }
+ else
+ m <<= 1;
+ }
+ r = BStr_resize(r, rl);
+ }
+ res.rep = r;
+ RETURN(res);
+}
+
+BitPattern
+atoBitPattern (const char* s, char f,char t,char x)
+ RETURNS(r)
+{
+ RETURN_OBJECT(BitPattern, r);
+ int sl = strlen(s);
+ if (sl != 0)
+ {
+ unsigned int rl = 0;
+ r.pattern.rep = BStr_resize(r.pattern.rep, sl);
+ r.mask.rep = BStr_resize(r.mask.rep, sl);
+ _BS_word* rs = r.pattern.rep->s;
+ _BS_word* ms = r.mask.rep->s;
+ _BS_word a = 0;
+ _BS_word b = 0;
+ _BS_word m = 1;
+ unsigned int i = 0;
+ for(;;)
+ {
+ char ch = s[i];
+ if (ch != t && ch != f && ch != x)
+ {
+ *rs = a;
+ *ms = b;
+ break;
+ }
+ ++rl;
+ if (ch == t)
+ {
+ a |= m;
+ b |= m;
+ }
+ else if (ch == f)
+ {
+ b |= m;
+ }
+ if (++i == sl)
+ {
+ *rs = a;
+ *ms = b;
+ break;
+ }
+ else if (i % BITSTRBITS == 0)
+ {
+ *rs++ = a;
+ *ms++ = b;
+ a = 0;
+ b = 0;
+ m = 1;
+ }
+ else
+ m <<= 1;
+ }
+ r.pattern.rep = BStr_resize(r.pattern.rep, rl);
+ r.mask.rep = BStr_resize(r.mask.rep, rl);
+ }
+ RETURN(r);
+}
+
+extern AllocRing _libgxx_fmtq;
+
+void BitString::printon (ostream& os, char f, char t) const
+{
+ unsigned int xl = rep->len;
+ const _BS_word* ptr = rep->s;
+ register streambuf *sb = os.rdbuf();
+ _BS_word a = 0;
+
+ for (unsigned int i = 0; i < xl; ++i)
+ {
+ if (i % BITSTRBITS == 0)
+ a = *ptr++;
+ sb->sputc((a & 1)? t : f);
+ a >>= 1;
+ }
+}
+const char* BitStringtoa(const BitString& x, char f, char t)
+{
+ int wrksiz = x.length() + 2;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ ostrstream stream(fmtbase, wrksiz);
+
+ x.printon(stream, f, t);
+ stream << ends;
+ return fmtbase;
+}
+
+ostream& operator << (ostream& s, const BitString& x)
+{
+ if (s.opfx())
+ x.printon(s);
+ return s;
+}
+
+const char* BitPatterntoa(const BitPattern& p, char f,char t,char x)
+{
+ unsigned int pl = p.pattern.rep->len;
+ unsigned int ml = p.mask.rep->len;
+ unsigned int l = (pl <= ml)? pl : ml;
+
+ int wrksiz = l + 2;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ ostrstream stream(fmtbase, wrksiz);
+
+ p.printon(stream, f, t, x);
+ stream << ends;
+ return fmtbase;
+}
+
+void BitPattern::printon(ostream& s, char f,char t,char x) const
+{
+ unsigned int pl = pattern.rep->len;
+ unsigned int ml = mask.rep->len;
+ unsigned int l = (pl <= ml)? pl : ml;
+ register streambuf *sb = s.rdbuf();
+
+ const _BS_word* ps = pattern.rep->s;
+ const _BS_word* ms = mask.rep->s;
+ _BS_word a = 0;
+ _BS_word m = 0;
+
+ for (unsigned int i = 0; i < l; ++i)
+ {
+ if (i % BITSTRBITS == 0)
+ {
+ a = *ps++;
+ m = *ms++;
+ }
+ if (m & 1)
+ sb->sputc((a & 1)? t : f);
+ else
+ sb->sputc(x);
+ a >>= 1;
+ m >>= 1;
+ }
+}
+
+ostream& operator << (ostream& s, const BitPattern& x)
+{
+ if (s.opfx())
+ x.printon(s);
+ return s;
+}
+
+
+int BitString::OK() const
+{
+ int v = rep != 0; // have a rep;
+ v &= BitStr_len(rep->len) <= rep->sz; // within allocated size
+ if (!v) error("invariant failure");
+ return v;
+}
+
+int BitSubString::OK() const
+{
+ int v = S.OK(); // valid BitString
+ v &= pos + len <= S.rep->len; // within bounds of targ
+ if (!v) S.error("BitSubString invariant failure");
+ return v;
+}
+
+int BitPattern::OK() const
+{
+ int v = pattern.OK() && mask.OK();
+ if (!v) pattern.error("BitPattern invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/libg++/Complex.cc b/gnu/lib/libg++/libg++/Complex.cc
new file mode 100644
index 0000000..5aed909
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Complex.cc
@@ -0,0 +1,256 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Complex.h>
+#include <std.h>
+#include <builtin.h>
+
+// error handling
+
+void default_Complex_error_handler(const char* msg)
+{
+ cerr << "Fatal Complex arithmetic error. " << msg << "\n";
+ exit(1);
+}
+
+one_arg_error_handler_t Complex_error_handler = default_Complex_error_handler;
+
+one_arg_error_handler_t set_Complex_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = Complex_error_handler;
+ Complex_error_handler = f;
+ return old;
+}
+
+void Complex::error(const char* msg) const
+{
+ (*Complex_error_handler)(msg);
+}
+
+/* from romine@xagsun.epm.ornl.gov */
+Complex /* const */ operator / (const Complex& x, const Complex& y)
+{
+ double den = fabs(y.real()) + fabs(y.imag());
+ if (den == 0.0) x.error ("Attempted division by zero.");
+ double xrden = x.real() / den;
+ double xiden = x.imag() / den;
+ double yrden = y.real() / den;
+ double yiden = y.imag() / den;
+ double nrm = yrden * yrden + yiden * yiden;
+ return Complex((xrden * yrden + xiden * yiden) / nrm,
+ (xiden * yrden - xrden * yiden) / nrm);
+}
+
+Complex& Complex::operator /= (const Complex& y)
+{
+ double den = fabs(y.real()) + fabs(y.imag());
+ if (den == 0.0) error ("Attempted division by zero.");
+ double xrden = re / den;
+ double xiden = im / den;
+ double yrden = y.real() / den;
+ double yiden = y.imag() / den;
+ double nrm = yrden * yrden + yiden * yiden;
+ re = (xrden * yrden + xiden * yiden) / nrm;
+ im = (xiden * yrden - xrden * yiden) / nrm;
+ return *this;
+}
+
+Complex /* const */ operator / (double x, const Complex& y)
+{
+ double den = norm(y);
+ if (den == 0.0) y.error ("Attempted division by zero.");
+ return Complex((x * y.real()) / den, -(x * y.imag()) / den);
+}
+
+Complex /* const */ operator / (const Complex& x, double y)
+{
+ if (y == 0.0) x.error ("Attempted division by zero.");
+ return Complex(x.real() / y, x.imag() / y);
+}
+
+
+Complex& Complex::operator /= (double y)
+{
+ if (y == 0.0) error ("Attempted division by zero.");
+ re /= y; im /= y;
+ return *this;
+}
+
+
+Complex /* const */ exp(const Complex& x)
+{
+ double r = exp(x.real());
+ return Complex(r * cos(x.imag()),
+ r * sin(x.imag()));
+}
+
+Complex /* const */ cosh(const Complex& x)
+{
+ return Complex(cos(x.imag()) * cosh(x.real()),
+ sin(x.imag()) * sinh(x.real()));
+}
+
+Complex /* const */ sinh(const Complex& x)
+{
+ return Complex(cos(x.imag()) * sinh(x.real()),
+ sin(x.imag()) * cosh(x.real()));
+}
+
+Complex /* const */ cos(const Complex& x)
+{
+ return Complex(cos(x.real()) * cosh(x.imag()),
+ -sin(x.real()) * sinh(x.imag()));
+}
+
+Complex /* const */ sin(const Complex& x)
+{
+ return Complex(sin(x.real()) * cosh(x.imag()),
+ cos(x.real()) * sinh(x.imag()));
+}
+
+Complex /* const */ log(const Complex& x)
+{
+ double h = hypot(x.real(), x.imag());
+ if (h <= 0.0) x.error("attempted log of zero magnitude number.");
+ return Complex(log(h), atan2(x.imag(), x.real()));
+}
+
+// Corrections based on reports from: thc@cs.brown.edu & saito@sdr.slb.com
+Complex /* const */ pow(const Complex& x, const Complex& p)
+{
+ double h = hypot(x.real(), x.imag());
+ if (h <= 0.0) x.error("attempted power of zero magnitude number.");
+
+ double a = atan2(x.imag(), x.real());
+ double lr = pow(h, p.real());
+ double li = p.real() * a;
+ if (p.imag() != 0.0)
+ {
+ lr /= exp(p.imag() * a);
+ li += p.imag() * log(h);
+ }
+ return Complex(lr * cos(li), lr * sin(li));
+}
+
+Complex /* const */ pow(const Complex& x, double p)
+{
+ double h = hypot(x.real(), x.imag());
+ if (h <= 0.0) x.error("attempted power of zero magnitude number.");
+ double lr = pow(h, p);
+ double a = atan2(x.imag(), x.real());
+ double li = p * a;
+ return Complex(lr * cos(li), lr * sin(li));
+}
+
+
+Complex /* const */ sqrt(const Complex& x)
+{
+ if (x.real() == 0.0 && x.imag() == 0.0)
+ return Complex(0.0, 0.0);
+ else
+ {
+ double s = sqrt((fabs(x.real()) + hypot(x.real(), x.imag())) * 0.5);
+ double d = (x.imag() / s) * 0.5;
+ if (x.real() > 0.0)
+ return Complex(s, d);
+ else if (x.imag() >= 0.0)
+ return Complex(d, s);
+ else
+ return Complex(-d, -s);
+ }
+}
+
+
+Complex /* const */ pow(const Complex& x, int p)
+{
+ if (p == 0)
+ return Complex(1.0, 0.0);
+ else if (x == 0.0)
+ return Complex(0.0, 0.0);
+ else
+ {
+ Complex res(1.0, 0.0);
+ Complex b = x;
+ if (p < 0)
+ {
+ p = -p;
+ b = 1.0 / b;
+ }
+ for(;;)
+ {
+ if (p & 1)
+ res *= b;
+ if ((p >>= 1) == 0)
+ return res;
+ else
+ b *= b;
+ }
+ }
+}
+
+ostream& operator << (ostream& s, const Complex& x)
+{
+ return s << "(" << x.real() << ", " << x.imag() << ")" ;
+}
+
+istream& operator >> (istream& s, Complex& x)
+{
+#ifdef _OLD_STREAMS
+ if (!s.good())
+ {
+ return s;
+ }
+#else
+ if (!s.ipfx(0))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+#endif
+ double r, i;
+ char ch;
+ s >> ws;
+ s.get(ch);
+ if (ch == '(')
+ {
+ s >> r;
+ s >> ws;
+ s.get(ch);
+ if (ch == ',')
+ {
+ s >> i;
+ s >> ws;
+ s .get(ch);
+ }
+ else
+ i = 0;
+ if (ch != ')')
+ s.clear(ios::failbit);
+ }
+ else
+ {
+ s.putback(ch);
+ s >> r;
+ i = 0;
+ }
+ x = Complex(r, i);
+ return s;
+}
+
diff --git a/gnu/lib/libg++/libg++/CursesW.cc b/gnu/lib/libg++/libg++/CursesW.cc
new file mode 100644
index 0000000..92bddfe
--- /dev/null
+++ b/gnu/lib/libg++/libg++/CursesW.cc
@@ -0,0 +1,253 @@
+/*
+Copyright (C) 1989, 1992 Free Software Foundation
+ written by Eric Newton (newton@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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <builtin.h>
+#ifndef _OLD_STREAMS
+#include <strstream.h>
+#endif
+// Include CurseW.h and/or curses.h *after* iostream includes,
+// because curses.h defines a clear macro that conflicts with iostream. Sigh.
+#include <CursesW.h>
+
+#if _G_HAVE_CURSES
+
+int CursesWindow::count = 0;
+
+/*
+ * C++ interface to curses library.
+ *
+ */
+
+#if !defined(_IO_MAGIC) && !defined(HAVE_VSCANF) &&!defined vsscanf
+extern "C" int _doscan(FILE *, const char*, va_list args);
+
+static int vsscanf(char *buf, const char * fmt, va_list args)
+{
+ FILE b;
+#ifdef _IOSTRG
+ b._flag = _IOREAD|_IOSTRG;
+#else
+ b._flag = _IOREAD;
+#endif
+ b._base = (unsigned char*)buf;
+ b._ptr = (unsigned char*)buf;
+ b._cnt = BUFSIZ;
+ return _doscan(&b, fmt, args);
+}
+#endif
+
+/*
+ * varargs functions are handled conservatively:
+ * They interface directly into the underlying
+ * _doscan, _doprnt and/or vfprintf routines rather than
+ * assume that such things are handled compatibly in the curses library
+ */
+
+int CursesWindow::scanw(const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#ifdef VMS
+ int result = wscanw(w , fmt , args);
+#else /* NOT VMS */
+ char buf[BUFSIZ];
+ int result = wgetstr(w, buf);
+ if (result == OK) {
+
+#ifdef _IO_MAGIC /* GNU iostreams */
+ strstreambuf ss(buf, BUFSIZ);
+ result = ss.vscan(fmt, args);
+#else
+ result = vsscanf(buf, fmt, args);
+#endif
+ }
+#endif /* !VMS */
+ va_end(args);
+ return result;
+}
+
+int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buf[BUFSIZ];
+ int result = wmove(w, y, x);
+ if (result == OK)
+#ifdef VMS
+ result=wscanw(w , fmt , args);
+#else /* !VMS */
+ {
+ result = wgetstr(w, buf);
+ if (result == OK) {
+#ifdef _IO_MAGIC /* GNU iostreams */
+ strstreambuf ss(buf, BUFSIZ);
+ result = ss.vscan(fmt, args);
+#else
+ result = vsscanf(buf, fmt, args);
+#endif
+ }
+ }
+#endif /* !VMS */
+ va_end(args);
+ return result;
+}
+
+int CursesWindow::printw(const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buf[BUFSIZ];
+ vsprintf(buf, fmt, args);
+ va_end(args);
+ return waddstr(w, buf);
+}
+
+
+int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ int result = wmove(w, y, x);
+ if (result == OK)
+ {
+ char buf[BUFSIZ];
+ vsprintf(buf, fmt, args);
+ result = waddstr(w, buf);
+ }
+ va_end(args);
+ return result;
+}
+
+CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
+{
+ if (count==0)
+ initscr();
+
+ w = newwin(lines, cols, begin_y, begin_x);
+ if (w == 0)
+ {
+ (*lib_error_handler)("CursesWindow", "Cannot construct window");
+ }
+
+ alloced = 1;
+ subwins = par = sib = 0;
+ count++;
+}
+
+CursesWindow::CursesWindow(WINDOW* &window)
+{
+ if (count==0)
+ initscr();
+
+ w = window;
+ alloced = 0;
+ subwins = par = sib = 0;
+ count++;
+}
+
+CursesWindow::CursesWindow(CursesWindow& win, int l, int c,
+ int by, int bx, char absrel)
+{
+
+ if (absrel == 'r') // relative origin
+ {
+ by += win.begy();
+ bx += win.begx();
+ }
+
+ // Even though we treat subwindows as a tree, the standard curses
+ // library needs the `subwin' call to link to the root in
+ // order to correctly perform refreshes, etc.
+
+ CursesWindow* root = &win;
+ while (root->par != 0) root = root->par;
+
+ w = subwin(root->w, l, c, by, bx);
+ if (w == 0)
+ {
+ (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
+ }
+
+ par = &win;
+ sib = win.subwins;
+ win.subwins = this;
+ subwins = 0;
+ alloced = 1;
+ count++;
+}
+
+
+void CursesWindow::kill_subwindows()
+{
+ for (CursesWindow* p = subwins; p != 0; p = p->sib)
+ {
+ p->kill_subwindows();
+ if (p->alloced)
+ {
+ if (p->w != 0)
+ ::delwin(p->w);
+ p->alloced = 0;
+ }
+ p->w = 0; // cause a run-time error if anyone attempts to use...
+ }
+}
+
+CursesWindow::~CursesWindow()
+{
+ kill_subwindows();
+
+ if (par != 0) // Snip us from the parent's list of subwindows.
+ {
+ CursesWindow * win = par->subwins;
+ CursesWindow * trail = 0;
+ for (;;)
+ {
+ if (win == 0)
+ break;
+ else if (win == this)
+ {
+ if (trail != 0)
+ trail->sib = win->sib;
+ else
+ par->subwins = win->sib;
+ break;
+ }
+ else
+ {
+ trail = win;
+ win = win->sib;
+ }
+ }
+ }
+
+ if (alloced && w != 0)
+ delwin(w);
+
+ --count;
+ if (count == 0)
+ endwin();
+ else if (count < 0) // cannot happen!
+ {
+ (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
+ }
+}
+
+#endif /* _G_HAVE_CURSES */
diff --git a/gnu/lib/libg++/libg++/DLList.cc b/gnu/lib/libg++/libg++/DLList.cc
new file mode 100644
index 0000000..87874c3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/DLList.cc
@@ -0,0 +1,327 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _G_NO_TEMPLATES
+#ifdef __GNUG__
+//#pragma implementation
+#endif
+#include <limits.h>
+#include <stream.h>
+#include <builtin.h>
+#include "DLList.h"
+
+void BaseDLList::error(const char* msg)
+{
+ (*lib_error_handler)("DLList", msg);
+}
+
+int BaseDLList::length() const
+{
+ int l = 0;
+ BaseDLNode* t = h;
+ if (t != 0) do { ++l; t = t->fd; } while (t != h);
+ return l;
+}
+
+// Note: This is an internal method. It does *not* free old contents!
+
+void BaseDLList::copy(const BaseDLList& a)
+{
+ if (a.h == 0)
+ h = 0;
+ else
+ {
+ BaseDLNode* p = a.h;
+ BaseDLNode* t = copy_node(p->item());
+ h = t;
+ p = p->fd;
+ while (p != a.h)
+ {
+ BaseDLNode* n = copy_node(p->item());
+ t->fd = n;
+ n->bk = t;
+ t = n;
+ p = p->fd;
+ }
+ t->fd = h;
+ h->bk = t;
+ return;
+ }
+}
+
+void BaseDLList::clear()
+{
+ if (h == 0)
+ return;
+
+ BaseDLNode* p = h->fd;
+ h->fd = 0;
+ h = 0;
+
+ while (p != 0)
+ {
+ BaseDLNode* nxt = p->fd;
+ delete_node(p);
+ p = nxt;
+ }
+}
+
+BaseDLList& BaseDLList::operator = (const BaseDLList& a)
+{
+ if (h != a.h)
+ {
+ clear();
+ copy(a);
+ }
+ return *this;
+}
+
+
+Pix BaseDLList::prepend(const void *datum)
+{
+ BaseDLNode* t = copy_node(datum);
+ if (h == 0)
+ t->fd = t->bk = h = t;
+ else
+ {
+ t->fd = h;
+ t->bk = h->bk;
+ h->bk->fd = t;
+ h->bk = t;
+ h = t;
+ }
+ return Pix(t);
+}
+
+Pix BaseDLList::append(const void *datum)
+{
+ BaseDLNode* t = copy_node(datum);
+ if (h == 0)
+ t->fd = t->bk = h = t;
+ else
+ {
+ t->bk = h->bk;
+ t->bk->fd = t;
+ t->fd = h;
+ h->bk = t;
+ }
+ return Pix(t);
+}
+
+Pix BaseDLList::ins_after(Pix p, const void *datum)
+{
+ if (p == 0) return prepend(datum);
+ BaseDLNode* u = (BaseDLNode*) p;
+ BaseDLNode* t = copy_node(datum);
+ t->bk = u;
+ t->fd = u->fd;
+ u->fd->bk = t;
+ u->fd = t;
+ return Pix(t);
+}
+
+Pix BaseDLList::ins_before(Pix p, const void *datum)
+{
+ if (p == 0) error("null Pix");
+ BaseDLNode* u = (BaseDLNode*) p;
+ BaseDLNode* t = copy_node(datum);
+ t->bk = u->bk;
+ t->fd = u;
+ u->bk->fd = t;
+ u->bk = t;
+ if (u == h) h = t;
+ return Pix(t);
+}
+
+void BaseDLList::join(BaseDLList& b)
+{
+ BaseDLNode* t = b.h;
+ b.h = 0;
+ if (h == 0)
+ h = t;
+ else if (t != 0)
+ {
+ BaseDLNode* l = t->bk;
+ h->bk->fd = t;
+ t->bk = h->bk;
+ h->bk = l;
+ l->fd = h;
+ }
+}
+
+int BaseDLList::owns(Pix p)
+{
+ BaseDLNode* t = h;
+ if (t != 0 && p != 0)
+ {
+ do
+ {
+ if (Pix(t) == p) return 1;
+ t = t->fd;
+ } while (t != h);
+ }
+ return 0;
+}
+
+void BaseDLList::del(Pix& p, int dir)
+{
+ if (p == 0) error("null Pix");
+ BaseDLNode* t = (BaseDLNode*) p;
+ if (t->fd == t)
+ {
+ h = 0;
+ p = 0;
+ }
+ else
+ {
+ if (dir < 0)
+ {
+ if (t == h)
+ p = 0;
+ else
+ p = Pix(t->bk);
+ }
+ else
+ {
+ if (t == h->bk)
+ p = 0;
+ else
+ p = Pix(t->fd);
+ }
+ t->bk->fd = t->fd;
+ t->fd->bk = t->bk;
+ if (t == h) h = t->fd;
+ }
+ delete t;
+}
+
+void BaseDLList::del_after(Pix& p)
+{
+ if (p == 0)
+ {
+ del_front();
+ return;
+ }
+
+ BaseDLNode* b = (BaseDLNode*) p;
+ BaseDLNode* t = b->fd;
+
+ if (b == t)
+ {
+ h = 0;
+ p = 0;
+ }
+ else
+ {
+ t->bk->fd = t->fd;
+ t->fd->bk = t->bk;
+ if (t == h) h = t->fd;
+ }
+ delete_node(t);
+}
+
+void BaseDLList::remove_front(void *dst)
+{
+ if (h == 0)
+ error("remove_front of empty list");
+ else {
+ BaseDLNode* t = h;
+ copy_item(dst, t->item());
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ h->fd->bk = h->bk;
+ h->bk->fd = h->fd;
+ h = h->fd;
+ }
+ delete_node(t);
+ }
+}
+
+void BaseDLList::del_front()
+{
+ if (h == 0)
+ error("del_front of empty list");
+ BaseDLNode* t = h;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ h->fd->bk = h->bk;
+ h->bk->fd = h->fd;
+ h = h->fd;
+ }
+ delete_node(t);
+}
+
+void BaseDLList::remove_rear(void *dst)
+{
+ if (h == 0)
+ error("remove_rear of empty list");
+ else
+ {
+ BaseDLNode* t = h->bk;
+ copy_item(dst, t->item());
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ t->fd->bk = t->bk;
+ t->bk->fd = t->fd;
+ }
+ delete_node(t);
+ }
+}
+
+void BaseDLList::del_rear()
+{
+ if (h == 0)
+ error("del_rear of empty list");
+ BaseDLNode* t = h->bk;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ t->fd->bk = t->bk;
+ t->bk->fd = t->fd;
+ }
+ delete_node(t);
+}
+
+
+int BaseDLList::OK()
+{
+ int v = 1;
+ if (h != 0)
+ {
+ BaseDLNode* t = h;
+ long count = LONG_MAX; // Lots of chances to find h!
+ do
+ {
+ count--;
+ v &= t->bk->fd == t;
+ v &= t->fd->bk == t;
+ t = t->fd;
+ } while (v && count > 0 && t != h);
+ v &= count > 0;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+#endif
diff --git a/gnu/lib/libg++/libg++/DiscUnif.cc b/gnu/lib/libg++/libg++/DiscUnif.cc
new file mode 100644
index 0000000..136ad11
--- /dev/null
+++ b/gnu/lib/libg++/libg++/DiscUnif.cc
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <DiscUnif.h>
+
+double DiscreteUniform::operator()()
+{
+ long tmp = long(floor(delta * pGenerator -> asDouble()));
+ return( double(pLow + tmp) );
+}
+
diff --git a/gnu/lib/libg++/libg++/Erlang.cc b/gnu/lib/libg++/libg++/Erlang.cc
new file mode 100644
index 0000000..da3e4e7
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Erlang.cc
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Erlang.h>
+
+double Erlang::operator()()
+{
+ double prod = 1.0;
+
+ for (int i = 0; i < k; i++) {
+ prod *= pGenerator -> asDouble();
+ }
+ return(-log(prod)/a);
+}
diff --git a/gnu/lib/libg++/libg++/Fix.cc b/gnu/lib/libg++/libg++/Fix.cc
new file mode 100644
index 0000000..f067eb3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Fix.cc
@@ -0,0 +1,663 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+//
+// Fix.cc : variable length fixed point data type class functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Fix.h>
+#include <std.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <strstream.h>
+
+// member constants
+
+const _G_uint16_t Fix::min_length;
+const _G_uint16_t Fix::max_length;
+const double Fix::min_value;
+const double Fix::max_value;
+
+// default parameters
+
+_G_uint16_t Fix::default_length = 16;
+int Fix::default_print_width = 8;
+
+Fix::PEH Fix::overflow_handler = Fix::overflow_saturate;
+
+Fix::Rep Fix::Rep_0 = { 16, 1, 1, { 0 } };
+Fix::Rep Fix::Rep_m1 = { 16, 1, 1, { 0x8000 } };
+Fix::Rep Fix::Rep_quotient_bump = { 16, 1, 1, { 0x4000 } };
+
+// error handling
+
+void
+Fix::default_error_handler(const char* msg)
+{
+ cerr << "Fix: " << msg << "\n";
+ abort();
+}
+
+void
+Fix::default_range_error_handler(const char* msg)
+{
+ cerr << "Fix: range error in " << msg << "\n";
+ //abort();
+}
+
+one_arg_error_handler_t
+ Fix::error_handler = Fix::default_error_handler,
+ Fix::range_error_handler = Fix::default_range_error_handler;
+
+one_arg_error_handler_t
+Fix::set_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = error_handler;
+ error_handler = f;
+ return old;
+}
+
+one_arg_error_handler_t
+Fix::set_range_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = range_error_handler;
+ range_error_handler = f;
+ return old;
+}
+
+void
+Fix::error(const char* msg)
+{
+ error_handler(msg);
+}
+
+void
+Fix::range_error(const char* msg)
+{
+ range_error_handler(msg);
+}
+
+// Fix::Rep allocation and initialization functions
+
+static inline Fix::Rep*
+_new_Fix(_G_uint16_t len)
+{
+ int siz = (((_G_uint32_t) len + 15) >> 4);
+ if (siz <= 0) siz = 1;
+ unsigned int allocsiz = (sizeof(Fix::Rep) + (siz - 1) * sizeof(_G_uint16_t));
+ Fix::Rep* z = (Fix::Rep*)(new char[allocsiz]);
+ memset(z, 0, allocsiz);
+ z->len = len;
+ z->siz = siz;
+ z->ref = 1;
+ return z;
+}
+
+Fix::Rep*
+Fix::new_Fix(_G_uint16_t len)
+{
+ return _new_Fix(len);
+}
+
+Fix::Rep*
+Fix::new_Fix(_G_uint16_t len, const Rep* x)
+{
+ Rep* z = _new_Fix(len);
+ return copy(x,z);
+}
+
+Fix::Rep*
+Fix::new_Fix(_G_uint16_t len, double d)
+{
+ Rep* z = _new_Fix(len);
+
+ if ( d == max_value )
+ {
+ z->s[0] = 0x7fff;
+ for ( int i=1; i < z->siz; i++ )
+ z->s[i] = 0xffff;
+ }
+ else if ( d < min_value || d > max_value )
+ range_error("declaration");
+ else
+ {
+ if (d < 0)
+ d += 2.0;
+ d *= 32768;
+ for ( int i=0; i < z->siz; i++ )
+ {
+ z->s[i] = (_G_uint16_t )d;
+ d -= z->s[i];
+ d *= 65536;
+ }
+ if ( d >= 32768 )
+ z->s[z->siz-1]++;
+ }
+ mask(z);
+ return z;
+}
+
+// convert to a double
+
+double
+value(const Fix& x)
+{
+ double d = 0.0;
+ for ( int i=x.rep->siz-1; i >= 0; i-- )
+ {
+ d += x.rep->s[i];
+ d *= 1./65536.;
+ }
+ d *= 2.;
+ return d < 1. ? d : d - 2.;
+}
+
+// extract mantissa to Integer
+
+Integer
+mantissa(const Fix& x)
+{
+ Integer a = 1, b=1;
+ for ( int i=0; i < x.rep->siz; i++ )
+ {
+ a <<= 16;
+ a += x.rep->s[i];
+ b <<= 16;
+ }
+ return a-b;
+}
+
+// comparison functions
+
+inline static int
+docmp(const _G_uint16_t* x, const _G_uint16_t* y, int siz)
+{
+ int diff = (_G_int16_t )*x - (_G_int16_t )*y;
+ while ( --siz && !diff )
+ diff = (_G_int32_t )(_G_uint32_t )*++x - (_G_int32_t )(_G_uint32_t )*++y;
+ return diff;
+}
+
+inline static int
+docmpz(const _G_uint16_t* x, int siz)
+{
+ while ( siz-- )
+ if ( *x++ ) return 1;
+ return 0;
+}
+
+int
+Fix::compare(const Rep* x, const Rep* y)
+{
+ if ( x->siz == y->siz )
+ return docmp(x->s, y->s, x->siz);
+ else
+ {
+ int r;
+ const Rep* longer, *shorter;
+ if ( x->siz > y->siz )
+ {
+ longer = x;
+ shorter = y;
+ r = 1;
+ }
+ else
+ {
+ longer = y;
+ shorter = x;
+ r = -1;
+ }
+ int diff = docmp(x->s, y->s, shorter->siz);
+ if ( diff )
+ return diff;
+ else if ( docmpz(&longer->s[shorter->siz], longer->siz-shorter->siz) )
+ return r;
+ else
+ return 0;
+ }
+}
+
+// arithmetic functions
+
+Fix::Rep*
+Fix::add(const Rep* x, const Rep* y, Rep* r)
+{
+ _G_uint16_t xsign = x->s[0], ysign = y->s[0];
+ const Rep* longer, *shorter;
+ if ( x->len >= y->len )
+ longer = x, shorter = y;
+ else
+ longer = y, shorter = x;
+ if ( r == NULL )
+ r = new_Fix(longer->len);
+ for ( int i=r->siz-1; i >= longer->siz; i-- )
+ r->s[i] = 0;
+ for ( ; i >= shorter->siz; i-- )
+ r->s[i] = longer->s[i];
+ _G_uint32_t sum = 0, carry = 0;
+ for ( ; i >= 0; i-- )
+ {
+ sum = carry + (_G_uint32_t )x->s[i] + (_G_uint32_t )y->s[i];
+ carry = sum >> 16;
+ r->s[i] = sum;
+ }
+ if ( (xsign ^ sum) & (ysign ^ sum) & 0x8000 )
+ overflow_handler(r);
+ return r;
+}
+
+Fix::Rep*
+Fix::subtract(const Rep* x, const Rep* y, Rep* r)
+{
+ _G_uint16_t xsign = x->s[0], ysign = y->s[0];
+ const Rep* longer, *shorter;
+ if ( x->len >= y->len )
+ longer = x, shorter = y;
+ else
+ longer = y, shorter = x;
+ if ( r == NULL )
+ r = new_Fix(longer->len);
+ for ( int i=r->siz-1; i >= longer->siz; i-- )
+ r->s[i] = 0;
+ for ( ; i >= shorter->siz; i-- )
+ r->s[i] = (longer == x ? x->s[i] : -y->s[i]);
+ _G_int16_t carry = 0;
+ _G_uint32_t sum = 0;
+ for ( ; i >= 0; i-- )
+ {
+ sum = (_G_int32_t )carry + (_G_uint32_t )x->s[i] - (_G_uint32_t )y->s[i];
+ carry = sum >> 16;
+ r->s[i] = sum;
+ }
+ if ( (xsign ^ sum) & (~ysign ^ sum) & 0x8000 )
+ overflow_handler(r);
+ return r;
+}
+
+Fix::Rep*
+Fix::multiply(const Rep* x, const Rep* y, Rep* r)
+{
+ if ( r == NULL )
+ r = new_Fix(x->len + y->len);
+ int xsign = x->s[0] & 0x8000,
+ ysign = y->s[0] & 0x8000;
+ Fix X(x->len), Y(y->len);
+ if ( xsign )
+ x = negate(x,X.rep);
+ if ( ysign )
+ y = negate(y,Y.rep);
+ for ( int i=0; i < r->siz; i++ )
+ r->s[i] = 0;
+ for ( i=x->siz-1; i >= 0; i-- )
+ {
+ _G_uint32_t carry = 0;
+ for ( int j=y->siz-1; j >= 0; j-- )
+ {
+ int k = i + j + 1;
+ _G_uint32_t a = (_G_uint32_t )x->s[i] * (_G_uint32_t )y->s[j];
+ _G_uint32_t b = ((a << 1) & 0xffff) + carry;
+ if ( k < r->siz )
+ {
+ b += r->s[k];
+ r->s[k] = b;
+ }
+ if ( k < (int)r->siz + 1 )
+ carry = (a >> 15) + (b >> 16);
+ }
+ r->s[i] = carry;
+ }
+ if ( xsign != ysign )
+ negate(r,r);
+ return r;
+}
+
+Fix::Rep*
+Fix::multiply(const Rep* x, int y, Rep* r)
+{
+ if ( y != (_G_int16_t )y )
+ range_error("multiply by int -- int too large");
+ if ( r == NULL )
+ r = new_Fix(x->len);
+ for ( int i=r->siz-1; i >= x->siz; i-- )
+ r->s[i] = 0;
+ _G_int32_t a, carry = 0;
+ for ( ; i > 0; i-- )
+ {
+ a = (_G_int32_t) (_G_uint32_t )x->s[i] * y + carry;
+ r->s[i] = a;
+ carry = a >> 16; // assumes arithmetic right shift
+ }
+ a = (_G_int32_t) (_G_int16_t )x->s[0] * y + carry;
+ r->s[0] = a;
+ a &= 0xffff8000L;
+ if ( a != 0xffff8000L && a != 0L ) {
+ r->s[0] = 0x8000 ^ x->s[0] ^ y;
+ overflow_handler(r);
+ }
+ return r;
+}
+
+Fix::Rep*
+Fix::divide(const Rep* x, const Rep* y, Rep* q, Rep* r)
+{
+ int xsign = x->s[0] & 0x8000,
+ ysign = y->s[0] & 0x8000;
+ if ( q == NULL )
+ q = new_Fix(x->len);
+ copy(&Rep_0,q);
+ if ( r == NULL )
+ r = new_Fix(x->len + y->len - 1);
+ if ( xsign )
+ negate(x,r);
+ else
+ copy(x,r);
+ Fix Y(y->len);
+ Rep* y2 = ( ysign ? negate(y,Y.rep) : copy(y,Y.rep) );
+ if ( !compare(y2) )
+ range_error("division -- division by zero");
+ else if ( compare(x,y2) >= 0 )
+ if ( compare(x,y2) == 0 && (xsign ^ ysign) != 0 )
+ {
+ copy(&Rep_m1,q);
+ copy(&Rep_0,r);
+ }
+ else
+ range_error("division");
+ else
+ {
+ Rep* t;
+ Fix S(r->len),
+ W(q->len,&Rep_quotient_bump);
+ for ( int i=1; i < q->len; i++ )
+ {
+ shift(y2,-1,y2);
+ subtract(r,y2,S.rep);
+ int s_status = compare(S.rep);
+ if ( s_status == 0 )
+ {
+ t = r, r = S.rep, S.rep = t;
+ break;
+ }
+ else if ( s_status > 0 )
+ {
+ t = r, r = S.rep, S.rep = t;
+ add(q,W.rep,q);
+ }
+ shift(W.rep,-1,W.rep);
+ }
+ if ( xsign ^ ysign )
+ negate(q,q);
+ }
+ return q;
+}
+
+Fix::Rep*
+Fix::shift(const Rep* x, int y, Rep* r)
+{
+ if ( r == NULL )
+ r = new_Fix(x->len);
+ if ( y == 0 )
+ {
+ copy (x, r);
+ return r;
+ }
+
+ int ay = abs((long) y),
+ ayh = ay >> 4,
+ ayl = ay & 0x0f;
+ int xl, u, ilow, ihigh;
+ _G_uint16_t *rs;
+ const _G_uint16_t *xsl, *xsr;
+
+ if ( y > 0 )
+ {
+ rs = r->s;
+ xsl = x->s + ayh;
+ xsr = xsl + 1;
+ xl = ayl;
+ u = 1;
+ ihigh = x->siz - ayh - 1;
+ ilow = 0;
+ }
+ else
+ {
+ rs = &r->s[r->siz - 1];
+ xsr = &x->s[r->siz - 1] - ayh;
+ xsl = xsr - 1;
+ xl = 16 - ayl;
+ u = -1;
+ ihigh = r->siz - ayh - 1;
+ ilow = ihigh - x->siz;
+ }
+
+ int xr = 16 - xl;
+ _G_uint16_t xrmask = 0xffffL >> xr;
+ for ( int i=0; i < ilow; i++, rs+=u, xsl+=u, xsr+=u )
+ *rs = 0;
+ for ( ; i < ihigh; i++, rs+=u, xsl+=u, xsr+=u )
+ *rs = (*xsl << xl) + ((*xsr >> xr) & xrmask);
+ *rs = (y > 0 ? (*xsl << xl) : ((*xsr >> xr) & xrmask));
+ rs += u;
+ for ( ; ++i < r->siz; rs+=u )
+ *rs = 0;
+ return r;
+}
+
+Fix::Rep*
+Fix::negate(const Rep* x, Rep* r)
+{
+ if ( r == NULL )
+ r = new_Fix(x->len);
+ _G_uint32_t carry = 1;
+ for ( int i=r->siz-1; i >= x->siz; i-- )
+ r->s[i] = 0;
+ for ( ; i >= 0; i-- )
+ {
+ _G_uint32_t a = (_G_uint16_t )~x->s[i] + carry; // bug work-around
+ r->s[i] = a;
+ carry = a >> 16;
+ }
+ return r;
+}
+
+// io functions
+
+Fix
+atoF(const char* a, int len)
+{
+ return Fix(len,atof(a));
+}
+
+extern AllocRing _libgxx_fmtq;
+
+void
+Fix::printon(ostream& s, int width) const
+{
+ double val = value(*this);
+ int old_precision = s.precision(width-3);
+ long old_flags = s.setf(ios::fixed, ios::fixed|ios::scientific);
+ if (val >= 0)
+ s << ' ';
+ s.width(width-2);
+ s << val;
+ s.precision(old_precision);
+ s.flags(old_flags);
+}
+
+char*
+Ftoa(Fix& x, int width)
+{
+ int wrksiz = width + 2;
+ char *fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ ostrstream stream(fmtbase, wrksiz);
+
+ x.printon(stream, width);
+ stream << ends;
+ return fmtbase;
+}
+
+extern Obstack _libgxx_io_ob;
+
+Fix
+Fix::operator %= (int y)
+{
+ Fix r((int )rep->len + y, *this); return *this = r;
+}
+
+istream&
+operator >> (istream& s, Fix& y)
+{
+ int got_one = 0;
+ if (!s.ipfx(0))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+
+ char sign = 0, point = 0;
+ char ch;
+ s >> ws;
+ if (!s.good())
+ {
+ s.clear(ios::failbit|s.rdstate());
+ return s;
+ }
+ while (s.get(ch))
+ {
+ if (ch == '-')
+ {
+ if (sign == 0)
+ {
+ sign = 1;
+ _libgxx_io_ob.grow(ch);
+ }
+ else
+ break;
+ }
+ if (ch == '.')
+ {
+ if (point == 0)
+ {
+ point = 1;
+ _libgxx_io_ob.grow(ch);
+ }
+ else
+ break;
+ }
+ else if (ch >= '0' && ch <= '9')
+ {
+ got_one = 1;
+ _libgxx_io_ob.grow(ch);
+ }
+ else
+ break;
+ }
+ char * p = (char*)(_libgxx_io_ob.finish(0));
+ if (s.good())
+ s.putback(ch);
+ if (!got_one)
+ s.clear(ios::failbit|s.rdstate());
+ else
+ y = atoF(p);
+ _libgxx_io_ob.free(p);
+ return s;
+}
+
+void
+show(const Fix& x)
+{
+ cout << "len = " << x.rep->len << "\n";
+ cout << "siz = " << x.rep->siz << "\n";
+ cout << "ref = " << x.rep->ref << "\n";
+ cout << "man = ";
+#ifdef _OLD_STREAMS
+ cout << Itoa(mantissa(x),16,4*x.rep->siz);
+#else
+ int old_flags = cout.setf(ios::hex, ios::hex|ios::dec|ios::oct);
+ cout.width(4*x.rep->siz);
+ cout << mantissa(x);
+ cout.setf(old_flags, ios::hex|ios::dec|ios::oct);
+#endif
+ cout << "\n";
+ cout << "val = " << value(x) << "\n";
+}
+
+// parameter setting operations
+
+Fix::PEH Fix::set_overflow_handler(PEH new_handler)
+{
+ PEH old_handler = overflow_handler;
+ overflow_handler = new_handler;
+ return old_handler;
+}
+
+int
+Fix::set_default_length(int newlen)
+{
+ _G_uint16_t oldlen = default_length;
+ if ( newlen < min_length || newlen > max_length )
+ error("illegal length in Fix::set_default_length");
+ default_length = newlen;
+ return oldlen;
+}
+
+// overflow handlers
+
+void
+Fix::overflow_saturate(Rep* r)
+{
+ if ( (_G_int16_t) r->s[0] > 0 )
+ {
+ r->s[0] = 0x8000;
+ for ( int i=1; i < r->siz; i++ )
+ r->s[i] = 0;
+ }
+ else
+ {
+ r->s[0] = 0x7fff;
+ for ( int i = 1; i < (int)r->siz; i++ )
+ r->s[i] = 0xffff;
+ mask(r);
+ }
+}
+
+void
+Fix::overflow_wrap(Rep*)
+{}
+
+void
+Fix::overflow_warning_saturate(Rep* r)
+{
+ overflow_warning(r);
+ overflow_saturate(r);
+}
+
+void
+Fix::overflow_warning(Rep*)
+{
+ cerr << "Fix: overflow warning\n";
+}
+
+void
+Fix::overflow_error(Rep*)
+{
+ cerr << "Fix: overflow error\n";
+ abort();
+}
diff --git a/gnu/lib/libg++/libg++/Fix16.cc b/gnu/lib/libg++/libg++/Fix16.cc
new file mode 100644
index 0000000..a66bfbf
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Fix16.cc
@@ -0,0 +1,238 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//
+// Fix.cc : fixed precision class support functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Fix16.h>
+
+// basic operators too large to be inline
+
+short Fix16::assign(double d)
+{
+ if (d == 1.0)
+ return Fix16_m_max;
+ else if (d > Fix16_max)
+ {
+ short i = Fix16_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix16_min)
+ {
+ short i = Fix16_m_min;
+ range_error(i);
+ return i;
+ }
+ else
+ return round(Fix16_mult * d);
+}
+
+long Fix32::assign(double d)
+{
+ if (d == 1.0)
+ return Fix32_m_max;
+ else if (d > Fix32_max)
+ {
+ long i = Fix32_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix32_min)
+ {
+ long i = Fix32_m_min;
+ range_error(i);
+ return i;
+ }
+ else
+ return round(Fix32_mult * d);
+}
+
+
+Fix32 operator * (const Fix32& a, const Fix32& b)
+{
+// break a and b into lo and hi parts, and do a multiple-precision
+// multiply, with rounding
+
+ int apos = (a.m >= 0);
+ unsigned long ua = (apos)? a.m : - a.m;
+ ua <<= 1; // ua is biased so result will be 31 bit mantissa, not 30:
+ unsigned long hi_a = (ua >> 16) & ((1 << 16) - 1);
+ unsigned long lo_a = ua & ((1 << 16) - 1);
+
+ int bpos = (b.m >= 0);
+ unsigned long ub = (bpos)? b.m : -b.m;
+ unsigned long hi_b = (ub >> 16) & ((1 << 16) - 1);
+ unsigned long lo_b = ub & ((1 << 16) - 1);
+
+ unsigned long r = lo_a * lo_b + (1 << 15);
+ r = (r >> 16) + hi_a * lo_b + lo_a * hi_b + (1 << 15);
+ r = (r >> 16) + hi_a * hi_b;
+ long p = (apos != bpos)? -r : r;
+ return Fix32(p);
+}
+
+Fix16 operator / (const Fix16& a, const Fix16& b)
+{
+ short q;
+ int apos = (a.m >= 0);
+ long la = (apos)? a.m : -a.m;
+ long scaled_a = la << 15;
+ int bpos = (b.m >= 0);
+ short sb = (bpos)? b.m: -b.m;
+ if (la >= sb)
+ {
+ q = (apos == bpos)? Fix16_m_max: Fix16_m_min;
+ a.range_error(q);
+ }
+ else
+ {
+ q = scaled_a / sb;
+ if ((scaled_a % sb) >= (sb / 2)) ++q;
+ if (apos != bpos) q = -q;
+ }
+ return Fix16(q);
+}
+
+Fix32 operator / (const Fix32& a, const Fix32& b)
+{
+ long q;
+ int apos = (a.m >= 0);
+ unsigned long la = (apos)? a.m : -a.m;
+ int bpos = (b.m >= 0);
+ unsigned long lb = (bpos)? b.m: -b.m;
+ if (la >= lb)
+ {
+ q = (apos == bpos)? Fix32_m_max: Fix32_m_min;
+ a.range_error(q);
+ }
+ else // standard shift-based division alg
+ {
+ q = 0;
+ long r = la;
+
+ for (int i = 32; i > 0; i--)
+ {
+ if ((unsigned)(r) > lb) {
+ q = (q << 1) | 1;
+ r -= lb;
+ }
+ else
+ q = (q << 1);
+ r <<= 1;
+ }
+
+ if (apos != bpos) q = -q; // Fix sign
+ }
+ return Fix32(q);
+}
+
+
+// error handling
+
+void Fix16::overflow(short& i) const
+{
+ (*Fix16_overflow_handler)(i);
+}
+
+void Fix32::overflow(long& i) const
+{
+ (*Fix32_overflow_handler)(i);
+}
+
+void Fix16::range_error(short& i) const
+{
+ (*Fix16_range_error_handler)(i);
+}
+
+void Fix32::range_error(long& i) const
+{
+ (*Fix32_range_error_handler)(i);
+}
+
+// data definitions
+
+Fix16_peh Fix16_overflow_handler = Fix16_overflow_saturate;
+Fix32_peh Fix32_overflow_handler = Fix32_overflow_saturate;
+
+Fix16_peh Fix16_range_error_handler = Fix16_warning;
+Fix32_peh Fix32_range_error_handler = Fix32_warning;
+
+//function definitions
+
+Fix16_peh set_Fix16_overflow_handler(Fix16_peh new_handler) {
+ Fix16_peh old_handler = Fix16_overflow_handler;
+ Fix16_overflow_handler = new_handler;
+ return old_handler;
+}
+
+Fix32_peh set_Fix32_overflow_handler(Fix32_peh new_handler) {
+ Fix32_peh old_handler = Fix32_overflow_handler;
+ Fix32_overflow_handler = new_handler;
+ return old_handler;
+}
+
+void set_overflow_handler(Fix16_peh handler16, Fix32_peh handler32) {
+ set_Fix16_overflow_handler(handler16);
+ set_Fix32_overflow_handler(handler32);
+}
+
+Fix16_peh set_Fix16_range_error_handler(Fix16_peh new_handler) {
+ Fix16_peh old_handler = Fix16_range_error_handler;
+ Fix16_range_error_handler = new_handler;
+ return old_handler;
+}
+
+Fix32_peh set_Fix32_range_error_handler(Fix32_peh new_handler) {
+ Fix32_peh old_handler = Fix32_range_error_handler;
+ Fix32_range_error_handler = new_handler;
+ return old_handler;
+}
+
+void set_range_error_handler(Fix16_peh handler16, Fix32_peh handler32) {
+ set_Fix16_range_error_handler(handler16);
+ set_Fix32_range_error_handler(handler32);
+}
+
+void Fix16_overflow_saturate(short& i)
+ { i = (i > 0 ? Fix16_m_min : Fix16_m_max); }
+void Fix16_ignore(short&) {}
+void Fix16_warning(short&)
+ { cerr << "warning: Fix16 result out of range\n"; }
+void Fix16_overflow_warning_saturate(short& i)
+ { cerr << "warning: Fix16 result out of range\n";
+ Fix16_overflow_saturate(i); }
+void Fix16_abort(short&)
+ { cerr << "error: Fix16 result out of range\n"; abort(); }
+
+void Fix32_ignore(long&) {}
+void Fix32_overflow_saturate(long& i)
+ { i = (i > 0 ? Fix32_m_min : Fix32_m_max); }
+void Fix32_warning(long&)
+ { cerr << "warning: Fix32 result out of range\n"; }
+void Fix32_overflow_warning_saturate(long& i)
+ { cerr << "warning: Fix32 result out of range\n";
+ Fix32_overflow_saturate(i); }
+void Fix32_abort(long&)
+ { cerr << "error: Fix32 result out of range\n"; abort(); }
+
diff --git a/gnu/lib/libg++/libg++/Fix24.cc b/gnu/lib/libg++/libg++/Fix24.cc
new file mode 100644
index 0000000..22e23dc
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Fix24.cc
@@ -0,0 +1,327 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//
+// Fix24.cc : fixed precision class support functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Fix24.h>
+
+// basic operators too large to be inline
+
+long Fix24::assign(double d)
+{
+ if (d == 1.0)
+ return Fix24_m_max;
+ else if (d > Fix24_max)
+ {
+ long i = Fix24_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix24_min)
+ {
+ long i = Fix24_m_min;
+ range_error(i);
+ return i;
+ }
+ else {
+ d = (long) (d * (1 << 24) + ((d >= 0)? 0.5 : -0.5)); // Round to 24 bits
+ return ((long) d) << (Fix24_shift - 24); /* Convert to integer format */
+ }
+}
+
+twolongs Fix48::assign(double d)
+{
+ if (d == 1.0)
+ return Fix48_m_max;
+ else if (d > Fix48_max)
+ {
+ twolongs i = Fix48_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix48_min)
+ {
+ twolongs i = Fix48_m_min;
+ range_error(i);
+ return i;
+ }
+ else {
+ twolongs i;
+ int sign = (d < 0);
+
+/* First, convert the absolute value of d to a 48-bit integer format */
+ if (d < 0) d = -d;
+ i.u = ((long)(d *= Fix24_mult)) & 0xffffff00;
+ i.l = ((unsigned long)((d - i.u)* (Fix24_mult / (1 << 7)))) & 0xffffff00;
+
+/* Calculate the two's complement if d was negative */
+ if (sign) {
+ unsigned long oldlower = i.l;
+ i.l = (~i.l + 1) & 0xffffff00;
+ i.u = (~i.u + (((oldlower ^ i.l) & Fix24_msb)? 0 : 1)) & 0xffffff00;
+ }
+ return i;
+ }
+}
+
+
+Fix48 operator * (const Fix24& a, const Fix24& b)
+{
+// break a and b into lo and hi parts, and do a multiple-precision
+// multiply, with rounding
+
+ int apos = (a.m >= 0);
+ unsigned long ua = (apos)? a.m : - a.m;
+ ua <<= 1; // ua is biased so result will be 47 bit mantissa, not 46:
+ unsigned long hi_a = (ua >> 16) & ((1 << 16) - 1);
+ unsigned long lo_a = ua & ((1 << 16) - 1);
+
+ int bpos = (b.m >= 0);
+ unsigned long ub = (bpos)? b.m : -b.m;
+ unsigned long hi_b = (ub >> 16) & ((1 << 16) - 1);
+ unsigned long lo_b = ub & ((1 << 16) - 1);
+
+ unsigned long
+ hi_r = hi_a * hi_b,
+ mi_r = hi_a * lo_b + lo_a * hi_b,
+ lo_r = lo_a * lo_b,
+ rl = ((hi_r << 16) & 0x00ffffffL) + (mi_r & 0x00ffffffL) + (lo_r >> 16);
+ twolongs r;
+ r.u = (hi_r & 0xffffff00L) + ((mi_r >> 16) & 0x0000ff00L)
+ + ((rl >> 16) & 0x0000ff00L);
+ r.l = rl << 8;
+
+ if ( apos != bpos ) {
+ unsigned long l = r.l;
+ r.l = -r.l;
+ r.u = (~r.u + ((l ^ r.l) & Fix24_msb ? 0 : Fix24_lsb)) & 0xffffff00;
+ }
+ return r;
+}
+
+Fix24 operator / (const Fix24& a, const Fix24& b)
+{
+ long q;
+ int apos = (a.m >= 0);
+ unsigned long la = (apos)? a.m : -a.m;
+ int bpos = (b.m >= 0);
+ unsigned long lb = (bpos)? b.m: -b.m;
+ if (la >= lb)
+ {
+ q = (apos == bpos)? Fix24_m_max: Fix24_m_min;
+ a.range_error(q);
+ }
+ else // standard shift-based division alg
+ {
+ q = 0;
+ long r = la;
+
+ for (int i = 32; i > 0; i--)
+ {
+ if ((unsigned)(r) > lb) {
+ q = (q << 1) | 1;
+ r -= lb;
+ }
+ else
+ q = (q << 1);
+ r <<= 1;
+ }
+
+ q += 0x80; // Round result to 24 bits
+ if (apos != bpos) q = -q; // Fix sign
+ }
+ return (q & ~0xFF);
+}
+
+
+Fix48 operator + (const Fix48& f, const Fix48& g)
+{
+ long lo_r = (f.m.l >> 8) + (g.m.l >> 8);
+ twolongs r;
+ r.u = f.m.u + g.m.u + (lo_r & 0x01000000L ? 0x00000100L : 0);
+ r.l = lo_r << 8;
+
+ if ( (f.m.u ^ r.u) & (g.m.u ^ r.u) & Fix24_msb )
+ f.overflow(r);
+ return r;
+}
+
+Fix48 operator - (const Fix48& f, const Fix48& g)
+{
+ unsigned lo_r = (f.m.l >> 8) - (g.m.l >> 8);
+ twolongs r;
+ r.u = f.m.u - g.m.u - (lo_r & 0x01000000L ? 0x00000100L: 0);
+ r.l = lo_r << 8;
+
+ if ( ((f.m.u ^ r.u) & (-g.m.u ^ r.u) & Fix24_msb) && g.m.u )
+ f.overflow(r);
+ return r;
+}
+
+Fix48 operator * (const Fix48& a, int b)
+{
+ twolongs r;
+ int bpos = (b >= 0);
+ unsigned ub = (bpos)? b : -b;
+ if ( ub >= 65536L ) {
+ r = (bpos)? Fix48_m_max : Fix48_m_min;
+ a.range_error(r);
+ }
+ else {
+ unsigned long
+ lo_r = (a.m.l & 0xffff) * ub,
+ mi_r = ((a.m.l >> 16) & 0xffff) * ub,
+ hi_r = a.m.u * ub;
+ r.l = lo_r + (mi_r << 16);
+ r.u = hi_r + ((mi_r >> 8) & 0x00ffff00L);
+ if ( !bpos ) {
+ unsigned long l = r.l;
+ r.l = -r.l;
+ r.u = ~r.u + ((l ^ r.l) & Fix24_msb ? 0 : Fix24_lsb);
+ }
+ }
+ return r;
+}
+
+Fix48 operator << (const Fix48& a, int b)
+{
+ twolongs r; r.u = 0; r.l = 0;
+ if ( b >= 0 )
+ if ( b < 24 ) {
+ r.u = (a.m.u << b) + ((a.m.l >> (24 - b)) & 0xffffff00L);
+ r.l = a.m.l << b;
+ }
+ else if ( b < 48 ) {
+ r.u = a.m.l << (b - 24);
+ }
+ return r;
+}
+
+Fix48 operator >> (const Fix48& a, int b)
+{
+ twolongs r; r.u = 0; r.l = 0;
+ if ( b >= 0 )
+ if ( b < 24 ) {
+ r.l = (a.m.u << (24 - b)) + ((a.m.l >> b) & 0xffffff00L);
+ r.u = (a.m.u >> b) & 0xffffff00L;
+ }
+ else if ( b < 48 ) {
+ r.l = (a.m.u >> (b - 24)) & 0xffffff00L;
+ r.u = (a.m.u >> 24) & 0xffffff00L;
+ }
+ else {
+ r.l = (a.m.u >> 24) & 0xffffff00L;
+ r.u = r.l;
+ }
+ return r;
+}
+
+// error handling
+
+void Fix24::overflow(long& i) const
+{
+ (*Fix24_overflow_handler)(i);
+}
+
+void Fix48::overflow(twolongs& i) const
+{
+ (*Fix48_overflow_handler)(i);
+}
+
+void Fix24::range_error(long& i) const
+{
+ (*Fix24_range_error_handler)(i);
+}
+
+void Fix48::range_error(twolongs& i) const
+{
+ (*Fix48_range_error_handler)(i);
+}
+
+// data definitions
+
+Fix24_peh Fix24_overflow_handler = Fix24_overflow_saturate;
+Fix48_peh Fix48_overflow_handler = Fix48_overflow_saturate;
+
+Fix24_peh Fix24_range_error_handler = Fix24_warning;
+Fix48_peh Fix48_range_error_handler = Fix48_warning;
+
+//function definitions
+
+Fix24_peh set_Fix24_overflow_handler(Fix24_peh new_handler) {
+ Fix24_peh old_handler = Fix24_overflow_handler;
+ Fix24_overflow_handler = new_handler;
+ return old_handler;
+}
+
+Fix48_peh set_Fix48_overflow_handler(Fix48_peh new_handler) {
+ Fix48_peh old_handler = Fix48_overflow_handler;
+ Fix48_overflow_handler = new_handler;
+ return old_handler;
+}
+
+void set_overflow_handler(Fix24_peh handler24, Fix48_peh handler48) {
+ set_Fix24_overflow_handler(handler24);
+ set_Fix48_overflow_handler(handler48);
+}
+
+Fix24_peh set_Fix24_range_error_handler(Fix24_peh new_handler) {
+ Fix24_peh old_handler = Fix24_range_error_handler;
+ Fix24_range_error_handler = new_handler;
+ return old_handler;
+}
+
+Fix48_peh set_Fix48_range_error_handler(Fix48_peh new_handler) {
+ Fix48_peh old_handler = Fix48_range_error_handler;
+ Fix48_range_error_handler = new_handler;
+ return old_handler;
+}
+
+void set_range_error_handler(Fix24_peh handler24, Fix48_peh handler48) {
+ set_Fix24_range_error_handler(handler24);
+ set_Fix48_range_error_handler(handler48);
+}
+
+void Fix24_overflow_saturate(long& i)
+ { i = (i > 0 ? Fix24_m_min : Fix24_m_max); }
+void Fix24_ignore(long&) {}
+void Fix24_warning(long&)
+ { cerr << "warning: Fix24 result out of range\n"; }
+void Fix24_overflow_warning_saturate(long& i)
+ { cerr << "warning: Fix24 result out of range\n";
+ Fix24_overflow_saturate(i); }
+void Fix24_abort(long&)
+ { cerr << "error: Fix24 result out of range\n"; abort(); }
+
+void Fix48_ignore(twolongs&) {}
+void Fix48_overflow_saturate(twolongs& i)
+ { i = (i.u > 0 ? Fix48_m_min : Fix48_m_max); }
+void Fix48_warning(twolongs&)
+ { cerr << "warning: Fix48 result out of range\n"; }
+void Fix48_overflow_warning_saturate(twolongs& i)
+ { cerr << "warning: Fix48 result out of range\n";
+ Fix48_overflow_saturate(i); }
+void Fix48_abort(twolongs&)
+ { cerr << "error: Fix48 result out of range\n"; abort(); }
+
diff --git a/gnu/lib/libg++/libg++/Geom.cc b/gnu/lib/libg++/libg++/Geom.cc
new file mode 100644
index 0000000..0353738
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Geom.cc
@@ -0,0 +1,30 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Geom.h>
+
+double Geometric::operator()()
+{
+ int samples;
+ for (samples = 1; pGenerator -> asDouble() < pMean; samples++);
+ return((double) samples);
+}
+
diff --git a/gnu/lib/libg++/libg++/GetOpt.cc b/gnu/lib/libg++/libg++/GetOpt.cc
new file mode 100644
index 0000000..16c647d
--- /dev/null
+++ b/gnu/lib/libg++/libg++/GetOpt.cc
@@ -0,0 +1,253 @@
+/*
+Getopt for GNU.
+Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+(Modified by Douglas C. Schmidt for use with GNU G++.)
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+/* AIX requires the alloca decl to be the first thing in the file. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#elif defined(sparc)
+#include <alloca.h>
+extern "C" void *__builtin_alloca(...);
+#elif defined(_AIX)
+#pragma alloca
+#else
+char *alloca ();
+#endif
+#include <GetOpt.h>
+
+char* GetOpt::nextchar = 0;
+int GetOpt::first_nonopt = 0;
+int GetOpt::last_nonopt = 0;
+
+GetOpt::GetOpt (int argc, char **argv, const char *optstring)
+ :opterr (1), nargc (argc), nargv (argv), noptstring (optstring)
+{
+ /* Initialize the internal data when the first call is made.
+ Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind = 1;
+ optarg = nextchar = 0;
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ ordering = RETURN_IN_ORDER;
+ else if (getenv ("_POSIX_OPTION_ORDER") != 0)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+}
+
+void
+GetOpt::exchange (char **argv)
+{
+ int nonopts_size
+ = (last_nonopt - first_nonopt) * sizeof (char *);
+ char **temp = (char **) alloca (nonopts_size);
+
+ /* Interchange the two blocks of data in argv. */
+
+ memcpy (temp, &argv[first_nonopt], nonopts_size);
+ memcpy (&argv[first_nonopt], &argv[last_nonopt],
+ (optind - last_nonopt) * sizeof (char *));
+ memcpy (&argv[first_nonopt + optind - last_nonopt], temp,
+ nonopts_size);
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of theoption characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns `EOF'.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ A colon in OPTSTRING means that the previous character is an option
+ that wants an argument. The argument is taken from the rest of the
+ current ARGV-element, or from the following ARGV-element,
+ and returned in `optarg'.
+
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg'.
+
+ If OPTSTRING starts with `-', it requests a different method of handling the
+ non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
+
+int
+GetOpt::operator () (void)
+{
+ if (nextchar == 0 || *nextchar == 0)
+ {
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange (nargv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Now skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < nargc
+ && (nargv[optind][0] != '-'
+ || nargv[optind][1] == 0))
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* Special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != nargc && !strcmp (nargv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange (nargv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = nargc;
+
+ optind = nargc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == nargc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return EOF;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (nargv[optind][0] != '-' || nargv[optind][1] == 0)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return EOF;
+ optarg = nargv[optind++];
+ return 0;
+ }
+
+ /* We have found another option-ARGV-element.
+ Start decoding its characters. */
+
+ nextchar = nargv[optind] + 1;
+ }
+
+ /* Look at and handle the next option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = (char *) strchr (noptstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == 0)
+ optind++;
+
+ if (temp == 0 || c == ':')
+ {
+ if (opterr != 0)
+ {
+ if (c < 040 || c >= 0177)
+ fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+ nargv[0], c);
+ else
+ fprintf (stderr, "%s: unrecognized option `-%c'\n",
+ nargv[0], c);
+ }
+ return '?';
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != 0)
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = 0;
+ nextchar = 0;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != 0)
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == nargc)
+ {
+ if (opterr != 0)
+ fprintf (stderr, "%s: no argument for `-%c' option\n",
+ nargv[0], c);
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = nargv[optind++];
+ nextchar = 0;
+ }
+ }
+ return c;
+ }
+}
diff --git a/gnu/lib/libg++/libg++/HypGeom.cc b/gnu/lib/libg++/libg++/HypGeom.cc
new file mode 100644
index 0000000..50d9586
--- /dev/null
+++ b/gnu/lib/libg++/libg++/HypGeom.cc
@@ -0,0 +1,30 @@
+
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <HypGeom.h>
+
+double HyperGeometric::operator()()
+{
+ double d = (pGenerator -> asDouble() > pP) ? (1.0 - pP) : (pP);
+ return(-pMean * log(pGenerator -> asDouble()) / (2.0 * d) );
+}
+
diff --git a/gnu/lib/libg++/libg++/Intdouble.cc b/gnu/lib/libg++/libg++/Intdouble.cc
new file mode 100644
index 0000000..8db9061
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Intdouble.cc
@@ -0,0 +1,142 @@
+/*
+Copyright (C) 1988, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+// Routines for converting between Integers and doubles.
+// Split up into a separate file to avoid Integer.o's need
+// for libm.a on some systems (including SunOS 4).
+
+#include <Integer.h>
+#include "Integer.hP"
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+
+#ifndef HUGE_VAL
+#ifdef HUGE
+#define HUGE_VAL HUGE
+#else
+#define HUGE_VAL DBL_MAX
+#endif
+#endif
+
+// convert to a double
+
+double Itodouble(const IntRep* rep)
+{
+ double d = 0.0;
+ double bound = DBL_MAX / 2.0;
+ for (int i = rep->len - 1; i >= 0; --i)
+ {
+ unsigned short a = I_RADIX >> 1;
+ while (a != 0)
+ {
+ if (d >= bound)
+ return (rep->sgn == I_NEGATIVE) ? -HUGE_VAL : HUGE_VAL;
+ d *= 2.0;
+ if (rep->s[i] & a)
+ d += 1.0;
+ a >>= 1;
+ }
+ }
+ if (rep->sgn == I_NEGATIVE)
+ return -d;
+ else
+ return d;
+}
+
+// see whether op double() will work-
+// have to actually try it in order to find out
+// since otherwise might trigger fp exception
+
+int Iisdouble(const IntRep* rep)
+{
+ double d = 0.0;
+ double bound = DBL_MAX / 2.0;
+ for (int i = rep->len - 1; i >= 0; --i)
+ {
+ unsigned short a = I_RADIX >> 1;
+ while (a != 0)
+ {
+ if (d > bound || (d == bound && (i > 0 || (rep->s[i] & a))))
+ return 0;
+ d *= 2.0;
+ if (rep->s[i] & a)
+ d += 1.0;
+ a >>= 1;
+ }
+ }
+ return 1;
+}
+
+// real division of num / den
+
+double ratio(const Integer& num, const Integer& den)
+{
+ Integer q, r;
+ divide(num, den, q, r);
+ double d1 = q.as_double();
+
+ if (d1 >= DBL_MAX || d1 <= -DBL_MAX || sign(r) == 0)
+ return d1;
+ else // use as much precision as available for fractional part
+ {
+ double d2 = 0.0;
+ double d3 = 0.0;
+ int cont = 1;
+ for (int i = den.rep->len - 1; i >= 0 && cont; --i)
+ {
+ unsigned short a = I_RADIX >> 1;
+ while (a != 0)
+ {
+ if (d2 + 1.0 == d2) // out of precision when we get here
+ {
+ cont = 0;
+ break;
+ }
+
+ d2 *= 2.0;
+ if (den.rep->s[i] & a)
+ d2 += 1.0;
+
+ if (i < r.rep->len)
+ {
+ d3 *= 2.0;
+ if (r.rep->s[i] & a)
+ d3 += 1.0;
+ }
+
+ a >>= 1;
+ }
+ }
+
+ if (sign(r) < 0)
+ d3 = -d3;
+ return d1 + d3 / d2;
+ }
+}
+
+double
+Integer::as_double () const
+{
+ return Itodouble (rep);
+}
+
+int
+Integer::fits_in_double () const
+{
+ return Iisdouble(rep);
+}
diff --git a/gnu/lib/libg++/libg++/Integer.cc b/gnu/lib/libg++/libg++/Integer.cc
new file mode 100644
index 0000000..5f11e6d
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Integer.cc
@@ -0,0 +1,2280 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ Some of the following algorithms are very loosely based on those from
+ MIT C-Scheme bignum.c, which is
+ Copyright (c) 1987 Massachusetts Institute of Technology
+
+ with other guidance from Knuth, vol. 2
+
+ Thanks to the creators of the algorithms.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Integer.h>
+#include <std.h>
+#include <ctype.h>
+#include <limits.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <new.h>
+#include <builtin.h>
+#include "Integer.hP"
+
+IntRep _ZeroRep = {1, 0, 1, {0}};
+IntRep _OneRep = {1, 0, 1, {1}};
+IntRep _MinusOneRep = {1, 0, 0, {1}};
+
+
+// utilities to extract and transfer bits
+
+// get low bits
+
+inline static unsigned short extract(unsigned long x)
+{
+ return x & I_MAXNUM;
+}
+
+// transfer high bits to low
+
+inline static unsigned long down(unsigned long x)
+{
+ return (x >> I_SHIFT) & I_MAXNUM;
+}
+
+// transfer low bits to high
+
+inline static unsigned long up(unsigned long x)
+{
+ return x << I_SHIFT;
+}
+
+// compare two equal-length reps
+
+inline static int docmp(const unsigned short* x, const unsigned short* y, int l)
+{
+ int diff = 0;
+ const unsigned short* xs = &(x[l]);
+ const unsigned short* ys = &(y[l]);
+ while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
+ return diff;
+}
+
+// figure out max length of result of +, -, etc.
+
+inline static int calc_len(int len1, int len2, int pad)
+{
+ return (len1 >= len2)? len1 + pad : len2 + pad;
+}
+
+// ensure len & sgn are correct
+
+inline static void Icheck(IntRep* rep)
+{
+ int l = rep->len;
+ const unsigned short* p = &(rep->s[l]);
+ while (l > 0 && *--p == 0) --l;
+ if ((rep->len = l) == 0) rep->sgn = I_POSITIVE;
+}
+
+
+// zero out the end of a rep
+
+inline static void Iclear_from(IntRep* rep, int p)
+{
+ unsigned short* cp = &(rep->s[p]);
+ const unsigned short* cf = &(rep->s[rep->len]);
+ while(cp < cf) *cp++ = 0;
+}
+
+// copy parts of a rep
+
+static inline void scpy(const unsigned short* src, unsigned short* dest,int nb)
+{
+ while (--nb >= 0) *dest++ = *src++;
+}
+
+// make sure an argument is valid
+
+static inline void nonnil(const IntRep* rep)
+{
+ if (rep == 0)
+ (*lib_error_handler)("Integer", "operation on uninitialized Integer");
+}
+
+// allocate a new Irep. Pad to something close to a power of two.
+
+inline static IntRep* Inew(int newlen)
+{
+ unsigned int siz = sizeof(IntRep) + newlen * sizeof(short) +
+ MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINIntRep_SIZE;
+ while (allocsiz < siz) allocsiz <<= 1; // find a power of 2
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXIntRep_SIZE * sizeof(short))
+ (*lib_error_handler)("Integer", "Requested length out of range");
+
+ IntRep* rep = (IntRep *) new char[allocsiz];
+ rep->sz = (allocsiz - sizeof(IntRep) + sizeof(short)) / sizeof(short);
+ return rep;
+}
+
+// allocate: use the bits in src if non-null, clear the rest
+
+IntRep* Ialloc(IntRep* old, const unsigned short* src, int srclen, int newsgn,
+ int newlen)
+{
+ IntRep* rep;
+ if (old == 0 || newlen > old->sz)
+ rep = Inew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->sgn = newsgn;
+
+ scpy(src, rep->s, srclen);
+ Iclear_from(rep, srclen);
+
+ if (old != rep && old != 0 && !STATIC_IntRep(old)) delete old;
+ return rep;
+}
+
+// allocate and clear
+
+IntRep* Icalloc(IntRep* old, int newlen)
+{
+ IntRep* rep;
+ if (old == 0 || newlen > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ rep = Inew(newlen);
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->sgn = I_POSITIVE;
+ Iclear_from(rep, 0);
+
+ return rep;
+}
+
+// reallocate
+
+IntRep* Iresize(IntRep* old, int newlen)
+{
+ IntRep* rep;
+ unsigned short oldlen;
+ if (old == 0)
+ {
+ oldlen = 0;
+ rep = Inew(newlen);
+ rep->sgn = I_POSITIVE;
+ }
+ else
+ {
+ oldlen = old->len;
+ if (newlen > old->sz)
+ {
+ rep = Inew(newlen);
+ scpy(old->s, rep->s, oldlen);
+ rep->sgn = old->sgn;
+ if (!STATIC_IntRep(old)) delete old;
+ }
+ else
+ rep = old;
+ }
+
+ rep->len = newlen;
+ Iclear_from(rep, oldlen);
+
+ return rep;
+}
+
+
+// same, for straight copy
+
+IntRep* Icopy(IntRep* old, const IntRep* src)
+{
+ if (old == src) return old;
+ IntRep* rep;
+ if (src == 0)
+ {
+ if (old == 0)
+ rep = Inew(0);
+ else
+ {
+ rep = old;
+ Iclear_from(rep, 0);
+ }
+ rep->len = 0;
+ rep->sgn = I_POSITIVE;
+ }
+ else
+ {
+ int newlen = src->len;
+ if (old == 0 || newlen > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ rep = Inew(newlen);
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->sgn = src->sgn;
+
+ scpy(src->s, rep->s, newlen);
+ }
+
+ return rep;
+}
+
+// allocate & copy space for a long
+
+IntRep* Icopy_long(IntRep* old, long x)
+{
+ int newsgn = (x >= 0);
+ IntRep* rep = Icopy_ulong(old, newsgn ? x : -x);
+ rep->sgn = newsgn;
+ return rep;
+}
+
+IntRep* Icopy_ulong(IntRep* old, unsigned long x)
+{
+ unsigned short src[SHORT_PER_LONG];
+
+ unsigned short srclen = 0;
+ while (x != 0)
+ {
+ src[srclen++] = extract(x);
+ x = down(x);
+ }
+
+ IntRep* rep;
+ if (old == 0 || srclen > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ rep = Inew(srclen);
+ }
+ else
+ rep = old;
+
+ rep->len = srclen;
+ rep->sgn = I_POSITIVE;
+
+ scpy(src, rep->s, srclen);
+
+ return rep;
+}
+
+// special case for zero -- it's worth it!
+
+IntRep* Icopy_zero(IntRep* old)
+{
+ if (old == 0 || STATIC_IntRep(old))
+ return &_ZeroRep;
+
+ old->len = 0;
+ old->sgn = I_POSITIVE;
+
+ return old;
+}
+
+// special case for 1 or -1
+
+IntRep* Icopy_one(IntRep* old, int newsgn)
+{
+ if (old == 0 || 1 > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ return newsgn==I_NEGATIVE ? &_MinusOneRep : &_OneRep;
+ }
+
+ old->sgn = newsgn;
+ old->len = 1;
+ old->s[0] = 1;
+
+ return old;
+}
+
+// convert to a legal two's complement long if possible
+// if too big, return most negative/positive value
+
+long Itolong(const IntRep* rep)
+{
+ if ((unsigned)(rep->len) > (unsigned)(SHORT_PER_LONG))
+ return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
+ else if (rep->len == 0)
+ return 0;
+ else if ((unsigned)(rep->len) < (unsigned)(SHORT_PER_LONG))
+ {
+ unsigned long a = rep->s[rep->len-1];
+ if (SHORT_PER_LONG > 2) // normally optimized out
+ {
+ for (int i = rep->len - 2; i >= 0; --i)
+ a = up(a) | rep->s[i];
+ }
+ return (rep->sgn == I_POSITIVE)? a : -((long)a);
+ }
+ else
+ {
+ unsigned long a = rep->s[SHORT_PER_LONG - 1];
+ if (a >= I_MINNUM)
+ return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
+ else
+ {
+ a = up(a) | rep->s[SHORT_PER_LONG - 2];
+ if (SHORT_PER_LONG > 2)
+ {
+ for (int i = SHORT_PER_LONG - 3; i >= 0; --i)
+ a = up(a) | rep->s[i];
+ }
+ return (rep->sgn == I_POSITIVE)? a : -((long)a);
+ }
+ }
+}
+
+// test whether op long() will work.
+// careful about asymmetry between LONG_MIN & LONG_MAX
+
+int Iislong(const IntRep* rep)
+{
+ unsigned int l = rep->len;
+ if (l < SHORT_PER_LONG)
+ return 1;
+ else if (l > SHORT_PER_LONG)
+ return 0;
+ else if ((unsigned)(rep->s[SHORT_PER_LONG - 1]) < (unsigned)(I_MINNUM))
+ return 1;
+ else if (rep->sgn == I_NEGATIVE && rep->s[SHORT_PER_LONG - 1] == I_MINNUM)
+ {
+ for (unsigned int i = 0; i < SHORT_PER_LONG - 1; ++i)
+ if (rep->s[i] != 0)
+ return 0;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+// comparison functions
+
+int compare(const IntRep* x, const IntRep* y)
+{
+ int diff = x->sgn - y->sgn;
+ if (diff == 0)
+ {
+ diff = x->len - y->len;
+ if (diff == 0)
+ diff = docmp(x->s, y->s, x->len);
+ if (x->sgn == I_NEGATIVE)
+ diff = -diff;
+ }
+ return diff;
+}
+
+int ucompare(const IntRep* x, const IntRep* y)
+{
+ int diff = x->len - y->len;
+ if (diff == 0)
+ {
+ int l = x->len;
+ const unsigned short* xs = &(x->s[l]);
+ const unsigned short* ys = &(y->s[l]);
+ while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
+ }
+ return diff;
+}
+
+int compare(const IntRep* x, long y)
+{
+ int xl = x->len;
+ int xsgn = x->sgn;
+ if (y == 0)
+ {
+ if (xl == 0)
+ return 0;
+ else if (xsgn == I_NEGATIVE)
+ return -1;
+ else
+ return 1;
+ }
+ else
+ {
+ int ysgn = y >= 0;
+ unsigned long uy = (ysgn)? y : -y;
+ int diff = xsgn - ysgn;
+ if (diff == 0)
+ {
+ diff = xl - SHORT_PER_LONG;
+ if (diff <= 0)
+ {
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+ diff = xl - yl;
+ if (diff == 0)
+ diff = docmp(x->s, tmp, xl);
+ }
+ if (xsgn == I_NEGATIVE)
+ diff = -diff;
+ }
+ return diff;
+ }
+}
+
+int ucompare(const IntRep* x, long y)
+{
+ int xl = x->len;
+ if (y == 0)
+ return xl;
+ else
+ {
+ unsigned long uy = (y >= 0)? y : -y;
+ int diff = xl - SHORT_PER_LONG;
+ if (diff <= 0)
+ {
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+ diff = xl - yl;
+ if (diff == 0)
+ diff = docmp(x->s, tmp, xl);
+ }
+ return diff;
+ }
+}
+
+
+
+// arithmetic functions
+
+IntRep* add(const IntRep* x, int negatex,
+ const IntRep* y, int negatey, IntRep* r)
+{
+ nonnil(x);
+ nonnil(y);
+
+ int xl = x->len;
+ int yl = y->len;
+
+ int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
+ int ysgn = (negatey && yl != 0) ? !y->sgn : y->sgn;
+
+ int xrsame = x == r;
+ int yrsame = y == r;
+
+ if (yl == 0)
+ r = Ialloc(r, x->s, xl, xsgn, xl);
+ else if (xl == 0)
+ r = Ialloc(r, y->s, yl, ysgn, yl);
+ else if (xsgn == ysgn)
+ {
+ if (xrsame || yrsame)
+ r = Iresize(r, calc_len(xl, yl, 1));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 1));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topa;
+ const unsigned short* topb;
+ if (xl >= yl)
+ {
+ as = (xrsame)? r->s : x->s;
+ topa = &(as[xl]);
+ bs = (yrsame)? r->s : y->s;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ bs = (xrsame)? r->s : x->s;
+ topb = &(bs[xl]);
+ as = (yrsame)? r->s : y->s;
+ topa = &(as[yl]);
+ }
+ unsigned long sum = 0;
+ while (bs < topb)
+ {
+ sum += (unsigned long)(*as++) + (unsigned long)(*bs++);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && as < topa)
+ {
+ sum += (unsigned long)(*as++);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ if (sum != 0)
+ *rs = extract(sum);
+ else if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ else
+ {
+ int comp = ucompare(x, y);
+ if (comp == 0)
+ r = Icopy_zero(r);
+ else
+ {
+ if (xrsame || yrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ unsigned short* rs = r->s;
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topa;
+ const unsigned short* topb;
+ if (comp > 0)
+ {
+ as = (xrsame)? r->s : x->s;
+ topa = &(as[xl]);
+ bs = (yrsame)? r->s : y->s;
+ topb = &(bs[yl]);
+ r->sgn = xsgn;
+ }
+ else
+ {
+ bs = (xrsame)? r->s : x->s;
+ topb = &(bs[xl]);
+ as = (yrsame)? r->s : y->s;
+ topa = &(as[yl]);
+ r->sgn = ysgn;
+ }
+ unsigned long hi = 1;
+ while (bs < topb)
+ {
+ hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ while (hi == 0 && as < topa)
+ {
+ hi = (unsigned long)(*as++) + I_MAXNUM;
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+
+IntRep* add(const IntRep* x, int negatex, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+ int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
+ int xrsame = x == r;
+
+ int ysgn = (y >= 0);
+ unsigned long uy = (ysgn)? y : -y;
+
+ if (y == 0)
+ r = Ialloc(r, x->s, xl, xsgn, xl);
+ else if (xl == 0)
+ r = Icopy_long(r, y);
+ else if (xsgn == ysgn)
+ {
+ if (xrsame)
+ r = Iresize(r, calc_len(xl, SHORT_PER_LONG, 1));
+ else
+ r = Icalloc(r, calc_len(xl, SHORT_PER_LONG, 1));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ const unsigned short* as = (xrsame)? r->s : x->s;
+ const unsigned short* topa = &(as[xl]);
+ unsigned long sum = 0;
+ while (as < topa && uy != 0)
+ {
+ unsigned long u = extract(uy);
+ uy = down(uy);
+ sum += (unsigned long)(*as++) + u;
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && as < topa)
+ {
+ sum += (unsigned long)(*as++);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ if (sum != 0)
+ *rs = extract(sum);
+ else if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ else
+ {
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+ int comp = xl - yl;
+ if (comp == 0)
+ comp = docmp(x->s, tmp, yl);
+ if (comp == 0)
+ r = Icopy_zero(r);
+ else
+ {
+ if (xrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ unsigned short* rs = r->s;
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topa;
+ const unsigned short* topb;
+ if (comp > 0)
+ {
+ as = (xrsame)? r->s : x->s;
+ topa = &(as[xl]);
+ bs = tmp;
+ topb = &(bs[yl]);
+ r->sgn = xsgn;
+ }
+ else
+ {
+ bs = (xrsame)? r->s : x->s;
+ topb = &(bs[xl]);
+ as = tmp;
+ topa = &(as[yl]);
+ r->sgn = ysgn;
+ }
+ unsigned long hi = 1;
+ while (bs < topb)
+ {
+ hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ while (hi == 0 && as < topa)
+ {
+ hi = (unsigned long)(*as++) + I_MAXNUM;
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+
+IntRep* multiply(const IntRep* x, const IntRep* y, IntRep* r)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ int rl = xl + yl;
+ int rsgn = x->sgn == y->sgn;
+ int xrsame = x == r;
+ int yrsame = y == r;
+ int xysame = x == y;
+
+ if (xl == 0 || yl == 0)
+ r = Icopy_zero(r);
+ else if (xl == 1 && x->s[0] == 1)
+ r = Icopy(r, y);
+ else if (yl == 1 && y->s[0] == 1)
+ r = Icopy(r, x);
+ else if (!(xysame && xrsame))
+ {
+ if (xrsame || yrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+
+ // use best inner/outer loop params given constraints
+ unsigned short* currentr;
+ const unsigned short* bota;
+ const unsigned short* as;
+ const unsigned short* botb;
+ const unsigned short* topb;
+ if (xrsame)
+ {
+ currentr = &(rs[xl-1]);
+ bota = rs;
+ as = currentr;
+ botb = y->s;
+ topb = &(botb[yl]);
+ }
+ else if (yrsame)
+ {
+ currentr = &(rs[yl-1]);
+ bota = rs;
+ as = currentr;
+ botb = x->s;
+ topb = &(botb[xl]);
+ }
+ else if (xl <= yl)
+ {
+ currentr = &(rs[xl-1]);
+ bota = x->s;
+ as = &(bota[xl-1]);
+ botb = y->s;
+ topb = &(botb[yl]);
+ }
+ else
+ {
+ currentr = &(rs[yl-1]);
+ bota = y->s;
+ as = &(bota[yl-1]);
+ botb = x->s;
+ topb = &(botb[xl]);
+ }
+
+ while (as >= bota)
+ {
+ unsigned long ai = (unsigned long)(*as--);
+ unsigned short* rs = currentr--;
+ *rs = 0;
+ if (ai != 0)
+ {
+ unsigned long sum = 0;
+ const unsigned short* bs = botb;
+ while (bs < topb)
+ {
+ sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && rs < topr)
+ {
+ sum += (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ }
+ }
+ }
+ else // x, y, and r same; compute over diagonals
+ {
+ r = Iresize(r, rl);
+ unsigned short* botr = r->s;
+ unsigned short* topr = &(botr[rl]);
+ unsigned short* rs = &(botr[rl - 2]);
+
+ const unsigned short* bota = (xrsame)? botr : x->s;
+ const unsigned short* loa = &(bota[xl - 1]);
+ const unsigned short* hia = loa;
+
+ for (; rs >= botr; --rs)
+ {
+ const unsigned short* h = hia;
+ const unsigned short* l = loa;
+ unsigned long prod = (unsigned long)(*h) * (unsigned long)(*l);
+ *rs = 0;
+
+ for(;;)
+ {
+ unsigned short* rt = rs;
+ unsigned long sum = prod + (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ while (sum != 0 && rt < topr)
+ {
+ sum += (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ }
+ if (h > l)
+ {
+ rt = rs;
+ sum = prod + (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ while (sum != 0 && rt < topr)
+ {
+ sum += (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ }
+ if (--h >= ++l)
+ prod = (unsigned long)(*h) * (unsigned long)(*l);
+ else
+ break;
+ }
+ else
+ break;
+ }
+ if (loa > bota)
+ --loa;
+ else
+ --hia;
+ }
+ }
+ r->sgn = rsgn;
+ Icheck(r);
+ return r;
+}
+
+
+IntRep* multiply(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+
+ if (xl == 0 || y == 0)
+ r = Icopy_zero(r);
+ else if (y == 1)
+ r = Icopy(r, x);
+ else
+ {
+ int ysgn = y >= 0;
+ int rsgn = x->sgn == ysgn;
+ unsigned long uy = (ysgn)? y : -y;
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+
+ int rl = xl + yl;
+ int xrsame = x == r;
+ if (xrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+ unsigned short* currentr;
+ const unsigned short* bota;
+ const unsigned short* as;
+ const unsigned short* botb;
+ const unsigned short* topb;
+
+ if (xrsame)
+ {
+ currentr = &(rs[xl-1]);
+ bota = rs;
+ as = currentr;
+ botb = tmp;
+ topb = &(botb[yl]);
+ }
+ else if (xl <= yl)
+ {
+ currentr = &(rs[xl-1]);
+ bota = x->s;
+ as = &(bota[xl-1]);
+ botb = tmp;
+ topb = &(botb[yl]);
+ }
+ else
+ {
+ currentr = &(rs[yl-1]);
+ bota = tmp;
+ as = &(bota[yl-1]);
+ botb = x->s;
+ topb = &(botb[xl]);
+ }
+
+ while (as >= bota)
+ {
+ unsigned long ai = (unsigned long)(*as--);
+ unsigned short* rs = currentr--;
+ *rs = 0;
+ if (ai != 0)
+ {
+ unsigned long sum = 0;
+ const unsigned short* bs = botb;
+ while (bs < topb)
+ {
+ sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && rs < topr)
+ {
+ sum += (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ }
+ }
+ r->sgn = rsgn;
+ }
+ Icheck(r);
+ return r;
+}
+
+
+// main division routine
+
+static void do_divide(unsigned short* rs,
+ const unsigned short* ys, int yl,
+ unsigned short* qs, int ql)
+{
+ const unsigned short* topy = &(ys[yl]);
+ unsigned short d1 = ys[yl - 1];
+ unsigned short d2 = ys[yl - 2];
+
+ int l = ql - 1;
+ int i = l + yl;
+
+ for (; l >= 0; --l, --i)
+ {
+ unsigned short qhat; // guess q
+ if (d1 == rs[i])
+ qhat = I_MAXNUM;
+ else
+ {
+ unsigned long lr = up((unsigned long)rs[i]) | rs[i-1];
+ qhat = lr / d1;
+ }
+
+ for(;;) // adjust q, use docmp to avoid overflow problems
+ {
+ unsigned short ts[3];
+ unsigned long prod = (unsigned long)d2 * (unsigned long)qhat;
+ ts[0] = extract(prod);
+ prod = down(prod) + (unsigned long)d1 * (unsigned long)qhat;
+ ts[1] = extract(prod);
+ ts[2] = extract(down(prod));
+ if (docmp(ts, &(rs[i-2]), 3) > 0)
+ --qhat;
+ else
+ break;
+ };
+
+ // multiply & subtract
+
+ const unsigned short* yt = ys;
+ unsigned short* rt = &(rs[l]);
+ unsigned long prod = 0;
+ unsigned long hi = 1;
+ while (yt < topy)
+ {
+ prod = (unsigned long)qhat * (unsigned long)(*yt++) + down(prod);
+ hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(extract(prod));
+ *rt++ = extract(hi);
+ hi = down(hi);
+ }
+ hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(down(prod));
+ *rt = extract(hi);
+ hi = down(hi);
+
+ // off-by-one, add back
+
+ if (hi == 0)
+ {
+ --qhat;
+ yt = ys;
+ rt = &(rs[l]);
+ hi = 0;
+ while (yt < topy)
+ {
+ hi = (unsigned long)(*rt) + (unsigned long)(*yt++) + down(hi);
+ *rt++ = extract(hi);
+ }
+ *rt = 0;
+ }
+ if (qs != 0)
+ qs[l] = qhat;
+ }
+}
+
+// divide by single digit, return remainder
+// if q != 0, then keep the result in q, else just compute rem
+
+static int unscale(const unsigned short* x, int xl, unsigned short y,
+ unsigned short* q)
+{
+ if (xl == 0 || y == 1)
+ return 0;
+ else if (q != 0)
+ {
+ unsigned short* botq = q;
+ unsigned short* qs = &(botq[xl - 1]);
+ const unsigned short* xs = &(x[xl - 1]);
+ unsigned long rem = 0;
+ while (qs >= botq)
+ {
+ rem = up(rem) | *xs--;
+ unsigned long u = rem / y;
+ *qs-- = extract(u);
+ rem -= u * y;
+ }
+ int r = extract(rem);
+ return r;
+ }
+ else // same loop, a bit faster if just need rem
+ {
+ const unsigned short* botx = x;
+ const unsigned short* xs = &(botx[xl - 1]);
+ unsigned long rem = 0;
+ while (xs >= botx)
+ {
+ rem = up(rem) | *xs--;
+ unsigned long u = rem / y;
+ rem -= u * y;
+ }
+ int r = extract(rem);
+ return r;
+ }
+}
+
+
+IntRep* div(const IntRep* x, const IntRep* y, IntRep* q)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ int comp = ucompare(x, y);
+ int xsgn = x->sgn;
+ int ysgn = y->sgn;
+
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ q = Icopy_zero(q);
+ else if (comp == 0)
+ q = Icopy_one(q, samesign);
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ unscale(q->s, q->len, y->s[0], q->s);
+ }
+ else
+ {
+ IntRep* yy = 0;
+ IntRep* r = 0;
+ unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
+ if (prescale != 1 || y == q)
+ {
+ yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ yy = (IntRep*)y;
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+ do_divide(r->s, yy->s, yl, q->s, ql);
+
+ if (yy != y && !STATIC_IntRep(yy)) delete yy;
+ if (!STATIC_IntRep(r)) delete r;
+ }
+ q->sgn = samesign;
+ Icheck(q);
+ return q;
+}
+
+IntRep* div(const IntRep* x, long y, IntRep* q)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ unsigned short ys[SHORT_PER_LONG];
+ unsigned long u;
+ int ysgn = y >= 0;
+ if (ysgn)
+ u = y;
+ else
+ u = -y;
+ int yl = 0;
+ while (u != 0)
+ {
+ ys[yl++] = extract(u);
+ u = down(u);
+ }
+
+ int comp = xl - yl;
+ if (comp == 0) comp = docmp(x->s, ys, xl);
+
+ int xsgn = x->sgn;
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ q = Icopy_zero(q);
+ else if (comp == 0)
+ {
+ q = Icopy_one(q, samesign);
+ }
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ unscale(q->s, q->len, ys[0], q->s);
+ }
+ else
+ {
+ IntRep* r = 0;
+ unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
+ if (prescale != 1)
+ {
+ unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
+ ys[0] = extract(prod);
+ prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
+ ys[1] = extract(prod);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+ do_divide(r->s, ys, yl, q->s, ql);
+
+ if (!STATIC_IntRep(r)) delete r;
+ }
+ q->sgn = samesign;
+ Icheck(q);
+ return q;
+}
+
+
+void divide(const Integer& Ix, long y, Integer& Iq, long& rem)
+{
+ const IntRep* x = Ix.rep;
+ nonnil(x);
+ IntRep* q = Iq.rep;
+ int xl = x->len;
+ if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ unsigned short ys[SHORT_PER_LONG];
+ unsigned long u;
+ int ysgn = y >= 0;
+ if (ysgn)
+ u = y;
+ else
+ u = -y;
+ int yl = 0;
+ while (u != 0)
+ {
+ ys[yl++] = extract(u);
+ u = down(u);
+ }
+
+ int comp = xl - yl;
+ if (comp == 0) comp = docmp(x->s, ys, xl);
+
+ int xsgn = x->sgn;
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ {
+ rem = Itolong(x);
+ q = Icopy_zero(q);
+ }
+ else if (comp == 0)
+ {
+ q = Icopy_one(q, samesign);
+ rem = 0;
+ }
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ rem = unscale(q->s, q->len, ys[0], q->s);
+ }
+ else
+ {
+ IntRep* r = 0;
+ unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
+ if (prescale != 1)
+ {
+ unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
+ ys[0] = extract(prod);
+ prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
+ ys[1] = extract(prod);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+
+ do_divide(r->s, ys, yl, q->s, ql);
+
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ Icheck(r);
+ rem = Itolong(r);
+ if (!STATIC_IntRep(r)) delete r;
+ }
+ rem = abs(rem);
+ if (xsgn == I_NEGATIVE) rem = -rem;
+ q->sgn = samesign;
+ Icheck(q);
+ Iq.rep = q;
+}
+
+
+void divide(const Integer& Ix, const Integer& Iy, Integer& Iq, Integer& Ir)
+{
+ const IntRep* x = Ix.rep;
+ nonnil(x);
+ const IntRep* y = Iy.rep;
+ nonnil(y);
+ IntRep* q = Iq.rep;
+ IntRep* r = Ir.rep;
+
+ int xl = x->len;
+ int yl = y->len;
+ if (yl == 0)
+ (*lib_error_handler)("Integer", "attempted division by zero");
+
+ int comp = ucompare(x, y);
+ int xsgn = x->sgn;
+ int ysgn = y->sgn;
+
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ {
+ q = Icopy_zero(q);
+ r = Icopy(r, x);
+ }
+ else if (comp == 0)
+ {
+ q = Icopy_one(q, samesign);
+ r = Icopy_zero(r);
+ }
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ int rem = unscale(q->s, q->len, y->s[0], q->s);
+ r = Icopy_long(r, rem);
+ if (rem != 0)
+ r->sgn = xsgn;
+ }
+ else
+ {
+ IntRep* yy = 0;
+ unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
+ if (prescale != 1 || y == q || y == r)
+ {
+ yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ yy = (IntRep*)y;
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+ do_divide(r->s, yy->s, yl, q->s, ql);
+
+ if (yy != y && !STATIC_IntRep(yy)) delete yy;
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ }
+ q->sgn = samesign;
+ Icheck(q);
+ Iq.rep = q;
+ Icheck(r);
+ Ir.rep = r;
+}
+
+IntRep* mod(const IntRep* x, const IntRep* y, IntRep* r)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ int comp = ucompare(x, y);
+ int xsgn = x->sgn;
+
+ if (comp < 0)
+ r = Icopy(r, x);
+ else if (comp == 0)
+ r = Icopy_zero(r);
+ else if (yl == 1)
+ {
+ int rem = unscale(x->s, xl, y->s[0], 0);
+ r = Icopy_long(r, rem);
+ if (rem != 0)
+ r->sgn = xsgn;
+ }
+ else
+ {
+ IntRep* yy = 0;
+ unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
+ if (prescale != 1 || y == r)
+ {
+ yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ yy = (IntRep*)y;
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ do_divide(r->s, yy->s, yl, 0, xl - yl + 1);
+
+ if (yy != y && !STATIC_IntRep(yy)) delete yy;
+
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+IntRep* mod(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ unsigned short ys[SHORT_PER_LONG];
+ unsigned long u;
+ int ysgn = y >= 0;
+ if (ysgn)
+ u = y;
+ else
+ u = -y;
+ int yl = 0;
+ while (u != 0)
+ {
+ ys[yl++] = extract(u);
+ u = down(u);
+ }
+
+ int comp = xl - yl;
+ if (comp == 0) comp = docmp(x->s, ys, xl);
+
+ int xsgn = x->sgn;
+
+ if (comp < 0)
+ r = Icopy(r, x);
+ else if (comp == 0)
+ r = Icopy_zero(r);
+ else if (yl == 1)
+ {
+ int rem = unscale(x->s, xl, ys[0], 0);
+ r = Icopy_long(r, rem);
+ if (rem != 0)
+ r->sgn = xsgn;
+ }
+ else
+ {
+ unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
+ if (prescale != 1)
+ {
+ unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
+ ys[0] = extract(prod);
+ prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
+ ys[1] = extract(prod);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ do_divide(r->s, ys, yl, 0, xl - yl + 1);
+
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+IntRep* lshift(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (xl == 0 || y == 0)
+ {
+ r = Icopy(r, x);
+ return r;
+ }
+
+ int xrsame = x == r;
+ int rsgn = x->sgn;
+
+ long ay = (y < 0)? -y : y;
+ int bw = ay / I_SHIFT;
+ int sw = ay % I_SHIFT;
+
+ if (y > 0)
+ {
+ int rl = bw + xl + 1;
+ if (xrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+
+ unsigned short* botr = r->s;
+ unsigned short* rs = &(botr[rl - 1]);
+ const unsigned short* botx = (xrsame)? botr : x->s;
+ const unsigned short* xs = &(botx[xl - 1]);
+ unsigned long a = 0;
+ while (xs >= botx)
+ {
+ a = up(a) | ((unsigned long)(*xs--) << sw);
+ *rs-- = extract(down(a));
+ }
+ *rs-- = extract(a);
+ while (rs >= botr)
+ *rs-- = 0;
+ }
+ else
+ {
+ int rl = xl - bw;
+ if (rl < 0)
+ r = Icopy_zero(r);
+ else
+ {
+ if (xrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+ int rw = I_SHIFT - sw;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+ const unsigned short* botx = (xrsame)? rs : x->s;
+ const unsigned short* xs = &(botx[bw]);
+ const unsigned short* topx = &(botx[xl]);
+ unsigned long a = (unsigned long)(*xs++) >> sw;
+ while (xs < topx)
+ {
+ a |= (unsigned long)(*xs++) << rw;
+ *rs++ = extract(a);
+ a = down(a);
+ }
+ *rs++ = extract(a);
+ if (xrsame) topr = (unsigned short*)topx;
+ while (rs < topr)
+ *rs++ = 0;
+ }
+ }
+ r->sgn = rsgn;
+ Icheck(r);
+ return r;
+}
+
+IntRep* lshift(const IntRep* x, const IntRep* yy, int negatey, IntRep* r)
+{
+ long y = Itolong(yy);
+ if (negatey)
+ y = -y;
+
+ return lshift(x, y, r);
+}
+
+IntRep* bitop(const IntRep* x, const IntRep* y, IntRep* r, char op)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ int xsgn = x->sgn;
+ int xrsame = x == r;
+ int yrsame = y == r;
+ if (xrsame || yrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[r->len]);
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topb;
+ if (xl >= yl)
+ {
+ as = (xrsame)? rs : x->s;
+ bs = (yrsame)? rs : y->s;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ bs = (xrsame)? rs : x->s;
+ topb = &(bs[xl]);
+ as = (yrsame)? rs : y->s;
+ }
+
+ switch (op)
+ {
+ case '&':
+ while (bs < topb) *rs++ = *as++ & *bs++;
+ while (rs < topr) *rs++ = 0;
+ break;
+ case '|':
+ while (bs < topb) *rs++ = *as++ | *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ case '^':
+ while (bs < topb) *rs++ = *as++ ^ *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ }
+ Icheck(r);
+ return r;
+}
+
+IntRep* bitop(const IntRep* x, long y, IntRep* r, char op)
+{
+ nonnil(x);
+ unsigned short tmp[SHORT_PER_LONG];
+ unsigned long u;
+ int newsgn;
+ if (newsgn = (y >= 0))
+ u = y;
+ else
+ u = -y;
+
+ int l = 0;
+ while (u != 0)
+ {
+ tmp[l++] = extract(u);
+ u = down(u);
+ }
+
+ int xl = x->len;
+ int yl = l;
+ int xsgn = x->sgn;
+ int xrsame = x == r;
+ if (xrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[r->len]);
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topb;
+ if (xl >= yl)
+ {
+ as = (xrsame)? rs : x->s;
+ bs = tmp;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ bs = (xrsame)? rs : x->s;
+ topb = &(bs[xl]);
+ as = tmp;
+ }
+
+ switch (op)
+ {
+ case '&':
+ while (bs < topb) *rs++ = *as++ & *bs++;
+ while (rs < topr) *rs++ = 0;
+ break;
+ case '|':
+ while (bs < topb) *rs++ = *as++ | *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ case '^':
+ while (bs < topb) *rs++ = *as++ ^ *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ }
+ Icheck(r);
+ return r;
+}
+
+
+
+IntRep* compl(const IntRep* src, IntRep* r)
+{
+ nonnil(src);
+ r = Icopy(r, src);
+ unsigned short* s = r->s;
+ unsigned short* top = &(s[r->len - 1]);
+ while (s < top)
+ {
+ unsigned short cmp = ~(*s);
+ *s++ = cmp;
+ }
+ unsigned short a = *s;
+ unsigned short b = 0;
+ while (a != 0)
+ {
+ b <<= 1;
+ if (!(a & 1)) b |= 1;
+ a >>= 1;
+ }
+ *s = b;
+ Icheck(r);
+ return r;
+}
+
+void (setbit)(Integer& x, long b)
+{
+ if (b >= 0)
+ {
+ int bw = (unsigned long)b / I_SHIFT;
+ int sw = (unsigned long)b % I_SHIFT;
+ int xl = x.rep ? x.rep->len : 0;
+ if (xl <= bw)
+ x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));
+ x.rep->s[bw] |= (1 << sw);
+ Icheck(x.rep);
+ }
+}
+
+void clearbit(Integer& x, long b)
+{
+ if (b >= 0)
+ {
+ if (x.rep == 0)
+ x.rep = &_ZeroRep;
+ else
+ {
+ int bw = (unsigned long)b / I_SHIFT;
+ int sw = (unsigned long)b % I_SHIFT;
+ if (x.rep->len > bw)
+ x.rep->s[bw] &= ~(1 << sw);
+ }
+ Icheck(x.rep);
+ }
+}
+
+int testbit(const Integer& x, long b)
+{
+ if (x.rep != 0 && b >= 0)
+ {
+ int bw = (unsigned long)b / I_SHIFT;
+ int sw = (unsigned long)b % I_SHIFT;
+ return (bw < x.rep->len && (x.rep->s[bw] & (1 << sw)) != 0);
+ }
+ else
+ return 0;
+}
+
+// A version of knuth's algorithm B / ex. 4.5.3.34
+// A better version that doesn't bother shifting all of `t' forthcoming
+
+IntRep* gcd(const IntRep* x, const IntRep* y)
+{
+ nonnil(x);
+ nonnil(y);
+ int ul = x->len;
+ int vl = y->len;
+
+ if (vl == 0)
+ return Ialloc(0, x->s, ul, I_POSITIVE, ul);
+ else if (ul == 0)
+ return Ialloc(0, y->s, vl, I_POSITIVE, vl);
+
+ IntRep* u = Ialloc(0, x->s, ul, I_POSITIVE, ul);
+ IntRep* v = Ialloc(0, y->s, vl, I_POSITIVE, vl);
+
+// find shift so that both not even
+
+ long k = 0;
+ int l = (ul <= vl)? ul : vl;
+ int cont = 1;
+ for (int i = 0; i < l && cont; ++i)
+ {
+ unsigned long a = (i < ul)? u->s[i] : 0;
+ unsigned long b = (i < vl)? v->s[i] : 0;
+ for (int j = 0; j < I_SHIFT; ++j)
+ {
+ if ((a | b) & 1)
+ {
+ cont = 0;
+ break;
+ }
+ else
+ {
+ ++k;
+ a >>= 1;
+ b >>= 1;
+ }
+ }
+ }
+
+ if (k != 0)
+ {
+ u = lshift(u, -k, u);
+ v = lshift(v, -k, v);
+ }
+
+ IntRep* t;
+ if (u->s[0] & 01)
+ t = Ialloc(0, v->s, v->len, !v->sgn, v->len);
+ else
+ t = Ialloc(0, u->s, u->len, u->sgn, u->len);
+
+ while (t->len != 0)
+ {
+ long s = 0; // shift t until odd
+ cont = 1;
+ int tl = t->len;
+ for (i = 0; i < tl && cont; ++i)
+ {
+ unsigned long a = t->s[i];
+ for (int j = 0; j < I_SHIFT; ++j)
+ {
+ if (a & 1)
+ {
+ cont = 0;
+ break;
+ }
+ else
+ {
+ ++s;
+ a >>= 1;
+ }
+ }
+ }
+
+ if (s != 0) t = lshift(t, -s, t);
+
+ if (t->sgn == I_POSITIVE)
+ {
+ u = Icopy(u, t);
+ t = add(t, 0, v, 1, t);
+ }
+ else
+ {
+ v = Ialloc(v, t->s, t->len, !t->sgn, t->len);
+ t = add(t, 0, u, 0, t);
+ }
+ }
+ if (!STATIC_IntRep(t)) delete t;
+ if (!STATIC_IntRep(v)) delete v;
+ if (k != 0) u = lshift(u, k, u);
+ return u;
+}
+
+
+
+long lg(const IntRep* x)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (xl == 0)
+ return 0;
+
+ long l = (xl - 1) * I_SHIFT - 1;
+ unsigned short a = x->s[xl-1];
+
+ while (a != 0)
+ {
+ a = a >> 1;
+ ++l;
+ }
+ return l;
+}
+
+IntRep* power(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int sgn;
+ if (x->sgn == I_POSITIVE || (!(y & 1)))
+ sgn = I_POSITIVE;
+ else
+ sgn = I_NEGATIVE;
+
+ int xl = x->len;
+
+ if (y == 0 || (xl == 1 && x->s[0] == 1))
+ r = Icopy_one(r, sgn);
+ else if (xl == 0 || y < 0)
+ r = Icopy_zero(r);
+ else if (y == 1 || y == -1)
+ r = Icopy(r, x);
+ else
+ {
+ int maxsize = ((lg(x) + 1) * y) / I_SHIFT + 2; // pre-allocate space
+ IntRep* b = Ialloc(0, x->s, xl, I_POSITIVE, maxsize);
+ b->len = xl;
+ r = Icalloc(r, maxsize);
+ r = Icopy_one(r, I_POSITIVE);
+ for(;;)
+ {
+ if (y & 1)
+ r = multiply(r, b, r);
+ if ((y >>= 1) == 0)
+ break;
+ else
+ b = multiply(b, b, b);
+ }
+ if (!STATIC_IntRep(b)) delete b;
+ }
+ r->sgn = sgn;
+ Icheck(r);
+ return r;
+}
+
+IntRep* abs(const IntRep* src, IntRep* dest)
+{
+ nonnil(src);
+ if (src != dest)
+ dest = Icopy(dest, src);
+ dest->sgn = I_POSITIVE;
+ return dest;
+}
+
+IntRep* negate(const IntRep* src, IntRep* dest)
+{
+ nonnil(src);
+ if (src != dest)
+ dest = Icopy(dest, src);
+ if (dest->len != 0)
+ dest->sgn = !dest->sgn;
+ return dest;
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+Integer sqrt(const Integer& x) return r(x)
+{
+ int s = sign(x);
+ if (s < 0) x.error("Attempted square root of negative Integer");
+ if (s != 0)
+ {
+ r >>= (lg(x) / 2); // get close
+ Integer q;
+ div(x, r, q);
+ while (q < r)
+ {
+ r += q;
+ r >>= 1;
+ div(x, r, q);
+ }
+ }
+ return;
+}
+
+Integer lcm(const Integer& x, const Integer& y) return r
+{
+ if (!x.initialized() || !y.initialized())
+ x.error("operation on uninitialized Integer");
+ Integer g;
+ if (sign(x) == 0 || sign(y) == 0)
+ g = 1;
+ else
+ g = gcd(x, y);
+ div(x, g, r);
+ mul(r, y, r);
+}
+
+#else
+Integer sqrt(const Integer& x)
+{
+ Integer r(x);
+ int s = sign(x);
+ if (s < 0) x.error("Attempted square root of negative Integer");
+ if (s != 0)
+ {
+ r >>= (lg(x) / 2); // get close
+ Integer q;
+ div(x, r, q);
+ while (q < r)
+ {
+ r += q;
+ r >>= 1;
+ div(x, r, q);
+ }
+ }
+ return r;
+}
+
+Integer lcm(const Integer& x, const Integer& y)
+{
+ Integer r;
+ if (!x.initialized() || !y.initialized())
+ x.error("operation on uninitialized Integer");
+ Integer g;
+ if (sign(x) == 0 || sign(y) == 0)
+ g = 1;
+ else
+ g = gcd(x, y);
+ div(x, g, r);
+ mul(r, y, r);
+ return r;
+}
+
+#endif
+
+
+
+IntRep* atoIntRep(const char* s, int base)
+{
+ int sl = strlen(s);
+ IntRep* r = Icalloc(0, sl * (lg(base) + 1) / I_SHIFT + 1);
+ if (s != 0)
+ {
+ char sgn;
+ while (isspace(*s)) ++s;
+ if (*s == '-')
+ {
+ sgn = I_NEGATIVE;
+ s++;
+ }
+ else if (*s == '+')
+ {
+ sgn = I_POSITIVE;
+ s++;
+ }
+ else
+ sgn = I_POSITIVE;
+ for (;;)
+ {
+ long digit;
+ if (*s >= '0' && *s <= '9') digit = *s - '0';
+ else if (*s >= 'a' && *s <= 'z') digit = *s - 'a' + 10;
+ else if (*s >= 'A' && *s <= 'Z') digit = *s - 'A' + 10;
+ else break;
+ if (digit >= base) break;
+ r = multiply(r, base, r);
+ r = add(r, 0, digit, r);
+ ++s;
+ }
+ r->sgn = sgn;
+ }
+ return r;
+}
+
+
+
+extern AllocRing _libgxx_fmtq;
+
+char* Itoa(const IntRep* x, int base, int width)
+{
+ int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(fmtlen);
+ char* f = cvtItoa(x, fmtbase, fmtlen, base, 0, width, 0, ' ', 'X', 0);
+ return f;
+}
+
+ostream& operator << (ostream& s, const Integer& y)
+{
+#ifdef _OLD_STREAMS
+ return s << Itoa(y.rep);
+#else
+ if (s.opfx())
+ {
+ int base = (s.flags() & ios::oct) ? 8 : (s.flags() & ios::hex) ? 16 : 10;
+ int width = s.width();
+ y.printon(s, base, width);
+ }
+ return s;
+#endif
+}
+
+void Integer::printon(ostream& s, int base /* =10 */, int width /* =0 */) const
+{
+ int align_right = !(s.flags() & ios::left);
+ int showpos = s.flags() & ios::showpos;
+ int showbase = s.flags() & ios::showbase;
+ char fillchar = s.fill();
+ char Xcase = (s.flags() & ios::uppercase)? 'X' : 'x';
+ const IntRep* x = rep;
+ int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
+ char* fmtbase = new char[fmtlen];
+ char* f = cvtItoa(x, fmtbase, fmtlen, base, showbase, width, align_right,
+ fillchar, Xcase, showpos);
+ s.write(f, fmtlen);
+ delete fmtbase;
+}
+
+char* cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base, int showbase,
+ int width, int align_right, char fillchar, char Xcase,
+ int showpos)
+{
+ char* e = fmt + fmtlen - 1;
+ char* s = e;
+ *--s = 0;
+
+ if (x->len == 0)
+ *--s = '0';
+ else
+ {
+ IntRep* z = Icopy(0, x);
+
+ // split division by base into two parts:
+ // first divide by biggest power of base that fits in an unsigned short,
+ // then use straight signed div/mods from there.
+
+ // find power
+ int bpower = 1;
+ unsigned short b = base;
+ unsigned short maxb = I_MAXNUM / base;
+ while (b < maxb)
+ {
+ b *= base;
+ ++bpower;
+ }
+ for(;;)
+ {
+ int rem = unscale(z->s, z->len, b, z->s);
+ Icheck(z);
+ if (z->len == 0)
+ {
+ while (rem != 0)
+ {
+ char ch = rem % base;
+ rem /= base;
+ if (ch >= 10)
+ ch += 'a' - 10;
+ else
+ ch += '0';
+ *--s = ch;
+ }
+ if (!STATIC_IntRep(z)) delete z;
+ break;
+ }
+ else
+ {
+ for (int i = 0; i < bpower; ++i)
+ {
+ char ch = rem % base;
+ rem /= base;
+ if (ch >= 10)
+ ch += 'a' - 10;
+ else
+ ch += '0';
+ *--s = ch;
+ }
+ }
+ }
+ }
+
+ if (base == 8 && showbase)
+ *--s = '0';
+ else if (base == 16 && showbase)
+ {
+ *--s = Xcase;
+ *--s = '0';
+ }
+ if (x->sgn == I_NEGATIVE) *--s = '-';
+ else if (showpos) *--s = '+';
+ int w = e - s - 1;
+ if (!align_right || w >= width)
+ {
+ while (w++ < width)
+ *--s = fillchar;
+ fmtlen = e - s - 1;
+ return s;
+ }
+ else
+ {
+ char* p = fmt;
+ for (char* t = s; *t != 0; ++t, ++p) *p = *t;
+ while (w++ < width) *p++ = fillchar;
+ *p = 0;
+ fmtlen = p - fmt;
+ return fmt;
+ }
+}
+
+char* dec(const Integer& x, int width)
+{
+ return Itoa(x, 10, width);
+}
+
+char* oct(const Integer& x, int width)
+{
+ return Itoa(x, 8, width);
+}
+
+char* hex(const Integer& x, int width)
+{
+ return Itoa(x, 16, width);
+}
+
+istream& operator >> (istream& stream, Integer& val)
+{
+ if (!stream.ipfx0())
+ return stream;
+ int sign = ' ';
+ register streambuf* sb = stream.rdbuf();
+ int base = 10;
+ int ndigits = 0;
+ register int ch = sb->sbumpc();
+ while (ch != EOF && isspace(ch))
+ ch = sb->sbumpc();
+ if (ch == '+' || ch == '-')
+ {
+ sign = ch;
+ ch = sb->sbumpc();
+ while (ch != EOF && isspace(ch))
+ ch = sb->sbumpc();
+ }
+ if (ch == EOF) goto eof_fail;
+ if (!(stream.flags() & ios::basefield))
+ {
+ if (ch == '0')
+ {
+ ch = sb->sbumpc();
+ if (ch == EOF) { }
+ else 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.rep = Icopy_zero(val.rep);
+
+ 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
+ goto done;
+ }
+ ndigits++;
+ switch (base)
+ {
+ case 8:
+ val <<= 3;
+ break;
+ case 16:
+ val <<= 4;
+ break;
+ default:
+ val *= base;
+ break;
+ }
+ val += digit;
+ ch = sb->sbumpc();
+ }
+ fail:
+ stream.set(ios::failbit);
+ done:
+ if (sign == '-')
+ val.negate();
+ return stream;
+ eof_fail:
+ stream.set(ios::failbit|ios::eofbit);
+ return stream;
+}
+
+int Integer::OK() const
+{
+ if (rep != 0)
+ {
+ int l = rep->len;
+ int s = rep->sgn;
+ int v = l <= rep->sz || STATIC_IntRep(rep); // length within bounds
+ v &= s == 0 || s == 1; // legal sign
+ Icheck(rep); // and correctly adjusted
+ v &= rep->len == l;
+ v &= rep->sgn == s;
+ if (v)
+ return v;
+ }
+ error("invariant failure");
+ return 0;
+}
+
+void Integer::error(const char* msg) const
+{
+ (*lib_error_handler)("Integer", msg);
+}
+
diff --git a/gnu/lib/libg++/libg++/LogNorm.cc b/gnu/lib/libg++/libg++/LogNorm.cc
new file mode 100644
index 0000000..ab60f87
--- /dev/null
+++ b/gnu/lib/libg++/libg++/LogNorm.cc
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Normal.h>
+
+#include <LogNorm.h>
+
+//
+// See Simulation, Modelling & Analysis by Law & Kelton, pp260
+//
+//
+
+double LogNormal::operator()()
+{
+ return exp (this->Normal::operator()() );
+}
+
+
diff --git a/gnu/lib/libg++/libg++/MLCG.cc b/gnu/lib/libg++/libg++/MLCG.cc
new file mode 100644
index 0000000..cdc1165
--- /dev/null
+++ b/gnu/lib/libg++/libg++/MLCG.cc
@@ -0,0 +1,103 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <MLCG.h>
+//
+// SEED_TABLE_SIZE must be a power of 2
+//
+
+
+#define SEED_TABLE_SIZE 32
+
+static _G_int32_t seedTable[SEED_TABLE_SIZE] = {
+0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
+0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
+0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
+0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
+0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
+0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
+0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
+0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf
+};
+
+MLCG::MLCG(_G_int32_t seed1, _G_int32_t seed2)
+{
+ initialSeedOne = seed1;
+ initialSeedTwo = seed2;
+ reset();
+}
+
+void
+MLCG::reset()
+{
+ _G_int32_t seed1 = initialSeedOne;
+ _G_int32_t seed2 = initialSeedTwo;
+
+ //
+ // Most people pick stupid seed numbers that do not have enough
+ // bits. In this case, if they pick a small seed number, we
+ // map that to a specific seed.
+ //
+ if (seed1 < 0) {
+ seed1 = (seed1 + 2147483561);
+ seed1 = (seed1 < 0) ? -seed1 : seed1;
+ }
+
+ if (seed2 < 0) {
+ seed2 = (seed2 + 2147483561);
+ seed2 = (seed2 < 0) ? -seed2 : seed2;
+ }
+
+ if (seed1 > -1 && seed1 < SEED_TABLE_SIZE) {
+ seedOne = seedTable[seed1];
+ } else {
+ seedOne = seed1 ^ seedTable[seed1 & (SEED_TABLE_SIZE-1)];
+ }
+
+ if (seed2 > -1 && seed2 < SEED_TABLE_SIZE) {
+ seedTwo = seedTable[seed2];
+ } else {
+ seedTwo = seed2 ^ seedTable[ seed2 & (SEED_TABLE_SIZE-1) ];
+ }
+ seedOne = (seedOne % 2147483561) + 1;
+ seedTwo = (seedTwo % 2147483397) + 1;
+}
+
+unsigned long MLCG::asLong()
+{
+ _G_int32_t k = seedOne % 53668;
+
+ seedOne = 40014 * (seedOne-k * 53668) - k * 12211;
+ if (seedOne < 0) {
+ seedOne += 2147483563;
+ }
+
+ k = seedTwo % 52774;
+ seedTwo = 40692 * (seedTwo - k * 52774) - k * 3791;
+ if (seedTwo < 0) {
+ seedTwo += 2147483399;
+ }
+
+ _G_int32_t z = seedOne - seedTwo;
+ if (z < 1) {
+ z += 2147483562;
+ }
+ return( (unsigned long) z);
+}
+
diff --git a/gnu/lib/libg++/libg++/NegExp.cc b/gnu/lib/libg++/libg++/NegExp.cc
new file mode 100644
index 0000000..8bd6d05
--- /dev/null
+++ b/gnu/lib/libg++/libg++/NegExp.cc
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <NegExp.h>
+
+double NegativeExpntl::operator()()
+{
+ return(-pMean * log(pGenerator -> asDouble()));
+}
+
diff --git a/gnu/lib/libg++/libg++/Normal.cc b/gnu/lib/libg++/libg++/Normal.cc
new file mode 100644
index 0000000..bae43e1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Normal.cc
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Normal.h>
+//
+// See Simulation, Modelling & Analysis by Law & Kelton, pp259
+//
+// This is the ``polar'' method.
+//
+
+double Normal::operator()()
+{
+
+ if (haveCachedNormal == 1) {
+ haveCachedNormal = 0;
+ return(cachedNormal * pStdDev + pMean );
+ } else {
+
+ for(;;) {
+ double u1 = pGenerator -> asDouble();
+ double u2 = pGenerator -> asDouble();
+ double v1 = 2 * u1 - 1;
+ double v2 = 2 * u2 - 1;
+ double w = (v1 * v1) + (v2 * v2);
+
+//
+// We actually generate two IID normal distribution variables.
+// We cache the one & return the other.
+//
+ if (w <= 1) {
+ double y = sqrt( (-2 * log(w)) / w);
+ double x1 = v1 * y;
+ double x2 = v2 * y;
+
+ haveCachedNormal = 1;
+ cachedNormal = x2;
+ return(x1 * pStdDev + pMean);
+ }
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/libg++/Obstack.cc b/gnu/lib/libg++/libg++/Obstack.cc
new file mode 100644
index 0000000..d661df0
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Obstack.cc
@@ -0,0 +1,125 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <limits.h>
+#include <builtin.h>
+#include <Obstack.h>
+
+/* We use subtraction of (char *)0 instead of casting to int
+ because on word-addressable machines a simple cast to int
+ may ignore the byte-within-word field of the pointer. */
+
+#ifndef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((P) - (char *)0)
+#endif
+
+#ifndef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((P) + (char *)0)
+#endif
+
+Obstack::Obstack(int size, int alignment)
+{
+ alignmentmask = alignment - 1;
+ chunksize = size;
+ chunk = 0;
+ nextfree = objectbase = 0;
+ chunklimit = 0;
+}
+
+void Obstack::_free(void* obj)
+{
+ _obstack_chunk* lp;
+ _obstack_chunk* plp;
+
+ lp = chunk;
+ while (lp != 0 && ((void*)lp > obj || (void*)(lp)->limit < obj))
+ {
+ plp = lp -> prev;
+ delete [] (char*)lp;
+ lp = plp;
+ }
+ if (lp)
+ {
+ objectbase = nextfree = (char *)(obj);
+ chunklimit = lp->limit;
+ chunk = lp;
+ }
+ else if (obj != 0)
+ (*lib_error_handler)("Obstack", "deletion of nonexistent obj");
+}
+
+void Obstack::newchunk(int size)
+{
+ _obstack_chunk* old_chunk = chunk;
+ _obstack_chunk* new_chunk;
+ long new_size;
+ int obj_size = nextfree - objectbase;
+
+ new_size = (obj_size + size) << 1;
+ if (new_size < chunksize)
+ new_size = chunksize;
+
+ new_chunk = chunk = (_obstack_chunk*)(new char[new_size]);
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = chunklimit = (char *) new_chunk + new_size;
+
+ memcpy((void*)new_chunk->contents, (void*)objectbase, obj_size);
+ objectbase = new_chunk->contents;
+ nextfree = objectbase + obj_size;
+}
+
+void* Obstack::finish()
+{
+ void* value = (void*) objectbase;
+ nextfree = __INT_TO_PTR (__PTR_TO_INT (nextfree + alignmentmask)
+ & ~alignmentmask);
+ if (nextfree - (char*)chunk > chunklimit - (char*)chunk)
+ nextfree = chunklimit;
+ objectbase = nextfree;
+ return value;
+}
+
+int Obstack::contains(void* obj) // true if obj somewhere in Obstack
+{
+ for (_obstack_chunk* ch = chunk;
+ ch != 0 && (obj < (void*)ch || obj >= (void*)(ch->limit));
+ ch = ch->prev);
+
+ return ch != 0;
+}
+
+int Obstack::OK()
+{
+ int v = chunksize > 0; // valid size
+ v &= alignmentmask != 0; // and alignment
+ v &= chunk != 0;
+ v &= objectbase >= chunk->contents;
+ v &= nextfree >= objectbase;
+ v &= nextfree <= chunklimit;
+ v &= chunklimit == chunk->limit;
+ _obstack_chunk* p = chunk;
+ // allow lots of chances to find bottom!
+ long x = LONG_MAX;
+ while (p != 0 && x != 0) { --x; p = p->prev; }
+ v &= x > 0;
+ if (!v)
+ (*lib_error_handler)("Obstack", "invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/libg++/Poisson.cc b/gnu/lib/libg++/libg++/Poisson.cc
new file mode 100644
index 0000000..8d70f17
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Poisson.cc
@@ -0,0 +1,36 @@
+
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Poisson.h>
+
+double Poisson::operator()()
+{
+ double bound = exp(-1.0 * pMean);
+ int count = 0;
+
+ for (double product = 1.0;
+ product >= bound;
+ product *= pGenerator -> asDouble()) {
+ count++;
+ }
+ return(count - 1);
+}
diff --git a/gnu/lib/libg++/libg++/RNG.cc b/gnu/lib/libg++/libg++/RNG.cc
new file mode 100644
index 0000000..02b7cdf
--- /dev/null
+++ b/gnu/lib/libg++/libg++/RNG.cc
@@ -0,0 +1,131 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <assert.h>
+#include <builtin.h>
+#include <RNG.h>
+
+// These two static fields get initialized by RNG::RNG().
+PrivateRNGSingleType RNG::singleMantissa;
+PrivateRNGDoubleType RNG::doubleMantissa;
+
+//
+// The scale constant is 2^-31. It is used to scale a 31 bit
+// long to a double.
+//
+
+//static const double randomDoubleScaleConstant = 4.656612873077392578125e-10;
+//static const float randomFloatScaleConstant = 4.656612873077392578125e-10;
+
+static char initialized = 0;
+
+RNG::RNG()
+{
+ if (!initialized)
+ {
+
+ assert (sizeof(double) == 2 * sizeof(_G_uint32_t));
+
+ //
+ // The following is a hack that I attribute to
+ // Andres Nowatzyk at CMU. The intent of the loop
+ // is to form the smallest number 0 <= x < 1.0,
+ // which is then used as a mask for two longwords.
+ // this gives us a fast way way to produce double
+ // precision numbers from longwords.
+ //
+ // I know that this works for IEEE and VAX floating
+ // point representations.
+ //
+ // A further complication is that gnu C will blow
+ // the following loop, unless compiled with -ffloat-store,
+ // because it uses extended representations for some of
+ // of the comparisons. Thus, we have the following hack.
+ // If we could specify #pragma optimize, we wouldn't need this.
+ //
+
+ PrivateRNGDoubleType t;
+ PrivateRNGSingleType s;
+
+#if _IEEE == 1
+
+ t.d = 1.5;
+ if ( t.u[1] == 0 ) { // sun word order?
+ t.u[0] = 0x3fffffff;
+ t.u[1] = 0xffffffff;
+ }
+ else {
+ t.u[0] = 0xffffffff; // encore word order?
+ t.u[1] = 0x3fffffff;
+ }
+
+ s.u = 0x3fffffff;
+#else
+ volatile double x = 1.0; // volatile needed when fp hardware used,
+ // and has greater precision than memory doubles
+ double y = 0.5;
+ do { // find largest fp-number < 2.0
+ t.d = x;
+ x += y;
+ y *= 0.5;
+ } while (x != t.d && x < 2.0);
+
+ volatile float xx = 1.0; // volatile needed when fp hardware used,
+ // and has greater precision than memory floats
+ float yy = 0.5;
+ do { // find largest fp-number < 2.0
+ s.s = xx;
+ xx += yy;
+ yy *= 0.5;
+ } while (xx != s.s && xx < 2.0);
+#endif
+ // set doubleMantissa to 1 for each doubleMantissa bit
+ doubleMantissa.d = 1.0;
+ doubleMantissa.u[0] ^= t.u[0];
+ doubleMantissa.u[1] ^= t.u[1];
+
+ // set singleMantissa to 1 for each singleMantissa bit
+ singleMantissa.s = 1.0;
+ singleMantissa.u ^= s.u;
+
+ initialized = 1;
+ }
+}
+
+float RNG::asFloat()
+{
+ PrivateRNGSingleType result;
+ result.s = 1.0;
+ result.u |= (asLong() & singleMantissa.u);
+ result.s -= 1.0;
+ assert( result.s < 1.0 && result.s >= 0);
+ return( result.s );
+}
+
+double RNG::asDouble()
+{
+ PrivateRNGDoubleType result;
+ result.d = 1.0;
+ result.u[0] |= (asLong() & doubleMantissa.u[0]);
+ result.u[1] |= (asLong() & doubleMantissa.u[1]);
+ result.d -= 1.0;
+ assert( result.d < 1.0 && result.d >= 0);
+ return( result.d );
+}
+
diff --git a/gnu/lib/libg++/libg++/Random.cc b/gnu/lib/libg++/libg++/Random.cc
new file mode 100644
index 0000000..572a602
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Random.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Random.h>
diff --git a/gnu/lib/libg++/libg++/Rational.cc b/gnu/lib/libg++/libg++/Rational.cc
new file mode 100644
index 0000000..3c00b56
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Rational.cc
@@ -0,0 +1,414 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Rational.h>
+#include <std.h>
+#include <math.h>
+#include <builtin.h>
+#include <float.h>
+
+void Rational::error(const char* msg) const
+{
+ (*lib_error_handler)("Rational", msg);
+}
+
+static const Integer _Int_One(1);
+
+void Rational::normalize()
+{
+ int s = sign(den);
+ if (s == 0)
+ error("Zero denominator.");
+ else if (s < 0)
+ {
+ den.negate();
+ num.negate();
+ }
+
+ Integer g = gcd(num, den);
+ if (ucompare(g, _Int_One) != 0)
+ {
+ num /= g;
+ den /= g;
+ }
+}
+
+void add(const Rational& x, const Rational& y, Rational& r)
+{
+ if (&r != &x && &r != &y)
+ {
+ mul(x.num, y.den, r.num);
+ mul(x.den, y.num, r.den);
+ add(r.num, r.den, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ else
+ {
+ Integer tmp;
+ mul(x.den, y.num, tmp);
+ mul(x.num, y.den, r.num);
+ add(r.num, tmp, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ r.normalize();
+}
+
+void sub(const Rational& x, const Rational& y, Rational& r)
+{
+ if (&r != &x && &r != &y)
+ {
+ mul(x.num, y.den, r.num);
+ mul(x.den, y.num, r.den);
+ sub(r.num, r.den, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ else
+ {
+ Integer tmp;
+ mul(x.den, y.num, tmp);
+ mul(x.num, y.den, r.num);
+ sub(r.num, tmp, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ r.normalize();
+}
+
+void mul(const Rational& x, const Rational& y, Rational& r)
+{
+ mul(x.num, y.num, r.num);
+ mul(x.den, y.den, r.den);
+ r.normalize();
+}
+
+void div(const Rational& x, const Rational& y, Rational& r)
+{
+ if (&r != &x && &r != &y)
+ {
+ mul(x.num, y.den, r.num);
+ mul(x.den, y.num, r.den);
+ }
+ else
+ {
+ Integer tmp;
+ mul(x.num, y.den, tmp);
+ mul(y.num, x.den, r.den);
+ r.num = tmp;
+ }
+ r.normalize();
+}
+
+
+
+
+void Rational::invert()
+{
+ Integer tmp = num;
+ num = den;
+ den = tmp;
+ int s = sign(den);
+ if (s == 0)
+ error("Zero denominator.");
+ else if (s < 0)
+ {
+ den.negate();
+ num.negate();
+ }
+}
+
+int compare(const Rational& x, const Rational& y)
+{
+ int xsgn = sign(x.num);
+ int ysgn = sign(y.num);
+ int d = xsgn - ysgn;
+ if (d == 0 && xsgn != 0) d = compare(x.num * y.den, x.den * y.num);
+ return d;
+}
+
+Rational::Rational(double x)
+{
+ num = 0;
+ den = 1;
+ if (x != 0.0)
+ {
+ int neg = x < 0;
+ if (neg)
+ x = -x;
+
+ const long shift = 15; // a safe shift per step
+ const double width = 32768.0; // = 2^shift
+ const int maxiter = 20; // ought not be necessary, but just in case,
+ // max 300 bits of precision
+ int expt;
+ double mantissa = frexp(x, &expt);
+ long exponent = expt;
+ double intpart;
+ int k = 0;
+ while (mantissa != 0.0 && k++ < maxiter)
+ {
+ mantissa *= width;
+ mantissa = modf(mantissa, &intpart);
+ num <<= shift;
+ num += (long)intpart;
+ exponent -= shift;
+ }
+ if (exponent > 0)
+ num <<= exponent;
+ else if (exponent < 0)
+ den <<= -exponent;
+ if (neg)
+ num.negate();
+ }
+ normalize();
+}
+
+
+Integer trunc(const Rational& x)
+{
+ return x.num / x.den ;
+}
+
+
+Rational pow(const Rational& x, const Integer& y)
+{
+ long yy = y.as_long();
+ return pow(x, yy);
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+Rational operator - (const Rational& x) return r(x)
+{
+ r.negate();
+}
+
+Rational abs(const Rational& x) return r(x)
+{
+ if (sign(r.num) < 0) r.negate();
+}
+
+
+Rational sqr(const Rational& x) return r
+{
+ mul(x.num, x.num, r.num);
+ mul(x.den, x.den, r.den);
+ r.normalize();
+}
+
+Integer floor(const Rational& x) return q
+{
+ Integer r;
+ divide(x.num, x.den, q, r);
+ if (sign(x.num) < 0 && sign(r) != 0) --q;
+}
+
+Integer ceil(const Rational& x) return q
+{
+ Integer r;
+ divide(x.num, x.den, q, r);
+ if (sign(x.num) >= 0 && sign(r) != 0) ++q;
+}
+
+Integer round(const Rational& x) return q
+{
+ Integer r;
+ divide(x.num, x.den, q, r);
+ r <<= 1;
+ if (ucompare(r, x.den) >= 0)
+ {
+ if (sign(x.num) >= 0)
+ ++q;
+ else
+ --q;
+ }
+}
+
+// power: no need to normalize since num & den already relatively prime
+
+Rational pow(const Rational& x, long y) return r
+{
+ if (y >= 0)
+ {
+ pow(x.num, y, r.num);
+ pow(x.den, y, r.den);
+ }
+ else
+ {
+ y = -y;
+ pow(x.num, y, r.den);
+ pow(x.den, y, r.num);
+ if (sign(r.den) < 0)
+ {
+ r.num.negate();
+ r.den.negate();
+ }
+ }
+}
+
+#else
+
+Rational operator - (const Rational& x)
+{
+ Rational r(x); r.negate(); return r;
+}
+
+Rational abs(const Rational& x)
+{
+ Rational r(x);
+ if (sign(r.num) < 0) r.negate();
+ return r;
+}
+
+
+Rational sqr(const Rational& x)
+{
+ Rational r;
+ mul(x.num, x.num, r.num);
+ mul(x.den, x.den, r.den);
+ r.normalize();
+ return r;
+}
+
+Integer floor(const Rational& x)
+{
+ Integer q;
+ Integer r;
+ divide(x.num, x.den, q, r);
+ if (sign(x.num) < 0 && sign(r) != 0) --q;
+ return q;
+}
+
+Integer ceil(const Rational& x)
+{
+ Integer q;
+ Integer r;
+ divide(x.num, x.den, q, r);
+ if (sign(x.num) >= 0 && sign(r) != 0) ++q;
+ return q;
+}
+
+Integer round(const Rational& x)
+{
+ Integer q;
+ Integer r;
+ divide(x.num, x.den, q, r);
+ r <<= 1;
+ if (ucompare(r, x.den) >= 0)
+ {
+ if (sign(x.num) >= 0)
+ ++q;
+ else
+ --q;
+ }
+ return q;
+}
+
+Rational pow(const Rational& x, long y)
+{
+ Rational r;
+ if (y >= 0)
+ {
+ pow(x.num, y, r.num);
+ pow(x.den, y, r.den);
+ }
+ else
+ {
+ y = -y;
+ pow(x.num, y, r.den);
+ pow(x.den, y, r.num);
+ if (sign(r.den) < 0)
+ {
+ r.num.negate();
+ r.den.negate();
+ }
+ }
+ return r;
+}
+
+#endif
+
+ostream& operator << (ostream& s, const Rational& y)
+{
+ if (y.denominator() == 1L)
+ s << y.numerator();
+ else
+ {
+ s << y.numerator();
+ s << "/";
+ s << y.denominator();
+ }
+ return s;
+}
+
+istream& operator >> (istream& s, Rational& y)
+{
+#ifdef _OLD_STREAMS
+ if (!s.good())
+ {
+ return s;
+ }
+#else
+ if (!s.ipfx(0))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+#endif
+ Integer n = 0;
+ Integer d = 1;
+ if (s >> n)
+ {
+ char ch = 0;
+ s.get(ch);
+ if (ch == '/')
+ {
+ s >> d;
+ }
+ else
+ {
+ s.putback(ch);
+ }
+ }
+ y = Rational(n, d);
+ return s;
+}
+
+int Rational::OK() const
+{
+ int v = num.OK() && den.OK(); // have valid num and denom
+ if (v)
+ {
+ v &= sign(den) > 0; // denominator positive;
+ v &= ucompare(gcd(num, den), _Int_One) == 0; // relatively prime
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+
+int
+Rational::fits_in_float() const
+{
+ return Rational (FLT_MIN) <= *this && *this <= Rational (FLT_MAX);
+}
+
+int
+Rational::fits_in_double() const
+{
+ return Rational (DBL_MIN) <= *this && *this <= Rational (DBL_MAX);
+}
diff --git a/gnu/lib/libg++/libg++/Regex.cc b/gnu/lib/libg++/libg++/Regex.cc
new file mode 100644
index 0000000..990f7b8
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Regex.cc
@@ -0,0 +1,135 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ Regex class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <ctype.h>
+#include <new.h>
+#include <builtin.h>
+
+extern "C" {
+#include <regex.h>
+}
+
+#include <Regex.h>
+
+Regex::~Regex()
+{
+ if (buf->buffer) free(buf->buffer);
+ if (buf->fastmap) free(buf->fastmap);
+ delete(buf);
+ delete(reg);
+}
+
+Regex::Regex(const char* t, int fast, int bufsize,
+ const char* transtable)
+{
+ int tlen = (t == 0)? 0 : strlen(t);
+ buf = new re_pattern_buffer;
+ reg = new re_registers;
+ if (fast)
+ buf->fastmap = (char*)malloc(256);
+ else
+ buf->fastmap = 0;
+ buf->translate = (char*)transtable;
+ if (tlen > bufsize)
+ bufsize = tlen;
+ buf->allocated = bufsize;
+ buf->buffer = (char *)malloc(buf->allocated);
+ char* msg = re_compile_pattern((const char*)t, tlen, buf);
+ if (msg != 0)
+ (*lib_error_handler)("Regex", msg);
+ else if (fast)
+ re_compile_fastmap(buf);
+}
+
+int Regex::match_info(int& start, int& length, int nth) const
+{
+ if ((unsigned)(nth) >= RE_NREGS)
+ return 0;
+ else
+ {
+ start = reg->start[nth];
+ length = reg->end[nth] - start;
+ return start >= 0 && length >= 0;
+ }
+}
+
+int Regex::search(const char* s, int len, int& matchlen, int startpos) const
+{
+ int matchpos, pos, range;
+ if (startpos >= 0)
+ {
+ pos = startpos;
+ range = len - startpos;
+ }
+ else
+ {
+ pos = len + startpos;
+ range = -pos;
+ }
+ matchpos = re_search_2(buf, 0, 0, (char*)s, len, pos, range, reg, len);
+ if (matchpos >= 0)
+ matchlen = reg->end[0] - reg->start[0];
+ else
+ matchlen = 0;
+ return matchpos;
+}
+
+int Regex::match(const char*s, int len, int p) const
+{
+ if (p < 0)
+ {
+ p += len;
+ if (p > len)
+ return -1;
+ return re_match_2(buf, 0, 0, (char*)s, p, 0, reg, p);
+ }
+ else if (p > len)
+ return -1;
+ else
+ return re_match_2(buf, 0, 0, (char*)s, len, p, reg, len);
+}
+
+int Regex::OK() const
+{
+// can't verify much, since we've lost the original string
+ int v = buf != 0; // have a regex buf
+ v &= buf->buffer != 0; // with a pat
+ if (!v) (*lib_error_handler)("Regex", "invariant failure");
+ return v;
+}
+
+/*
+ some built-in Regular expressions
+*/
+
+const Regex RXwhite("[ \n\t\r\v\f]+", 1);
+const Regex RXint("-?[0-9]+", 1);
+const Regex RXdouble("-?\\(\\([0-9]+\\.[0-9]*\\)\\|\\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)\\([eE][---+]?[0-9]+\\)?", 1, 200);
+const Regex RXalpha("[A-Za-z]+", 1);
+const Regex RXlowercase("[a-z]+", 1);
+const Regex RXuppercase("[A-Z]+", 1);
+const Regex RXalphanum("[0-9A-Za-z]+", 1);
+const Regex RXidentifier("[A-Za-z_][A-Za-z0-9_]*", 1);
+
diff --git a/gnu/lib/libg++/libg++/RndInt.cc b/gnu/lib/libg++/libg++/RndInt.cc
new file mode 100644
index 0000000..c09f1e5
--- /dev/null
+++ b/gnu/lib/libg++/libg++/RndInt.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <RndInt.h>
diff --git a/gnu/lib/libg++/libg++/SLList.cc b/gnu/lib/libg++/libg++/SLList.cc
new file mode 100644
index 0000000..6efd997
--- /dev/null
+++ b/gnu/lib/libg++/libg++/SLList.cc
@@ -0,0 +1,247 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _G_NO_TEMPLATES
+#ifdef __GNUG__
+//#pragma implementation
+#endif
+#include <limits.h>
+#include <stream.h>
+#include <builtin.h>
+#include "SLList.h"
+
+void BaseSLList::error(const char* msg)
+{
+ (*lib_error_handler)("SLList", msg);
+}
+
+int BaseSLList::length() const
+{
+ int l = 0;
+ BaseSLNode* t = last;
+ if (t != 0) do { ++l; t = t->tl; } while (t != last);
+ return l;
+}
+
+void BaseSLList::clear()
+{
+ if (last == 0)
+ return;
+
+ BaseSLNode* p = last->tl;
+ last->tl = 0;
+ last = 0;
+
+ while (p != 0)
+ {
+ BaseSLNode* nxt = p->tl;
+ delete_node(p);
+ p = nxt;
+ }
+}
+
+
+// Note: This is an internal method. It does *not* free old contents!
+
+void BaseSLList::copy(const BaseSLList& a)
+{
+ if (a.last == 0)
+ last = 0;
+ else
+ {
+ BaseSLNode* p = a.last->tl;
+ BaseSLNode* h = copy_node(p->item());
+ last = h;
+ for (;;)
+ {
+ if (p == a.last)
+ {
+ last->tl = h;
+ return;
+ }
+ p = p->tl;
+ BaseSLNode* n = copy_node(p->item());
+ last->tl = n;
+ last = n;
+ }
+ }
+}
+
+BaseSLList& BaseSLList::operator = (const BaseSLList& a)
+{
+ if (last != a.last)
+ {
+ clear();
+ copy(a);
+ }
+ return *this;
+}
+
+Pix BaseSLList::prepend(const void *datum)
+{
+ return prepend(copy_node(datum));
+}
+
+
+Pix BaseSLList::prepend(BaseSLNode* t)
+{
+ if (t == 0) return 0;
+ if (last == 0)
+ t->tl = last = t;
+ else
+ {
+ t->tl = last->tl;
+ last->tl = t;
+ }
+ return Pix(t);
+}
+
+
+Pix BaseSLList::append(const void *datum)
+{
+ return append(copy_node(datum));
+}
+
+Pix BaseSLList::append(BaseSLNode* t)
+{
+ if (t == 0) return 0;
+ if (last == 0)
+ t->tl = last = t;
+ else
+ {
+ t->tl = last->tl;
+ last->tl = t;
+ last = t;
+ }
+ return Pix(t);
+}
+
+void BaseSLList::join(BaseSLList& b)
+{
+ BaseSLNode* t = b.last;
+ b.last = 0;
+ if (last == 0)
+ last = t;
+ else if (t != 0)
+ {
+ BaseSLNode* f = last->tl;
+ last->tl = t->tl;
+ t->tl = f;
+ last = t;
+ }
+}
+
+Pix BaseSLList::ins_after(Pix p, const void *datum)
+{
+ BaseSLNode* u = (BaseSLNode*)p;
+ BaseSLNode* t = copy_node(datum);
+ if (last == 0)
+ t->tl = last = t;
+ else if (u == 0) // ins_after 0 means prepend
+ {
+ t->tl = last->tl;
+ last->tl = t;
+ }
+ else
+ {
+ t->tl = u->tl;
+ u->tl = t;
+ if (u == last)
+ last = t;
+ }
+ return Pix(t);
+}
+
+void BaseSLList::del_after(Pix p)
+{
+ BaseSLNode* u = (BaseSLNode*)p;
+ if (last == 0 || u == last) error("cannot del_after last");
+ if (u == 0) u = last; // del_after 0 means delete first
+ BaseSLNode* t = u->tl;
+ if (u == t)
+ last = 0;
+ else
+ {
+ u->tl = t->tl;
+ if (last == t)
+ last = u;
+ }
+ delete_node(t);
+}
+
+int BaseSLList::owns(Pix p)
+{
+ BaseSLNode* t = last;
+ if (t != 0 && p != 0)
+ {
+ do
+ {
+ if (Pix(t) == p) return 1;
+ t = t->tl;
+ } while (t != last);
+ }
+ return 0;
+}
+
+int BaseSLList::remove_front(void *dst, int signal_error)
+{
+ if (last)
+ {
+ BaseSLNode* t = last->tl;
+ copy_item(dst, t->item());
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete_node(t);
+ return 1;
+ }
+ if (signal_error)
+ error("remove_front of empty list");
+ return 0;
+}
+
+void BaseSLList::del_front()
+{
+ if (last == 0) error("del_front of empty list");
+ BaseSLNode* t = last->tl;
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete_node(t);
+}
+
+int BaseSLList::OK()
+{
+ int v = 1;
+ if (last != 0)
+ {
+ BaseSLNode* t = last;
+ long count = LONG_MAX; // Lots of chances to find last!
+ do
+ {
+ count--;
+ t = t->tl;
+ } while (count > 0 && t != last);
+ v &= count > 0;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+#endif /*!_G_NO_TEMPLATES*/
diff --git a/gnu/lib/libg++/libg++/SmplHist.cc b/gnu/lib/libg++/libg++/SmplHist.cc
new file mode 100644
index 0000000..a1fcd15
--- /dev/null
+++ b/gnu/lib/libg++/libg++/SmplHist.cc
@@ -0,0 +1,112 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <SmplHist.h>
+#include <math.h>
+
+#ifndef HUGE_VAL
+#ifdef HUGE
+#define HUGE_VAL HUGE
+#else
+#include <float.h>
+#define HUGE_VAL DBL_MAX
+#endif
+#endif
+
+const int SampleHistogramMinimum = -2;
+const int SampleHistogramMaximum = -1;
+
+SampleHistogram::SampleHistogram(double low, double high, double width)
+{
+ if (high < low) {
+ double t = high;
+ high = low;
+ low = t;
+ }
+
+ if (width == -1) {
+ width = (high - low) / 10;
+ }
+
+ howManyBuckets = int((high - low) / width) + 2;
+ bucketCount = new int[howManyBuckets];
+ bucketLimit = new double[howManyBuckets];
+ double lim = low;
+ for (int i = 0; i < howManyBuckets; i++) {
+ bucketCount[i] = 0;
+ bucketLimit[i] = lim;
+ lim += width;
+ }
+ bucketLimit[howManyBuckets-1] = HUGE_VAL; /* from math.h */
+}
+
+SampleHistogram::~SampleHistogram()
+{
+ if (howManyBuckets > 0) {
+ delete bucketCount;
+ delete bucketLimit;
+ }
+}
+
+void
+SampleHistogram::operator+=(double value)
+{
+ int i;
+ for (i = 0; i < howManyBuckets; i++) {
+ if (value < bucketLimit[i]) break;
+ }
+ bucketCount[i]++;
+ this->SampleStatistic::operator+=(value);
+}
+
+int
+SampleHistogram::similarSamples(double d)
+{
+ int i;
+ for (i = 0; i < howManyBuckets; i++) {
+ if (d < bucketLimit[i]) return(bucketCount[i]);
+ }
+ return(0);
+}
+
+void
+SampleHistogram::printBuckets(ostream& s)
+{
+ for(int i = 0; i < howManyBuckets; i++) {
+ if (bucketLimit[i] >= HUGE_VAL) {
+ s << "< max : " << bucketCount[i] << "\n";
+ } else {
+ s << "< " << bucketLimit[i] << " : " << bucketCount[i] << "\n";
+ }
+ }
+}
+
+void
+SampleHistogram::reset()
+{
+ this->SampleStatistic::reset();
+ if (howManyBuckets > 0) {
+ for (register int i = 0; i < howManyBuckets; i++) {
+ bucketCount[i] = 0;
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/libg++/SmplStat.cc b/gnu/lib/libg++/libg++/SmplStat.cc
new file mode 100644
index 0000000..461bea4
--- /dev/null
+++ b/gnu/lib/libg++/libg++/SmplStat.cc
@@ -0,0 +1,160 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <SmplStat.h>
+#include <math.h>
+
+#ifndef HUGE_VAL
+#ifdef HUGE
+#define HUGE_VAL HUGE
+#else
+#include <float.h>
+#define HUGE_VAL DBL_MAX
+#endif
+#endif
+
+// error handling
+
+void default_SampleStatistic_error_handler(const char* msg)
+{
+ cerr << "Fatal SampleStatistic error. " << msg << "\n";
+ exit(1);
+}
+
+one_arg_error_handler_t SampleStatistic_error_handler = default_SampleStatistic_error_handler;
+
+one_arg_error_handler_t set_SampleStatistic_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = SampleStatistic_error_handler;
+ SampleStatistic_error_handler = f;
+ return old;
+}
+
+void SampleStatistic::error(const char* msg)
+{
+ (*SampleStatistic_error_handler)(msg);
+}
+
+// t-distribution: given p-value and degrees of freedom, return t-value
+// adapted from Peizer & Pratt JASA, vol63, p1416
+
+double tval(double p, int df)
+{
+ double t;
+ int positive = p >= 0.5;
+ p = (positive)? 1.0 - p : p;
+ if (p <= 0.0 || df <= 0)
+ t = HUGE_VAL;
+ else if (p == 0.5)
+ t = 0.0;
+ else if (df == 1)
+ t = 1.0 / tan((p + p) * 1.57079633);
+ else if (df == 2)
+ t = sqrt(1.0 / ((p + p) * (1.0 - p)) - 2.0);
+ else
+ {
+ double ddf = df;
+ double a = sqrt(log(1.0 / (p * p)));
+ double aa = a * a;
+ a = a - ((2.515517 + (0.802853 * a) + (0.010328 * aa)) /
+ (1.0 + (1.432788 * a) + (0.189269 * aa) +
+ (0.001308 * aa * a)));
+ t = ddf - 0.666666667 + 1.0 / (10.0 * ddf);
+ t = sqrt(ddf * (exp(a * a * (ddf - 0.833333333) / (t * t)) - 1.0));
+ }
+ return (positive)? t : -t;
+}
+
+void
+SampleStatistic::reset()
+{
+ n = 0; x = x2 = 0.0;
+ maxValue = -HUGE_VAL;
+ minValue = HUGE_VAL;
+}
+
+void
+SampleStatistic::operator+=(double value)
+{
+ n += 1;
+ x += value;
+ x2 += (value * value);
+ if ( minValue > value) minValue = value;
+ if ( maxValue < value) maxValue = value;
+}
+
+double
+SampleStatistic::mean()
+{
+ if ( n > 0) {
+ return (x / n);
+ }
+ else {
+ return ( 0.0 );
+ }
+}
+
+double
+SampleStatistic::var()
+{
+ if ( n > 1) {
+ return(( x2 - ((x * x) / n)) / ( n - 1));
+ }
+ else {
+ return ( 0.0 );
+ }
+}
+
+double
+SampleStatistic::stdDev()
+{
+ if ( n <= 0 || this -> var() <= 0) {
+ return(0);
+ } else {
+ return( (double) sqrt( var() ) );
+ }
+}
+
+double
+SampleStatistic::confidence(int interval)
+{
+ int df = n - 1;
+ if (df <= 0) return HUGE_VAL;
+ double t = tval(double(100 + interval) * 0.005, df);
+ if (t == HUGE_VAL)
+ return t;
+ else
+ return (t * stdDev()) / sqrt(double(n));
+}
+
+double
+SampleStatistic::confidence(double p_value)
+{
+ int df = n - 1;
+ if (df <= 0) return HUGE_VAL;
+ double t = tval((1.0 + p_value) * 0.5, df);
+ if (t == HUGE_VAL)
+ return t;
+ else
+ return (t * stdDev()) / sqrt(double(n));
+}
+
+
diff --git a/gnu/lib/libg++/libg++/String.cc b/gnu/lib/libg++/libg++/String.cc
new file mode 100644
index 0000000..ad86079
--- /dev/null
+++ b/gnu/lib/libg++/libg++/String.cc
@@ -0,0 +1,1313 @@
+/*
+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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ String class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <String.h>
+#include <std.h>
+#include <ctype.h>
+#include <limits.h>
+#include <new.h>
+#include <builtin.h>
+
+// extern "C" {
+#include <regex.h>
+// }
+
+void String::error(const char* msg) const
+{
+ (*lib_error_handler)("String", msg);
+}
+
+String::operator const char*() const
+{
+ return (const char*)chars();
+}
+
+// globals
+
+StrRep _nilStrRep = { 0, 1, { 0 } }; // nil strings point here
+String _nilString; // nil SubStrings point here
+
+
+
+
+/*
+ the following inline fcts are specially designed to work
+ in support of String classes, and are not meant as generic replacements
+ for libc "str" functions.
+
+ inline copy fcts - I like left-to-right from->to arguments.
+ all versions assume that `to' argument is non-null
+
+ These are worth doing inline, rather than through calls because,
+ via procedural integration, adjacent copy calls can be smushed
+ together by the optimizer.
+*/
+
+// copy n bytes
+inline static void ncopy(const char* from, char* to, int n)
+{
+ if (from != to) while (--n >= 0) *to++ = *from++;
+}
+
+// copy n bytes, null-terminate
+inline static void ncopy0(const char* from, char* to, int n)
+{
+ if (from != to)
+ {
+ while (--n >= 0) *to++ = *from++;
+ *to = 0;
+ }
+ else
+ to[n] = 0;
+}
+
+// copy until null
+inline static void scopy(const char* from, char* to)
+{
+ if (from != 0) while((*to++ = *from++) != 0);
+}
+
+// copy right-to-left
+inline static void revcopy(const char* from, char* to, short n)
+{
+ if (from != 0) while (--n >= 0) *to-- = *from--;
+}
+
+
+inline static int slen(const char* t) // inline strlen
+{
+ if (t == 0)
+ return 0;
+ else
+ {
+ const char* a = t;
+ while (*a++ != 0);
+ return a - 1 - t;
+ }
+}
+
+// minimum & maximum representable rep size
+
+#define MAXStrRep_SIZE ((1 << (sizeof(short) * CHAR_BIT - 1)) - 1)
+#define MINStrRep_SIZE 16
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
+
+// The basic allocation primitive:
+// Always round request to something close to a power of two.
+// This ensures a bit of padding, which often means that
+// concatenations don't have to realloc. Plus it tends to
+// be faster when lots of Strings are created and discarded,
+// since just about any version of malloc (op new()) will
+// be faster when it can reuse identically-sized chunks
+
+inline static StrRep* Snew(int newsiz)
+{
+ unsigned int siz = sizeof(StrRep) + newsiz + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINStrRep_SIZE;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXStrRep_SIZE)
+ (*lib_error_handler)("String", "Requested length out of range");
+
+ StrRep* rep = (StrRep *) new char[allocsiz];
+ rep->sz = allocsiz - sizeof(StrRep);
+ return rep;
+}
+
+// Do-something-while-allocating routines.
+
+// We live with two ways to signify empty Sreps: either the
+// null pointer (0) or a pointer to the nilStrRep.
+
+// We always signify unknown source lengths (usually when fed a char*)
+// via len == -1, in which case it is computed.
+
+// allocate, copying src if nonull
+
+StrRep* Salloc(StrRep* old, const char* src, int srclen, int newlen)
+{
+ if (old == &_nilStrRep) old = 0;
+ if (srclen < 0) srclen = slen(src);
+ if (newlen < srclen) newlen = srclen;
+ StrRep* rep;
+ if (old == 0 || newlen > old->sz)
+ rep = Snew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+ ncopy0(src, rep->s, srclen);
+
+ if (old != rep && old != 0) delete old;
+
+ return rep;
+}
+
+// reallocate: Given the initial allocation scheme, it will
+// generally be faster in the long run to get new space & copy
+// than to call realloc
+
+StrRep* Sresize(StrRep* old, int newlen)
+{
+ if (old == &_nilStrRep) old = 0;
+ StrRep* rep;
+ if (old == 0)
+ rep = Snew(newlen);
+ else if (newlen > old->sz)
+ {
+ rep = Snew(newlen);
+ ncopy0(old->s, rep->s, old->len);
+ delete old;
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+
+ return rep;
+}
+
+// like allocate, but we know that src is a StrRep
+
+StrRep* Scopy(StrRep* old, const StrRep* s)
+{
+ if (old == &_nilStrRep) old = 0;
+ if (s == &_nilStrRep) s = 0;
+ if (old == s)
+ return (old == 0)? &_nilStrRep : old;
+ else if (s == 0)
+ {
+ old->s[0] = 0;
+ old->len = 0;
+ return old;
+ }
+ else
+ {
+ StrRep* rep;
+ int newlen = s->len;
+ if (old == 0 || newlen > old->sz)
+ {
+ if (old != 0) delete old;
+ rep = Snew(newlen);
+ }
+ else
+ rep = old;
+ rep->len = newlen;
+ ncopy0(s->s, rep->s, newlen);
+ return rep;
+ }
+}
+
+// allocate & concatenate
+
+StrRep* Scat(StrRep* old, const char* s, int srclen, const char* t, int tlen)
+{
+ if (old == &_nilStrRep) old = 0;
+ if (srclen < 0) srclen = slen(s);
+ if (tlen < 0) tlen = slen(t);
+ int newlen = srclen + tlen;
+ StrRep* rep;
+
+ if (old == 0 || newlen > old->sz ||
+ (t >= old->s && t < &(old->s[old->len]))) // beware of aliasing
+ rep = Snew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+
+ ncopy(s, rep->s, srclen);
+ ncopy0(t, &(rep->s[srclen]), tlen);
+
+ if (old != rep && old != 0) delete old;
+
+ return rep;
+}
+
+// double-concatenate
+
+StrRep* Scat(StrRep* old, const char* s, int srclen, const char* t, int tlen,
+ const char* u, int ulen)
+{
+ if (old == &_nilStrRep) old = 0;
+ if (srclen < 0) srclen = slen(s);
+ if (tlen < 0) tlen = slen(t);
+ if (ulen < 0) ulen = slen(u);
+ int newlen = srclen + tlen + ulen;
+ StrRep* rep;
+ if (old == 0 || newlen > old->sz ||
+ (t >= old->s && t < &(old->s[old->len])) ||
+ (u >= old->s && u < &(old->s[old->len])))
+ rep = Snew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+
+ ncopy(s, rep->s, srclen);
+ ncopy(t, &(rep->s[srclen]), tlen);
+ ncopy0(u, &(rep->s[srclen+tlen]), ulen);
+
+ if (old != rep && old != 0) delete old;
+
+ return rep;
+}
+
+// like cat, but we know that new stuff goes in the front of existing rep
+
+StrRep* Sprepend(StrRep* old, const char* t, int tlen)
+{
+ char* s;
+ int srclen;
+ if (old == &_nilStrRep || old == 0)
+ {
+ s = 0; old = 0; srclen = 0;
+ }
+ else
+ {
+ s = old->s; srclen = old->len;
+ }
+ if (tlen < 0) tlen = slen(t);
+ int newlen = srclen + tlen;
+ StrRep* rep;
+ if (old == 0 || newlen > old->sz ||
+ (t >= old->s && t < &(old->s[old->len])))
+ rep = Snew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+
+ revcopy(&(s[srclen]), &(rep->s[newlen]), srclen+1);
+ ncopy(t, rep->s, tlen);
+
+ if (old != rep && old != 0) delete old;
+
+ return rep;
+}
+
+
+// string compare: first argument is known to be non-null
+
+inline static int scmp(const char* a, const char* b)
+{
+ if (b == 0)
+ return *a != 0;
+ else
+ {
+ signed char diff = 0;
+ while ((diff = *a - *b++) == 0 && *a++ != 0);
+ return diff;
+ }
+}
+
+
+inline static int ncmp(const char* a, int al, const char* b, int bl)
+{
+ int n = (al <= bl)? al : bl;
+ signed char diff;
+ while (n-- > 0) if ((diff = *a++ - *b++) != 0) return diff;
+ return al - bl;
+}
+
+int fcompare(const String& x, const String& y)
+{
+ const char* a = x.chars();
+ const char* b = y.chars();
+ int al = x.length();
+ int bl = y.length();
+ int n = (al <= bl)? al : bl;
+ signed char diff = 0;
+ while (n-- > 0)
+ {
+ char ac = *a++;
+ char bc = *b++;
+ if ((diff = ac - bc) != 0)
+ {
+ if (ac >= 'a' && ac <= 'z')
+ ac = ac - 'a' + 'A';
+ if (bc >= 'a' && bc <= 'z')
+ bc = bc - 'a' + 'A';
+ if ((diff = ac - bc) != 0)
+ return diff;
+ }
+ }
+ return al - bl;
+}
+
+// these are not inline, but pull in the above inlines, so are
+// pretty fast
+
+int compare(const String& x, const char* b)
+{
+ return scmp(x.chars(), b);
+}
+
+int compare(const String& x, const String& y)
+{
+ return scmp(x.chars(), y.chars());
+}
+
+int compare(const String& x, const SubString& y)
+{
+ return ncmp(x.chars(), x.length(), y.chars(), y.length());
+}
+
+int compare(const SubString& x, const String& y)
+{
+ return ncmp(x.chars(), x.length(), y.chars(), y.length());
+}
+
+int compare(const SubString& x, const SubString& y)
+{
+ return ncmp(x.chars(), x.length(), y.chars(), y.length());
+}
+
+int compare(const SubString& x, const char* b)
+{
+ if (b == 0)
+ return x.length();
+ else
+ {
+ const char* a = x.chars();
+ int n = x.length();
+ signed char diff;
+ while (n-- > 0) if ((diff = *a++ - *b++) != 0) return diff;
+ return (*b == 0) ? 0 : -1;
+ }
+}
+
+/*
+ index fcts
+*/
+
+int String::search(int start, int sl, char c) const
+{
+ const char* s = chars();
+ if (sl > 0)
+ {
+ if (start >= 0)
+ {
+ const char* a = &(s[start]);
+ const char* lasta = &(s[sl]);
+ while (a < lasta) if (*a++ == c) return --a - s;
+ }
+ else
+ {
+ const char* a = &(s[sl + start + 1]);
+ while (--a >= s) if (*a == c) return a - s;
+ }
+ }
+ return -1;
+}
+
+int String::search(int start, int sl, const char* t, int tl) const
+{
+ const char* s = chars();
+ if (tl < 0) tl = slen(t);
+ if (sl > 0 && tl > 0)
+ {
+ if (start >= 0)
+ {
+ const char* lasts = &(s[sl - tl]);
+ const char* lastt = &(t[tl]);
+ const char* p = &(s[start]);
+
+ while (p <= lasts)
+ {
+ const char* x = p++;
+ const char* y = t;
+ while (*x++ == *y++) if (y >= lastt) return --p - s;
+ }
+ }
+ else
+ {
+ const char* firsts = &(s[tl - 1]);
+ const char* lastt = &(t[tl - 1]);
+ const char* p = &(s[sl + start + 1]);
+
+ while (--p >= firsts)
+ {
+ const char* x = p;
+ const char* y = lastt;
+ while (*x-- == *y--) if (y < t) return ++x - s;
+ }
+ }
+ }
+ return -1;
+}
+
+int String::match(int start, int sl, int exact, const char* t, int tl) const
+{
+ if (tl < 0) tl = slen(t);
+
+ if (start < 0)
+ {
+ start = sl + start - tl + 1;
+ if (start < 0 || (exact && start != 0))
+ return -1;
+ }
+ else if (exact && sl - start != tl)
+ return -1;
+
+ if (sl == 0 || tl == 0 || sl - start < tl || start >= sl)
+ return -1;
+
+ int n = tl;
+ const char* s = &(rep->s[start]);
+ while (--n >= 0) if (*s++ != *t++) return -1;
+ return tl;
+}
+
+void SubString::assign(const StrRep* ysrc, const char* ys, int ylen)
+{
+ if (&S == &_nilString) return;
+
+ if (ylen < 0) ylen = slen(ys);
+ StrRep* targ = S.rep;
+ int sl = targ->len - len + ylen;
+
+ if (ysrc == targ || sl >= targ->sz)
+ {
+ StrRep* oldtarg = targ;
+ targ = Sresize(0, sl);
+ ncopy(oldtarg->s, targ->s, pos);
+ ncopy(ys, &(targ->s[pos]), ylen);
+ scopy(&(oldtarg->s[pos + len]), &(targ->s[pos + ylen]));
+ delete oldtarg;
+ }
+ else if (len == ylen)
+ ncopy(ys, &(targ->s[pos]), len);
+ else if (ylen < len)
+ {
+ ncopy(ys, &(targ->s[pos]), ylen);
+ scopy(&(targ->s[pos + len]), &(targ->s[pos + ylen]));
+ }
+ else
+ {
+ revcopy(&(targ->s[targ->len]), &(targ->s[sl]), targ->len-pos-len +1);
+ ncopy(ys, &(targ->s[pos]), ylen);
+ }
+ targ->len = sl;
+ S.rep = targ;
+}
+
+
+
+/*
+ * substitution
+ */
+
+
+int String::_gsub(const char* pat, int pl, const char* r, int rl)
+{
+ int nmatches = 0;
+ if (pl < 0) pl = slen(pat);
+ if (rl < 0) rl = slen(r);
+ int sl = length();
+ if (sl <= 0 || pl <= 0 || sl < pl)
+ return nmatches;
+
+ const char* s = chars();
+
+ // prepare to make new rep
+ StrRep* nrep = 0;
+ int nsz = 0;
+ char* x = 0;
+
+ int si = 0;
+ int xi = 0;
+ int remaining = sl;
+
+ while (remaining >= pl)
+ {
+ int pos = search(si, sl, pat, pl);
+ if (pos < 0)
+ break;
+ else
+ {
+ ++nmatches;
+ int mustfit = xi + remaining + rl - pl;
+ if (mustfit >= nsz)
+ {
+ if (nrep != 0) nrep->len = xi;
+ nrep = Sresize(nrep, mustfit);
+ nsz = nrep->sz;
+ x = nrep->s;
+ }
+ pos -= si;
+ ncopy(&(s[si]), &(x[xi]), pos);
+ ncopy(r, &(x[xi + pos]), rl);
+ si += pos + pl;
+ remaining -= pos + pl;
+ xi += pos + rl;
+ }
+ }
+
+ if (nrep == 0)
+ {
+ if (nmatches == 0)
+ return nmatches;
+ else
+ nrep = Sresize(nrep, xi+remaining);
+ }
+
+ ncopy0(&(s[si]), &(x[xi]), remaining);
+ nrep->len = xi + remaining;
+
+ if (nrep->len <= rep->sz) // fit back in if possible
+ {
+ rep->len = nrep->len;
+ ncopy0(nrep->s, rep->s, rep->len);
+ delete(nrep);
+ }
+ else
+ {
+ delete(rep);
+ rep = nrep;
+ }
+ return nmatches;
+}
+
+int String::_gsub(const Regex& pat, const char* r, int rl)
+{
+ int nmatches = 0;
+ int sl = length();
+ if (sl <= 0)
+ return nmatches;
+
+ if (rl < 0) rl = slen(r);
+
+ const char* s = chars();
+
+ StrRep* nrep = 0;
+ int nsz = 0;
+
+ char* x = 0;
+
+ int si = 0;
+ int xi = 0;
+ int remaining = sl;
+ int pos, pl = 0; // how long is a regular expression?
+
+ while (remaining > 0)
+ {
+ pos = pat.search(s, sl, pl, si); // unlike string search, the pos returned here is absolute
+ if (pos < 0 || pl <= 0)
+ break;
+ else
+ {
+ ++nmatches;
+ int mustfit = xi + remaining + rl - pl;
+ if (mustfit >= nsz)
+ {
+ if (nrep != 0) nrep->len = xi;
+ nrep = Sresize(nrep, mustfit);
+ x = nrep->s;
+ nsz = nrep->sz;
+ }
+ pos -= si;
+ ncopy(&(s[si]), &(x[xi]), pos);
+ ncopy(r, &(x[xi + pos]), rl);
+ si += pos + pl;
+ remaining -= pos + pl;
+ xi += pos + rl;
+ }
+ }
+
+ if (nrep == 0)
+ {
+ if (nmatches == 0)
+ return nmatches;
+ else
+ nrep = Sresize(nrep, xi+remaining);
+ }
+
+ ncopy0(&(s[si]), &(x[xi]), remaining);
+ nrep->len = xi + remaining;
+
+ if (nrep->len <= rep->sz) // fit back in if possible
+ {
+ rep->len = nrep->len;
+ ncopy0(nrep->s, rep->s, rep->len);
+ delete(nrep);
+ }
+ else
+ {
+ delete(rep);
+ rep = nrep;
+ }
+ return nmatches;
+}
+
+
+/*
+ * deletion
+ */
+
+void String::del(int pos, int len)
+{
+ if (pos < 0 || len <= 0 || (unsigned)(pos + len) > length()) return;
+ int nlen = length() - len;
+ int first = pos + len;
+ ncopy0(&(rep->s[first]), &(rep->s[pos]), length() - first);
+ rep->len = nlen;
+}
+
+void String::del(const Regex& r, int startpos)
+{
+ int mlen;
+ int first = r.search(chars(), length(), mlen, startpos);
+ del(first, mlen);
+}
+
+void String::del(const char* t, int startpos)
+{
+ int tlen = slen(t);
+ int p = search(startpos, length(), t, tlen);
+ del(p, tlen);
+}
+
+void String::del(const String& y, int startpos)
+{
+ del(search(startpos, length(), y.chars(), y.length()), y.length());
+}
+
+void String::del(const SubString& y, int startpos)
+{
+ del(search(startpos, length(), y.chars(), y.length()), y.length());
+}
+
+void String::del(char c, int startpos)
+{
+ del(search(startpos, length(), c), 1);
+}
+
+/*
+ * substring extraction
+ */
+
+
+SubString String::at(int first, int len)
+{
+ return _substr(first, len);
+}
+
+SubString String::operator() (int first, int len)
+{
+ return _substr(first, len);
+}
+
+SubString String::before(int pos)
+{
+ return _substr(0, pos);
+}
+
+SubString String::through(int pos)
+{
+ return _substr(0, pos+1);
+}
+
+SubString String::after(int pos)
+{
+ return _substr(pos + 1, length() - (pos + 1));
+}
+
+SubString String::from(int pos)
+{
+ return _substr(pos, length() - pos);
+}
+
+SubString String::at(const String& y, int startpos)
+{
+ int first = search(startpos, length(), y.chars(), y.length());
+ return _substr(first, y.length());
+}
+
+SubString String::at(const SubString& y, int startpos)
+{
+ int first = search(startpos, length(), y.chars(), y.length());
+ return _substr(first, y.length());
+}
+
+SubString String::at(const Regex& r, int startpos)
+{
+ int mlen;
+ int first = r.search(chars(), length(), mlen, startpos);
+ return _substr(first, mlen);
+}
+
+SubString String::at(const char* t, int startpos)
+{
+ int tlen = slen(t);
+ int first = search(startpos, length(), t, tlen);
+ return _substr(first, tlen);
+}
+
+SubString String::at(char c, int startpos)
+{
+ int first = search(startpos, length(), c);
+ return _substr(first, 1);
+}
+
+SubString String::before(const String& y, int startpos)
+{
+ int last = search(startpos, length(), y.chars(), y.length());
+ return _substr(0, last);
+}
+
+SubString String::before(const SubString& y, int startpos)
+{
+ int last = search(startpos, length(), y.chars(), y.length());
+ return _substr(0, last);
+}
+
+SubString String::before(const Regex& r, int startpos)
+{
+ int mlen;
+ int first = r.search(chars(), length(), mlen, startpos);
+ return _substr(0, first);
+}
+
+SubString String::before(char c, int startpos)
+{
+ int last = search(startpos, length(), c);
+ return _substr(0, last);
+}
+
+SubString String::before(const char* t, int startpos)
+{
+ int tlen = slen(t);
+ int last = search(startpos, length(), t, tlen);
+ return _substr(0, last);
+}
+
+SubString String::through(const String& y, int startpos)
+{
+ int last = search(startpos, length(), y.chars(), y.length());
+ if (last >= 0) last += y.length();
+ return _substr(0, last);
+}
+
+SubString String::through(const SubString& y, int startpos)
+{
+ int last = search(startpos, length(), y.chars(), y.length());
+ if (last >= 0) last += y.length();
+ return _substr(0, last);
+}
+
+SubString String::through(const Regex& r, int startpos)
+{
+ int mlen;
+ int first = r.search(chars(), length(), mlen, startpos);
+ if (first >= 0) first += mlen;
+ return _substr(0, first);
+}
+
+SubString String::through(char c, int startpos)
+{
+ int last = search(startpos, length(), c);
+ if (last >= 0) last += 1;
+ return _substr(0, last);
+}
+
+SubString String::through(const char* t, int startpos)
+{
+ int tlen = slen(t);
+ int last = search(startpos, length(), t, tlen);
+ if (last >= 0) last += tlen;
+ return _substr(0, last);
+}
+
+SubString String::after(const String& y, int startpos)
+{
+ int first = search(startpos, length(), y.chars(), y.length());
+ if (first >= 0) first += y.length();
+ return _substr(first, length() - first);
+}
+
+SubString String::after(const SubString& y, int startpos)
+{
+ int first = search(startpos, length(), y.chars(), y.length());
+ if (first >= 0) first += y.length();
+ return _substr(first, length() - first);
+}
+
+SubString String::after(char c, int startpos)
+{
+ int first = search(startpos, length(), c);
+ if (first >= 0) first += 1;
+ return _substr(first, length() - first);
+}
+
+SubString String::after(const Regex& r, int startpos)
+{
+ int mlen;
+ int first = r.search(chars(), length(), mlen, startpos);
+ if (first >= 0) first += mlen;
+ return _substr(first, length() - first);
+}
+
+SubString String::after(const char* t, int startpos)
+{
+ int tlen = slen(t);
+ int first = search(startpos, length(), t, tlen);
+ if (first >= 0) first += tlen;
+ return _substr(first, length() - first);
+}
+
+SubString String::from(const String& y, int startpos)
+{
+ int first = search(startpos, length(), y.chars(), y.length());
+ return _substr(first, length() - first);
+}
+
+SubString String::from(const SubString& y, int startpos)
+{
+ int first = search(startpos, length(), y.chars(), y.length());
+ return _substr(first, length() - first);
+}
+
+SubString String::from(const Regex& r, int startpos)
+{
+ int mlen;
+ int first = r.search(chars(), length(), mlen, startpos);
+ return _substr(first, length() - first);
+}
+
+SubString String::from(char c, int startpos)
+{
+ int first = search(startpos, length(), c);
+ return _substr(first, length() - first);
+}
+
+SubString String::from(const char* t, int startpos)
+{
+ int tlen = slen(t);
+ int first = search(startpos, length(), t, tlen);
+ return _substr(first, length() - first);
+}
+
+
+
+/*
+ * split/join
+ */
+
+
+int split(const String& src, String results[], int n, const String& sep)
+{
+ String x = src;
+ const char* s = x.chars();
+ int sl = x.length();
+ int i = 0;
+ int pos = 0;
+ while (i < n && pos < sl)
+ {
+ int p = x.search(pos, sl, sep.chars(), sep.length());
+ if (p < 0)
+ p = sl;
+ results[i].rep = Salloc(results[i].rep, &(s[pos]), p - pos, p - pos);
+ i++;
+ pos = p + sep.length();
+ }
+ return i;
+}
+
+int split(const String& src, String results[], int n, const Regex& r)
+{
+ String x = src;
+ const char* s = x.chars();
+ int sl = x.length();
+ int i = 0;
+ int pos = 0;
+ int p, matchlen;
+ while (i < n && pos < sl)
+ {
+ p = r.search(s, sl, matchlen, pos);
+ if (p < 0)
+ p = sl;
+ results[i].rep = Salloc(results[i].rep, &(s[pos]), p - pos, p - pos);
+ i++;
+ pos = p + matchlen;
+ }
+ return i;
+}
+
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+String join(String src[], int n, const String& separator) return x;
+{
+ String sep = separator;
+ int xlen = 0;
+ for (int i = 0; i < n; ++i)
+ xlen += src[i].length();
+ xlen += (n - 1) * sep.length();
+
+ x.alloc(xlen);
+
+ int j = 0;
+
+ for (i = 0; i < n - 1; ++i)
+ {
+ ncopy(src[i].chars(), &(x.rep->s[j]), src[i].length());
+ j += src[i].length();
+ ncopy(sep.chars(), &(x.rep->s[j]), sep.length());
+ j += sep.length();
+ }
+ ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
+}
+
+#else
+
+String join(String src[], int n, const String& separator)
+{
+ String x;
+ String sep = separator;
+ int xlen = 0;
+ for (int i = 0; i < n; ++i)
+ xlen += src[i].length();
+ xlen += (n - 1) * sep.length();
+
+ x.alloc(xlen);
+
+ int j = 0;
+
+ for (i = 0; i < n - 1; ++i)
+ {
+ ncopy(src[i].chars(), &(x.rep->s[j]), src[i].length());
+ j += src[i].length();
+ ncopy(sep.chars(), &(x.rep->s[j]), sep.length());
+ j += sep.length();
+ }
+ ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
+ return x;
+}
+
+#endif
+
+/*
+ misc
+*/
+
+
+StrRep* Sreverse(const StrRep* src, StrRep* dest)
+{
+ int n = src->len;
+ if (src != dest)
+ dest = Salloc(dest, src->s, n, n);
+ if (n > 0)
+ {
+ char* a = dest->s;
+ char* b = &(a[n - 1]);
+ while (a < b)
+ {
+ char t = *a;
+ *a++ = *b;
+ *b-- = t;
+ }
+ }
+ return dest;
+}
+
+
+StrRep* Supcase(const StrRep* src, StrRep* dest)
+{
+ int n = src->len;
+ if (src != dest) dest = Salloc(dest, src->s, n, n);
+ char* p = dest->s;
+ char* e = &(p[n]);
+ for (; p < e; ++p) if (islower(*p)) *p = toupper(*p);
+ return dest;
+}
+
+StrRep* Sdowncase(const StrRep* src, StrRep* dest)
+{
+ int n = src->len;
+ if (src != dest) dest = Salloc(dest, src->s, n, n);
+ char* p = dest->s;
+ char* e = &(p[n]);
+ for (; p < e; ++p) if (isupper(*p)) *p = tolower(*p);
+ return dest;
+}
+
+StrRep* Scapitalize(const StrRep* src, StrRep* dest)
+{
+ int n = src->len;
+ if (src != dest) dest = Salloc(dest, src->s, n, n);
+
+ char* p = dest->s;
+ char* e = &(p[n]);
+ for (; p < e; ++p)
+ {
+ int at_word;
+ if (at_word = islower(*p))
+ *p = toupper(*p);
+ else
+ at_word = isupper(*p) || isdigit(*p);
+
+ if (at_word)
+ {
+ while (++p < e)
+ {
+ if (isupper(*p))
+ *p = tolower(*p);
+ /* A '\'' does not break a word, so that "Nathan's" stays
+ "Nathan's" rather than turning into "Nathan'S". */
+ else if (!islower(*p) && !isdigit(*p) && (*p != '\''))
+ break;
+ }
+ }
+ }
+ return dest;
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+String replicate(char c, int n) return w;
+{
+ w.rep = Sresize(w.rep, n);
+ char* p = w.rep->s;
+ while (n-- > 0) *p++ = c;
+ *p = 0;
+}
+
+String replicate(const String& y, int n) return w
+{
+ int len = y.length();
+ w.rep = Sresize(w.rep, n * len);
+ char* p = w.rep->s;
+ while (n-- > 0)
+ {
+ ncopy(y.chars(), p, len);
+ p += len;
+ }
+ *p = 0;
+}
+
+String common_prefix(const String& x, const String& y, int startpos) return r;
+{
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[startpos]);
+ const char* ss = xs;
+ const char* topx = &(xchars[x.length()]);
+ const char* ys = &(ychars[startpos]);
+ const char* topy = &(ychars[y.length()]);
+ for (int l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
+ r.rep = Salloc(r.rep, ss, l, l);
+}
+
+String common_suffix(const String& x, const String& y, int startpos) return r;
+{
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[x.length() + startpos]);
+ const char* botx = xchars;
+ const char* ys = &(ychars[y.length() + startpos]);
+ const char* boty = ychars;
+ for (int l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
+ r.rep = Salloc(r.rep, ++xs, l, l);
+}
+
+#else
+
+String replicate(char c, int n)
+{
+ String w;
+ w.rep = Sresize(w.rep, n);
+ char* p = w.rep->s;
+ while (n-- > 0) *p++ = c;
+ *p = 0;
+ return w;
+}
+
+String replicate(const String& y, int n)
+{
+ String w;
+ int len = y.length();
+ w.rep = Sresize(w.rep, n * len);
+ char* p = w.rep->s;
+ while (n-- > 0)
+ {
+ ncopy(y.chars(), p, len);
+ p += len;
+ }
+ *p = 0;
+ return w;
+}
+
+String common_prefix(const String& x, const String& y, int startpos)
+{
+ String r;
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[startpos]);
+ const char* ss = xs;
+ const char* topx = &(xchars[x.length()]);
+ const char* ys = &(ychars[startpos]);
+ const char* topy = &(ychars[y.length()]);
+ for (int l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
+ r.rep = Salloc(r.rep, ss, l, l);
+ return r;
+}
+
+String common_suffix(const String& x, const String& y, int startpos)
+{
+ String r;
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[x.length() + startpos]);
+ const char* botx = xchars;
+ const char* ys = &(ychars[y.length() + startpos]);
+ const char* boty = ychars;
+ for (int l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
+ r.rep = Salloc(r.rep, ++xs, l, l);
+ return r;
+}
+
+#endif
+
+// IO
+
+istream& operator>>(istream& s, String& x)
+{
+ if (!s.ipfx(0) || (!(s.flags() & ios::skipws) && !ws(s)))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+ int ch;
+ int i = 0;
+ x.rep = Sresize(x.rep, 20);
+ register streambuf *sb = s.rdbuf();
+ while ((ch = sb->sbumpc()) != EOF)
+ {
+ if (isspace(ch))
+ break;
+ if (i >= x.rep->sz - 1)
+ x.rep = Sresize(x.rep, i+1);
+ x.rep->s[i++] = ch;
+ }
+ x.rep->s[i] = 0;
+ x.rep->len = i;
+ int new_state = s.rdstate();
+ if (i == 0) new_state |= ios::failbit;
+ if (ch == EOF) new_state |= ios::eofbit;
+ s.clear(new_state);
+ return s;
+}
+
+int readline(istream& s, String& x, char terminator, int discard)
+{
+ if (!s.ipfx(0))
+ return 0;
+ int ch;
+ int i = 0;
+ x.rep = Sresize(x.rep, 80);
+ register streambuf *sb = s.rdbuf();
+ while ((ch = sb->sbumpc()) != EOF)
+ {
+ if (ch != terminator || !discard)
+ {
+ if (i >= x.rep->sz - 1)
+ x.rep = Sresize(x.rep, i+1);
+ x.rep->s[i++] = ch;
+ }
+ if (ch == terminator)
+ break;
+ }
+ x.rep->s[i] = 0;
+ x.rep->len = i;
+ if (ch == EOF) s.clear(ios::eofbit|s.rdstate());
+ return i;
+}
+
+
+ostream& operator<<(ostream& s, const SubString& x)
+{
+ const char* a = x.chars();
+ const char* lasta = &(a[x.length()]);
+ while (a < lasta)
+ s.put(*a++);
+ return(s);
+}
+
+// from John.Willis@FAS.RI.CMU.EDU
+
+int String::freq(const SubString& y) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,y.chars(), y.length())>= 0) found++;
+ return(found);
+}
+
+int String::freq(const String& y) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,y.chars(),y.length()) >= 0) found++;
+ return(found);
+}
+
+int String::freq(const char* t) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,t) >= 0) found++;
+ return(found);
+}
+
+int String::freq(char c) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,&c,1) >= 0) found++;
+ return(found);
+}
+
+
+int String::OK() const
+{
+ if (rep == 0 // don't have a rep
+ || rep->len > rep->sz // string oustide bounds
+ || rep->s[rep->len] != 0) // not null-terminated
+ error("invariant failure");
+ return 1;
+}
+
+int SubString::OK() const
+{
+ int v = S != (const char*)0; // have a String;
+ v &= S.OK(); // that is legal
+ v &= pos + len >= S.rep->len;// pos and len within bounds
+ if (!v) S.error("SubString invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/libg++/Uniform.cc b/gnu/lib/libg++/libg++/Uniform.cc
new file mode 100644
index 0000000..2bf7259
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Uniform.cc
@@ -0,0 +1,27 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Uniform.h>
+
+double Uniform::operator()()
+{
+ return( pLow + delta * pGenerator -> asDouble() );
+}
diff --git a/gnu/lib/libg++/libg++/Weibull.cc b/gnu/lib/libg++/libg++/Weibull.cc
new file mode 100644
index 0000000..02670b9
--- /dev/null
+++ b/gnu/lib/libg++/libg++/Weibull.cc
@@ -0,0 +1,33 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Weibull.h>
+
+//
+// See Simulation, Modelling & Analysis by Law & Kelton, pp259
+//
+// This is the ``polar'' method.
+//
+
+double Weibull::operator()()
+{
+ return( pow(pBeta * ( - log(1 - pGenerator -> asDouble()) ), pInvAlpha) );
+}
diff --git a/gnu/lib/libg++/libg++/bitand.c b/gnu/lib/libg++/libg++/bitand.c
new file mode 100644
index 0000000..7809a11
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitand.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+/* Copy LENGTH bits from (starting at SRCBIT) into pdst starting at DSTBIT.
+ This will work even if psrc & pdst overlap. */
+
+void
+_BS_and (pdst, dstbit, psrc, srcbit, length)
+ register _BS_word* pdst;
+ int dstbit;
+ register const _BS_word* psrc;
+ int srcbit;
+ _BS_size_t length;
+{
+#define COMBINE(dst, src) (dst) & (src)
+#include "bitdo2.h"
+}
diff --git a/gnu/lib/libg++/libg++/bitany.c b/gnu/lib/libg++/libg++/bitany.c
new file mode 100644
index 0000000..861382f
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitany.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+int
+_BS_any (ptr, offset, length)
+ register const _BS_word *ptr;
+ int offset;
+ _BS_size_t length;
+{
+#undef DOIT
+#define DOIT(WORD, MASK) if ((WORD) & (MASK)) return 1;
+#include "bitdo1.h"
+ return 0;
+}
diff --git a/gnu/lib/libg++/libg++/bitblt.c b/gnu/lib/libg++/libg++/bitblt.c
new file mode 100644
index 0000000..f7c4322
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitblt.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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).
+ Based on ideas in the X11 MFB server. */
+
+#include "bitprims.h"
+#define ONES ((_BS_word)(~0))
+
+/* Copy LENGTH bits from (starting at SRCBIT) into pdst starting at DSTBIT.
+ This will work even if psrc & pdst overlap. */
+
+void
+_BS_blt (op, pdst, dstbit, psrc, srcbit, length)
+ enum _BS_alu op;
+ register _BS_word* pdst;
+ int dstbit;
+ register const _BS_word* psrc;
+ int srcbit;
+ _BS_size_t length;
+{
+ _BS_word ca1, cx1, ca2, cx2;
+ switch (op)
+ {
+ case _BS_alu_clear:
+ _BS_clear (pdst, dstbit, length);
+ return;
+ case _BS_alu_and:
+ _BS_and (pdst, dstbit, psrc, srcbit, length);
+ return;
+ case _BS_alu_andReverse:
+ ca1 = ONES; cx1 = 0; ca2 = ONES; cx2 = 0;
+ break;
+ case _BS_alu_copy:
+ _BS_copy (pdst, dstbit, psrc, srcbit, length);
+ return;
+ case _BS_alu_andInverted:
+ ca1 = ONES; cx1 = ONES; ca2 = 0; cx2 = 0;
+ break;
+ case _BS_alu_noop:
+ return;
+ case _BS_alu_xor:
+ _BS_xor (pdst, dstbit, psrc, srcbit, length);
+ return;
+ case _BS_alu_or:
+ ca1 = ONES; cx1 = ONES; ca2 = ONES; cx2 = 0;
+ break;
+ case _BS_alu_nor:
+ ca1 = ONES; cx1 = ONES; ca2 = ONES; cx2 = ONES;
+ break;
+ case_BS_alu_equiv:
+ ca1 = 0; cx1 = ONES; ca2 = ONES; cx2 = ONES;
+ break;
+ case _BS_alu_invert:
+ _BS_invert (pdst, dstbit, length);
+ return;
+ case _BS_alu_orReverse:
+ ca1 = ONES; cx1 = ONES; ca2 = 0; cx2 = ONES;
+ break;
+ case _BS_alu_copyInverted:
+ ca1 = 0; cx1 = 0; ca2 = ONES; cx2 = ONES;
+ break;
+ case _BS_alu_orInverted:
+ ca1 = ONES; cx1 = 0; ca2 = ONES; cx2 = ONES;
+ break;
+ case _BS_alu_nand:
+ ca1 = ONES; cx1 = 0; ca2 = 0; cx2 = ONES;
+ break;
+ case _BS_alu_set:
+ _BS_set (pdst, dstbit, length);
+ return;
+ }
+ {
+#define COMBINE(dst, src) ((dst) & ((src) & ca1 ^ cx1) ^ ((src) & ca2 ^ cx2))
+#include "bitdo2.h"
+ }
+}
diff --git a/gnu/lib/libg++/libg++/bitclear.c b/gnu/lib/libg++/libg++/bitclear.c
new file mode 100644
index 0000000..8015843
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitclear.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+void
+_BS_clear (ptr, offset, length)
+ register _BS_word *ptr;
+ int offset;
+ _BS_size_t length;
+{
+#undef DOIT
+#define DOIT(WORD, MASK) ((WORD) &= ~(MASK))
+#include "bitdo1.h"
+}
diff --git a/gnu/lib/libg++/libg++/bitcopy.c b/gnu/lib/libg++/libg++/bitcopy.c
new file mode 100644
index 0000000..f0f449c
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitcopy.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+/* Copy LENGTH bits from (starting at SRCBIT) into pdst starting at DSTBIT.
+ This will work even if psrc & pdst overlap. */
+
+void
+_BS_copy (pdst, dstbit, psrc, srcbit, length)
+ register _BS_word* pdst;
+ int dstbit;
+ register const _BS_word* psrc;
+ int srcbit;
+ _BS_size_t length;
+{
+#define COMBINE(dst, src) (src)
+#include "bitdo2.h"
+}
diff --git a/gnu/lib/libg++/libg++/bitcount.c b/gnu/lib/libg++/libg++/bitcount.c
new file mode 100644
index 0000000..9a17d17
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitcount.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+/* bit_count[I] is number of '1' bits in I. */
+static const unsigned char
+four_bit_count[16] = {
+ 0, 1, 1, 2,
+ 1, 2, 2, 3,
+ 1, 2, 2, 3,
+ 2, 3, 3, 4};
+
+#if !defined(inline) && !defined(__GNUC__) && !defined(__cplusplus)
+#define inline
+#endif
+
+static inline int
+_BS_count_word (word)
+ register _BS_word word;
+{
+ register int count = 0;
+ while (word > 0)
+ {
+ count += four_bit_count[word & 15];
+ word >>= 4;
+ }
+ return count;
+}
+
+int
+_BS_count (ptr, offset, length)
+ register const _BS_word *ptr;
+ int offset;
+ _BS_size_t length;
+{
+ register int count = 0;
+#undef DOIT
+#define DOIT(WORD, MASK) count += _BS_count_word ((WORD) & (MASK));
+#include "bitdo1.h"
+ return count;
+}
diff --git a/gnu/lib/libg++/libg++/bitinvert.c b/gnu/lib/libg++/libg++/bitinvert.c
new file mode 100644
index 0000000..50f0369
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitinvert.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+void
+_BS_invert (ptr, offset, length)
+ register _BS_word *ptr;
+ int offset;
+ _BS_size_t length;
+{
+#undef DOIT
+#define DOIT(WORD, MASK) ((WORD) ^= (MASK))
+#include "bitdo1.h"
+}
diff --git a/gnu/lib/libg++/libg++/bitlcomp.c b/gnu/lib/libg++/libg++/bitlcomp.c
new file mode 100644
index 0000000..cbcb22e
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitlcomp.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+#include <stdlib.h>
+
+/* Return -1, 0, 1 depending on whether (ptr0, len0) is
+ lexicographically less than, equal, or greater than (ptr1, len1).
+ Both bitstrings must be left-aligned. */
+
+int
+_BS_lcompare_0 (ptr0, len0, ptr1, len1)
+ register _BS_word *ptr0;
+ _BS_size_t len0;
+ register _BS_word *ptr1;
+ _BS_size_t len1;
+{
+ _BS_size_t nwords0 = len0 / _BS_BITS_PER_WORD;
+ _BS_size_t nwords1 = len1 / _BS_BITS_PER_WORD;
+ register _BS_word word0, word1, mask;
+ _BS_size_t nwords = nwords0 > nwords1 ? nwords1 : nwords0;
+ for (; nwords != 0; nwords--)
+ {
+ word0 = *ptr0++;
+ word1 = *ptr1++;
+ if (word0 != word1)
+ {
+#if _BS_BIGENDIAN
+ return (word0 < word1) ? -1 : 1;
+#else
+ mask = 1;
+ for (;;)
+ {
+ int bit0 = word0 & 1;
+ int bit1 = word1 & 1;
+ int diff = bit0 - bit1;
+ if (diff)
+ return diff;
+ word0 >>= 1;
+ word1 >>= 1;
+ }
+#endif
+ }
+ }
+ len0 -= nwords0 * _BS_BITS_PER_WORD;
+ len1 -= nwords1 * _BS_BITS_PER_WORD;
+ if (len0 == 0 || len1 == 0)
+ return len0 == 0 - len1 == 0;
+ len0 &= _BS_BITS_PER_WORD - 1;
+ len1 &= _BS_BITS_PER_WORD - 1;
+ word0 = *ptr0++ & ~((_BS_word)(~0) _BS_RIGHT len0);
+ word1 = *ptr1++ & ~((_BS_word)(~0) _BS_RIGHT len1);
+ if (word0 == word1)
+ return len0 == len1 ? 0 : len0 < len1 ? -1 : 1;
+#if _BS_BIGENDIAN
+ return (word0 < word1) ? -1 : 1;
+#else
+ for (;;)
+ {
+ int bit0 = word0 & 1;
+ int bit1 = word1 & 1;
+ int diff = bit0 - bit1;
+ if (diff)
+ return diff;
+ word0 >>= 1;
+ word1 >>= 1;
+ }
+#endif
+}
+
diff --git a/gnu/lib/libg++/libg++/bitset1.c b/gnu/lib/libg++/libg++/bitset1.c
new file mode 100644
index 0000000..96e5ebd
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitset1.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+void
+_BS_set (ptr, offset, length)
+ register _BS_word *ptr;
+ int offset;
+ _BS_size_t length;
+{
+#undef DOIT
+#define DOIT(WORD, MASK) ((WORD) |= (MASK))
+#include "bitdo1.h"
+}
diff --git a/gnu/lib/libg++/libg++/bitxor.c b/gnu/lib/libg++/libg++/bitxor.c
new file mode 100644
index 0000000..0159bb4
--- /dev/null
+++ b/gnu/lib/libg++/libg++/bitxor.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU BitString 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.
+
+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 "bitprims.h"
+
+/* Copy LENGTH bits from (starting at SRCBIT) into pdst starting at DSTBIT.
+ This will work even if psrc & pdst overlap. */
+
+void
+_BS_xor (pdst, dstbit, psrc, srcbit, length)
+ register _BS_word* pdst;
+ int dstbit;
+ register const _BS_word* psrc;
+ int srcbit;
+ _BS_size_t length;
+{
+#define COMBINE(dst, src) (dst) ^ (src)
+#include "bitdo2.h"
+}
diff --git a/gnu/lib/libg++/libg++/builtin.cc b/gnu/lib/libg++/libg++/builtin.cc
new file mode 100644
index 0000000..6b9abe5
--- /dev/null
+++ b/gnu/lib/libg++/libg++/builtin.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
diff --git a/gnu/lib/libg++/libg++/chr.cc b/gnu/lib/libg++/libg++/chr.cc
new file mode 100644
index 0000000..d580a62
--- /dev/null
+++ b/gnu/lib/libg++/libg++/chr.cc
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <AllocRing.h>
+
+extern AllocRing _libgxx_fmtq;
+
+char* chr(char ch, int width)
+{
+ int len = 1;
+ int wrksiz = len + width + 1;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ char* fmt = fmtbase;
+ for (int blanks = width - len; blanks > 0; --blanks)
+ *fmt++ = ' ';
+ *fmt++ = ch;
+ *fmt = 0;
+ return fmtbase;
+}
diff --git a/gnu/lib/libg++/libg++/compare.cc b/gnu/lib/libg++/libg++/compare.cc
new file mode 100644
index 0000000..aae8409
--- /dev/null
+++ b/gnu/lib/libg++/libg++/compare.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <compare.h>
diff --git a/gnu/lib/libg++/libg++/error.cc b/gnu/lib/libg++/libg++/error.cc
new file mode 100644
index 0000000..852b3df
--- /dev/null
+++ b/gnu/lib/libg++/libg++/error.cc
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+#ifdef __GNUC__
+typedef _VOLATILE_VOID (*NoReturnFunc)(void);
+/* Cast abort to a _VOLATILE_VOID function, even if <stdlib.h> differs.
+This is to avoid a warning from g++ that a `volatile' function does return. */
+#define ABORT() ((NoReturnFunc)abort)()
+#else
+#define ABORT abort()
+#endif
+
+_VOLATILE_VOID default_one_arg_error_handler(const char* msg)
+{
+ fputs("Error: ", stderr);
+ fputs(msg, stderr);
+ fputs("\n", stderr);
+ ABORT();
+}
+
+
+_VOLATILE_VOID default_two_arg_error_handler(const char* kind, const char* msg)
+{
+ fputs(kind, stderr);
+ fputs(" Error: ", stderr);
+ fputs(msg, stderr);
+ fputs("\n", stderr);
+ ABORT();
+}
+
+two_arg_error_handler_t lib_error_handler = default_two_arg_error_handler;
+
+two_arg_error_handler_t set_lib_error_handler(two_arg_error_handler_t f)
+{
+ two_arg_error_handler_t old = lib_error_handler;
+ lib_error_handler = f;
+ return old;
+}
+
diff --git a/gnu/lib/libg++/libg++/fmtq.cc b/gnu/lib/libg++/libg++/fmtq.cc
new file mode 100644
index 0000000..7a9dd7b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/fmtq.cc
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <AllocRing.h>
+
+// AllocRings are used for output operations
+// We guaranteee that the last _libgxx_maxfmt formats
+// will be intact
+
+static const int _libgxx_maxfmt = 20;
+AllocRing _libgxx_fmtq(_libgxx_maxfmt);
diff --git a/gnu/lib/libg++/libg++/gcd.cc b/gnu/lib/libg++/libg++/gcd.cc
new file mode 100644
index 0000000..76ff0ef
--- /dev/null
+++ b/gnu/lib/libg++/libg++/gcd.cc
@@ -0,0 +1,52 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+
+/*
+ common functions on built-in types
+*/
+
+long gcd(long x, long y) // euclid's algorithm
+{
+ long a = abs(x);
+ long b = abs(y);
+
+ long tmp;
+
+ if (b > a)
+ {
+ tmp = a; a = b; b = tmp;
+ }
+ for(;;)
+ {
+ if (b == 0)
+ return a;
+ else if (b == 1)
+ return b;
+ else
+ {
+ tmp = b;
+ b = a % b;
+ a = tmp;
+ }
+ }
+}
diff --git a/gnu/lib/libg++/libg++/hash.cc b/gnu/lib/libg++/libg++/hash.cc
new file mode 100644
index 0000000..4f16f97
--- /dev/null
+++ b/gnu/lib/libg++/libg++/hash.cc
@@ -0,0 +1,56 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+/*
+ some useful hash functions
+*/
+
+unsigned int hashpjw(const char* x) // From Dragon book, p436
+{
+ unsigned int h = 0;
+ unsigned int g;
+
+ while (*x != 0)
+ {
+ h = (h << 4) + *x++;
+ if ((g = h & 0xf0000000) != 0)
+ h = (h ^ (g >> 24)) ^ g;
+ }
+ return h;
+}
+
+unsigned int multiplicativehash(int x)
+{
+ // uses a const close to golden ratio * pow(2,32)
+ return ((unsigned)x) * 2654435767;
+}
+
+
+unsigned int foldhash(double x)
+{
+ union { unsigned int i[2]; double d; } u;
+ u.d = x;
+ unsigned int u0 = u.i[0];
+ unsigned int u1 = u.i[1];
+ return u0 ^ u1;
+}
+
diff --git a/gnu/lib/libg++/libg++/ioob.cc b/gnu/lib/libg++/libg++/ioob.cc
new file mode 100644
index 0000000..08409a5
--- /dev/null
+++ b/gnu/lib/libg++/libg++/ioob.cc
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of GNU CC.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU CC General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU CC, but only under the conditions described in the
+GNU CC General Public License. A copy of this license is
+supposed to have been given to you along with GNU CC so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Obstack.h>
+
+// Obstacks are used as an easy way to allocate enough space
+// for various builtin input operations
+
+
+Obstack _libgxx_io_ob;
diff --git a/gnu/lib/libg++/libg++/lg.cc b/gnu/lib/libg++/libg++/lg.cc
new file mode 100644
index 0000000..b5ea5fd
--- /dev/null
+++ b/gnu/lib/libg++/libg++/lg.cc
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+long lg(unsigned long x)
+{
+ long l = 0;
+ while (x > 1)
+ {
+ x = x >> 1;
+ ++l;
+ }
+ return l;
+}
diff --git a/gnu/lib/libg++/libg++/math.cc b/gnu/lib/libg++/libg++/math.cc
new file mode 100644
index 0000000..f1a0e52
--- /dev/null
+++ b/gnu/lib/libg++/libg++/math.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <math.h>
diff --git a/gnu/lib/libg++/libg++/new.cc b/gnu/lib/libg++/libg++/new.cc
new file mode 100644
index 0000000..7a707a6
--- /dev/null
+++ b/gnu/lib/libg++/libg++/new.cc
@@ -0,0 +1,31 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <new.h>
+
+#if 0 /* ndef NO_LIBGXX_MALLOC */
+
+void* operator new(size_t n)
+{
+ return malloc (n);
+}
+#endif
diff --git a/gnu/lib/libg++/libg++/pow.cc b/gnu/lib/libg++/libg++/pow.cc
new file mode 100644
index 0000000..b56a8b7
--- /dev/null
+++ b/gnu/lib/libg++/libg++/pow.cc
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <math.h>
+
+double pow(double x, long p)
+{
+ if (p == 0)
+ return 1.0;
+ else if (x == 0.0)
+ return 0.0;
+ else
+ {
+ if (p < 0)
+ {
+ p = -p;
+ x = 1.0 / x;
+ }
+
+ double r = 1.0;
+ for(;;)
+ {
+ if (p & 1)
+ r *= x;
+ if ((p >>= 1) == 0)
+ return r;
+ else
+ x *= x;
+ }
+ }
+}
+
+long pow(long x, long p)
+{
+ if (p == 0)
+ return 1;
+ else if (p < 0 || x == 0)
+ return 0;
+ else
+ {
+ long r = 1;
+ for(;;)
+ {
+ if (p & 1)
+ r *= x;
+ if ((p >>= 1) == 0)
+ return r;
+ else
+ x *= x;
+ }
+ }
+}
diff --git a/gnu/lib/libg++/libg++/regex.cc b/gnu/lib/libg++/libg++/regex.cc
new file mode 100644
index 0000000..db23a51
--- /dev/null
+++ b/gnu/lib/libg++/libg++/regex.cc
@@ -0,0 +1,2757 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 1985, 1989-90 Free Software Foundation, Inc.
+
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+// This is a translation into C++ of regex.c, the GNU regexp package.
+
+/* To test, compile with -Dtest. This Dtestable feature turns this into
+ a self-contained program which reads a pattern, describes how it
+ compiles, then reads a string and searches for it.
+
+ On the other hand, if you compile with both -Dtest and -Dcanned you
+ can run some tests we've already thought of. */
+
+/* AIX requires the alloca decl to be the first thing in the file. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#ifdef sparc
+#include <alloca.h>
+extern "C" void *__builtin_alloca(...);
+#else
+#ifdef _AIX
+#pragma alloca
+#else
+char *alloca ();
+#endif
+#endif
+#endif
+
+#ifdef emacs
+
+/* The `emacs' switch turns on certain special matching commands
+ that make sense only in emacs. */
+
+#include "config.h"
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+#else /* not emacs */
+
+#include <_G_config.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Define the syntax stuff, so we can do the \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+#ifndef Sword
+#define Sword 1
+#endif
+
+#define SYNTAX(c) re_syntax_table[c]
+
+
+#ifdef SYNTAX_TABLE
+
+char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+static char re_syntax_table[256];
+
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ memset (re_syntax_table, 0, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ done = 1;
+}
+
+#endif /* SYNTAX_TABLE */
+#endif /* emacs */
+
+/* We write fatal error messages on standard error. */
+#include <stdio.h>
+
+/* isalpha(3) etc. are used for the character classes. */
+#include <ctype.h>
+/* Sequents are missing isgraph. */
+#ifndef isgraph
+#define isgraph(c) (isprint((c)) && !isspace((c)))
+#endif
+
+/* Get the interface, including the syntax bits. */
+#include "regex.h"
+
+
+/* These are the command codes that appear in compiled regular
+ expressions, one per byte. Some command codes are followed by
+ argument bytes. A command code can specify any interpretation
+ whatsoever for its arguments. Zero-bytes may appear in the compiled
+ regular expression.
+
+ The value of `exactn' is needed in search.c (search_buffer) in emacs.
+ So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
+ `exactn' we use here must also be 1. */
+
+enum regexpcode
+ {
+ unused=0,
+ exactn=1, /* Followed by one byte giving n, then by n literal bytes. */
+ begline, /* Fail unless at beginning of line. */
+ endline, /* Fail unless at end of line. */
+ jump, /* Followed by two bytes giving relative address to jump to. */
+ on_failure_jump, /* Followed by two bytes giving relative address of
+ place to resume at in case of failure. */
+ finalize_jump, /* Throw away latest failure point and then jump to
+ address. */
+ maybe_finalize_jump, /* Like jump but finalize if safe to do so.
+ This is used to jump back to the beginning
+ of a repeat. If the command that follows
+ this jump is clearly incompatible with the
+ one at the beginning of the repeat, such that
+ we can be sure that there is no use backtracking
+ out of repetitions already completed,
+ then we finalize. */
+ dummy_failure_jump, /* Jump, and push a dummy failure point. This
+ failure point will be thrown away if an attempt
+ is made to use it for a failure. A + construct
+ makes this before the first repeat. Also
+ use it as an intermediary kind of jump when
+ compiling an or construct. */
+ succeed_n, /* Used like on_failure_jump except has to succeed n times;
+ then gets turned into an on_failure_jump. The relative
+ address following it is useless until then. The
+ address is followed by two bytes containing n. */
+ jump_n, /* Similar to jump, but jump n times only; also the relative
+ address following is in turn followed by yet two more bytes
+ containing n. */
+ set_number_at, /* Set the following relative location to the
+ subsequent number. */
+ anychar, /* Matches any (more or less) one character. */
+ charset, /* Matches any one char belonging to specified set.
+ First following byte is number of bitmap bytes.
+ Then come bytes for a bitmap saying which chars are in.
+ Bits in each byte are ordered low-bit-first.
+ A character is in the set if its bit is 1.
+ A character too large to have a bit in the map
+ is automatically not in the set. */
+ charset_not, /* Same parameters as charset, but match any character
+ that is not one of those specified. */
+ start_memory, /* Start remembering the text that is matched, for
+ storing in a memory register. Followed by one
+ byte containing the register number. Register numbers
+ must be in the range 0 through RE_NREGS. */
+ stop_memory, /* Stop remembering the text that is matched
+ and store it in a memory register. Followed by
+ one byte containing the register number. Register
+ numbers must be in the range 0 through RE_NREGS. */
+ duplicate, /* Match a duplicate of something remembered.
+ Followed by one byte containing the index of the memory
+ register. */
+#ifdef emacs
+ before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+#endif
+ begbuf, /* Succeeds if at beginning of buffer. */
+ endbuf, /* Succeeds if at end of buffer. */
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+#ifdef emacs
+ ,syntaxspec, /* Matches any character whose syntax is specified.
+ followed by a byte which contains a syntax code,
+ e.g., Sword. */
+ notsyntaxspec /* Matches any character whose syntax differs from
+ that specified. */
+#endif
+ };
+
+
+/* Number of failure points to allocate space for initially,
+ when matching. If this number is exceeded, more space is allocated,
+ so it is not a hard limit. */
+
+#ifndef NFAILURES
+#define NFAILURES 80
+#endif
+
+
+#ifndef SIGN_EXTEND_CHAR
+#ifdef __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char)(c))
+#else
+#define SIGN_EXTEND_CHAR(c) (((c)^128) - 128) /* As in Harbison and Steele. */
+#endif
+#endif /* not SIGN_EXTEND_CHAR */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+#define STORE_NUMBER(destination, number) \
+ { (destination)[0] = (char)((number) & 0377); \
+ (destination)[1] = (number) >> 8; }
+
+/* Same as STORE_NUMBER, except increment the destination pointer to
+ the byte after where the number is stored. Watch out that values for
+ DESTINATION such as p + 1 won't work, whereas p will. */
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ { STORE_NUMBER(destination, number); \
+ (destination) += 2; }
+
+
+/* Put into DESTINATION a number stored in two contingous bytes starting
+ at SOURCE. */
+#define EXTRACT_NUMBER(destination, source) \
+ { (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*(char *)((source) + 1)) << 8; }
+
+/* Same as EXTRACT_NUMBER, except increment the pointer for source to
+ point to second byte of SOURCE. Note that SOURCE has to be a value
+ such as p, not, e.g., p + 1. */
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ { EXTRACT_NUMBER (destination, source); \
+ (source) += 2; }
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit-mask comprised of the various bits
+ defined in regex.h. */
+
+int
+re_set_syntax (int syntax)
+{
+ int ret;
+
+ ret = obscure_syntax;
+ obscure_syntax = syntax;
+ return ret;
+}
+
+/* Set by re_set_syntax to the current regexp syntax to recognize. */
+int obscure_syntax = 0;
+
+
+
+/* Macros for re_compile_pattern, which is found below these definitions. */
+
+#define CHAR_CLASS_MAX_LENGTH 6
+
+/* Fetch the next character in the uncompiled pattern, translating it if
+ necessary. */
+#define PATFETCH(c) \
+ {if (p == pend) goto end_of_pattern; \
+ c = * (const unsigned char *) p++; \
+ if (translate) c = translate[c]; }
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ {if (p == pend) goto end_of_pattern; \
+ c = * (const unsigned char *) p++; }
+
+#define PATUNFETCH p--
+
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 28
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ { \
+ while (b - bufp->buffer + (n) >= bufp->allocated) \
+ EXTEND_BUFFER; \
+ }
+
+/* Make sure we have one more byte of buffer space and then add CH to it. */
+#define BUFPUSH(ch) \
+ { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (char) (ch); \
+ }
+
+/* Extend the buffer by twice its current size via reallociation and
+ reset the pointers that pointed into the old allocation to point to
+ the correct places in the new allocation. If extending the buffer
+ results in it being larger than 1 << 16, then flag memory exhausted. */
+#define EXTEND_BUFFER \
+ { char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == (1L<<16)) goto too_big; \
+ bufp->allocated *= 2; \
+ if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16); \
+ bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated); \
+ if (bufp->buffer == 0) \
+ goto memory_exhausted; \
+ b = (b - old_buffer) + bufp->buffer; \
+ if (fixup_jump) \
+ fixup_jump = (fixup_jump - old_buffer) + bufp->buffer; \
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ }
+
+/* Set the bit for character C in a character set list. */
+#define SET_LIST_BIT(c) (b[(c) / BYTEWIDTH] |= 1 << ((c) % BYTEWIDTH))
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (isdigit (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+/* Subroutines for re_compile_pattern. */
+static void store_jump (char *from, char opcode, char *to);
+static void insert_jump (char op, char *from, char *to, char *current_end);
+static void store_jump_n (char *from, char opcode, char *to, unsigned n);
+static void insert_jump_n (char, char *, char *, char *, unsigned);
+static void insert_op_2 (char, char *, char *_end, int, int);
+
+
+/* re_compile_pattern takes a regular-expression string
+ and converts it into a buffer full of byte commands for matching.
+
+ PATTERN is the address of the pattern string
+ SIZE is the length of it.
+ BUFP is a struct re_pattern_buffer * which points to the info
+ on where to store the byte commands.
+ This structure contains a char * which points to the
+ actual space, which should have been obtained with malloc.
+ re_compile_pattern may use realloc to grow the buffer space.
+
+ The number of bytes of commands can be found out by looking in
+ the `struct re_pattern_buffer' that bufp pointed to, after
+ re_compile_pattern returns. */
+
+char *
+re_compile_pattern (const char *pattern, int size, struct re_pattern_buffer *bufp)
+{
+ register char *b = bufp->buffer;
+ register const char *p = pattern;
+ const char *pend = pattern + size;
+ register unsigned c, c1;
+ const char *p1;
+ unsigned char *translate = (unsigned char *) bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell whether a new exact-match
+ character can be added to that command or requires a new `exactn'
+ command. */
+
+ char *pending_exact = 0;
+
+ /* Address of the place where a forward-jump should go to the end of
+ the containing expression. Each alternative of an `or', except the
+ last, ends with a forward-jump of this sort. */
+
+ char *fixup_jump = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells postfix * where to find the start of its operand. */
+
+ char *laststart = 0;
+
+ /* In processing a repeat, 1 means zero matches is allowed. */
+
+ char zero_times_ok;
+
+ /* In processing a repeat, 1 means many matches is allowed. */
+
+ char many_times_ok;
+
+ /* Address of beginning of regexp, or inside of last \(. */
+
+ char *begalt = b;
+
+ /* In processing an interval, at least this many matches must be made. */
+ int lower_bound;
+
+ /* In processing an interval, at most this many matches can be made. */
+ int upper_bound;
+
+ /* Place in pattern (i.e., the {) to which to go back if the interval
+ is invalid. */
+ const char *beg_interval = 0;
+
+ /* Stack of information saved by \( and restored by \).
+ Four stack elements are pushed by each \(:
+ First, the value of b.
+ Second, the value of fixup_jump.
+ Third, the value of regnum.
+ Fourth, the value of begalt. */
+
+ int stackb[40];
+ int *stackp = stackb;
+ int *stacke = stackb + 40;
+ int *stackt;
+
+ /* Counts \('s as they are encountered. Remembered for the matching \),
+ where it becomes the register number to put in the stop_memory
+ command. */
+
+ unsigned regnum = 1;
+
+ bufp->fastmap_accurate = 0;
+
+#ifndef emacs
+#ifndef SYNTAX_TABLE
+ /* Initialize the syntax table. */
+ init_syntax_once();
+#endif
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ bufp->allocated = INIT_BUF_SIZE;
+ if (bufp->buffer)
+ /* EXTEND_BUFFER loses when bufp->allocated is 0. */
+ bufp->buffer = (char *) realloc (bufp->buffer, INIT_BUF_SIZE);
+ else
+ /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = (char *) malloc (INIT_BUF_SIZE);
+ if (!bufp->buffer) goto memory_exhausted;
+ begalt = b = bufp->buffer;
+ }
+
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '$':
+ {
+ const char *p1 = p;
+ /* When testing what follows the $,
+ look past the \-constructs that don't consume anything. */
+ if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ while (p1 != pend)
+ {
+ if (*p1 == '\\' && p1 + 1 != pend
+ && (p1[1] == '<' || p1[1] == '>'
+ || p1[1] == '`' || p1[1] == '\''
+#ifdef emacs
+ || p1[1] == '='
+#endif
+ || p1[1] == 'b' || p1[1] == 'B'))
+ p1 += 2;
+ else
+ break;
+ }
+ if (obscure_syntax & RE_TIGHT_VBAR)
+ {
+ if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p1 != pend)
+ goto normal_char;
+ /* Make operand of last vbar end before this `$'. */
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+ fixup_jump = 0;
+ BUFPUSH (endline);
+ break;
+ }
+ /* $ means succeed if at end of line, but only in special contexts.
+ If validly in the middle of a pattern, it is a normal character. */
+
+ if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS) && p1 != pend)
+ goto invalid_pattern;
+ if (p1 == pend || *p1 == '\n'
+ || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
+ || (obscure_syntax & RE_NO_BK_PARENS
+ ? *p1 == ')'
+ : *p1 == '\\' && p1[1] == ')')
+ || (obscure_syntax & RE_NO_BK_VBAR
+ ? *p1 == '|'
+ : *p1 == '\\' && p1[1] == '|'))
+ {
+ BUFPUSH (endline);
+ break;
+ }
+ goto normal_char;
+ }
+ case '^':
+ /* ^ means succeed if at beg of line, but only if no preceding
+ pattern. */
+
+ if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS) && laststart)
+ goto invalid_pattern;
+ if (laststart && p - 2 >= pattern && p[-2] != '\n'
+ && !(obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ if (obscure_syntax & RE_TIGHT_VBAR)
+ {
+ if (p != pattern + 1
+ && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ BUFPUSH (begline);
+ begalt = b;
+ }
+ else
+ BUFPUSH (begline);
+ break;
+
+ case '+':
+ case '?':
+ if ((obscure_syntax & RE_BK_PLUS_QM)
+ || (obscure_syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern, char not special. */
+ if (!laststart)
+ {
+ if (obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
+ goto invalid_pattern;
+ else if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+ /* If there is a sequence of repetition chars,
+ collapse it down to just one. */
+ zero_times_ok = 0;
+ many_times_ok = 0;
+ while (1)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+ if (p == pend)
+ break;
+ PATFETCH (c);
+ if (c == '*')
+ ;
+ else if (!(obscure_syntax & RE_BK_PLUS_QM)
+ && (c == '+' || c == '?'))
+ ;
+ else if ((obscure_syntax & RE_BK_PLUS_QM)
+ && c == '\\')
+ {
+ int c1;
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ {
+ /* If more than one repetition is allowed, put in at the
+ end a backward relative jump from b to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump). */
+ GET_BUFFER_SPACE (3);
+ store_jump (b, maybe_finalize_jump, laststart - 3);
+ b += 3; /* Because store_jump put stuff here. */
+ }
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ insert_jump (on_failure_jump, laststart, b + 3, b);
+ pending_exact = 0;
+ b += 3;
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ dummy-failure before the initial on-failure-jump
+ instruction of the loop. This effects a skip over that
+ instruction the first time we hit that loop. */
+ GET_BUFFER_SPACE (6);
+ insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
+ b += 3;
+ }
+ break;
+
+ case '.':
+ laststart = b;
+ BUFPUSH (anychar);
+ break;
+
+ case '[':
+ if (p == pend)
+ goto invalid_pattern;
+ while (b - bufp->buffer
+ > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
+ EXTEND_BUFFER;
+
+ laststart = b;
+ if (*p == '^')
+ {
+ BUFPUSH (charset_not);
+ p++;
+ }
+ else
+ BUFPUSH (charset);
+ p1 = p;
+
+ BUFPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+ /* Clear the whole map */
+ memset (b, 0, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ if ((obscure_syntax & RE_HAT_NOT_NEWLINE) && b[-2] == charset_not)
+ SET_LIST_BIT ('\n');
+
+
+ /* Read in characters and ranges, setting map bits. */
+ while (1)
+ {
+ /* Don't translate while fetching, in case it's a range bound.
+ When we set the bit for the character, we translate it. */
+ PATFETCH_RAW (c);
+
+ /* If set, \ escapes characters when inside [...]. */
+ if ((obscure_syntax & RE_AWK_CLASS_HACK) && c == '\\')
+ {
+ PATFETCH(c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+ if (c == ']')
+ {
+ if (p == p1 + 1)
+ {
+ /* If this is an empty bracket expression. */
+ if ((obscure_syntax & RE_NO_EMPTY_BRACKETS)
+ && p == pend)
+ goto invalid_pattern;
+ }
+ else
+ /* Stop if this isn't merely a ] inside a bracket
+ expression, but rather the end of a bracket
+ expression. */
+ break;
+ }
+ /* Get a range. */
+ if (p[0] == '-' && p[1] != ']')
+ {
+ PATFETCH (c1);
+ /* Don't translate the range bounds while fetching them. */
+ PATFETCH_RAW (c1);
+
+ if ((obscure_syntax & RE_NO_EMPTY_RANGES) && c > c1)
+ goto invalid_pattern;
+
+ if ((obscure_syntax & RE_NO_HYPHEN_RANGE_END)
+ && c1 == '-' && *p != ']')
+ goto invalid_pattern;
+
+ while (c <= c1)
+ {
+ /* Translate each char that's in the range. */
+ if (translate)
+ SET_LIST_BIT (translate[c]);
+ else
+ SET_LIST_BIT (c);
+ c++;
+ }
+ }
+ else if ((obscure_syntax & RE_CHAR_CLASSES)
+ && c == '[' && p[0] == ':')
+ {
+ /* Longest valid character class word has six characters. */
+ char str[CHAR_CLASS_MAX_LENGTH];
+ PATFETCH (c);
+ c1 = 0;
+ /* If no ] at end. */
+ if (p == pend)
+ goto invalid_pattern;
+ while (1)
+ {
+ /* Don't translate the ``character class'' characters. */
+ PATFETCH_RAW (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+ if (p == pend
+ || c == ']' /* End of the bracket expression. */
+ || p[0] != ']'
+ || p + 1 == pend
+ || (strcmp (str, "alpha") != 0
+ && strcmp (str, "upper") != 0
+ && strcmp (str, "lower") != 0
+ && strcmp (str, "digit") != 0
+ && strcmp (str, "alnum") != 0
+ && strcmp (str, "xdigit") != 0
+ && strcmp (str, "space") != 0
+ && strcmp (str, "print") != 0
+ && strcmp (str, "punct") != 0
+ && strcmp (str, "graph") != 0
+ && strcmp (str, "cntrl") != 0))
+ {
+ /* Undo the ending character, the letters, and leave
+ the leading : and [ (but set bits for them). */
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ }
+ else
+ {
+ /* The ] at the end of the character class. */
+ PATFETCH (c);
+ if (c != ']')
+ goto invalid_pattern;
+ for (c = 0; c < (1 << BYTEWIDTH); c++)
+ {
+ if ((strcmp (str, "alpha") == 0 && isalpha (c))
+ || (strcmp (str, "upper") == 0 && isupper (c))
+ || (strcmp (str, "lower") == 0 && islower (c))
+ || (strcmp (str, "digit") == 0 && isdigit (c))
+ || (strcmp (str, "alnum") == 0 && isalnum (c))
+ || (strcmp (str, "xdigit") == 0 && isxdigit (c))
+ || (strcmp (str, "space") == 0 && isspace (c))
+ || (strcmp (str, "print") == 0 && isprint (c))
+ || (strcmp (str, "punct") == 0 && ispunct (c))
+ || (strcmp (str, "graph") == 0 && isgraph (c))
+ || (strcmp (str, "cntrl") == 0 && iscntrl (c)))
+ SET_LIST_BIT (c);
+ }
+ }
+ }
+ else if (translate)
+ SET_LIST_BIT (translate[c]);
+ else
+ SET_LIST_BIT (c);
+ }
+
+ /* Discard any character set/class bitmap bytes that are all
+ 0 at the end of the map. Decrement the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ break;
+
+ case '(':
+ if (! (obscure_syntax & RE_NO_BK_PARENS))
+ goto normal_char;
+ else
+ goto handle_open;
+
+ case ')':
+ if (! (obscure_syntax & RE_NO_BK_PARENS))
+ goto normal_char;
+ else
+ goto handle_close;
+
+ case '\n':
+ if (! (obscure_syntax & RE_NEWLINE_OR))
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case '|':
+ if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
+ && (! laststart || p == pend))
+ goto invalid_pattern;
+ else if (! (obscure_syntax & RE_NO_BK_VBAR))
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case '{':
+ if (! ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ && (obscure_syntax & RE_INTERVALS)))
+ goto normal_char;
+ else
+ goto handle_interval;
+
+ case '\\':
+ if (p == pend) goto invalid_pattern;
+ PATFETCH_RAW (c);
+ switch (c)
+ {
+ case '(':
+ if (obscure_syntax & RE_NO_BK_PARENS)
+ goto normal_backsl;
+ handle_open:
+ if (stackp == stacke) goto nesting_too_deep;
+
+ /* Laststart should point to the start_memory that we are about
+ to push (unless the pattern has RE_NREGS or more ('s). */
+ *stackp++ = b - bufp->buffer;
+ if (regnum < RE_NREGS)
+ {
+ BUFPUSH (start_memory);
+ BUFPUSH (regnum);
+ }
+ *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
+ *stackp++ = regnum++;
+ *stackp++ = begalt - bufp->buffer;
+ fixup_jump = 0;
+ laststart = 0;
+ begalt = b;
+ break;
+
+ case ')':
+ if (obscure_syntax & RE_NO_BK_PARENS)
+ goto normal_backsl;
+ handle_close:
+ if (stackp == stackb) goto unmatched_close;
+ begalt = *--stackp + bufp->buffer;
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+ if (stackp[-1] < RE_NREGS)
+ {
+ BUFPUSH (stop_memory);
+ BUFPUSH (stackp[-1]);
+ }
+ stackp -= 2;
+ fixup_jump = *stackp ? *stackp + bufp->buffer - 1 : 0;
+ laststart = *--stackp + bufp->buffer;
+ break;
+
+ case '|':
+ if ((obscure_syntax & RE_LIMITED_OPS)
+ || (obscure_syntax & RE_NO_BK_VBAR))
+ goto normal_backsl;
+ handle_bar:
+ if (obscure_syntax & RE_LIMITED_OPS)
+ goto normal_char;
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (6);
+ insert_jump (on_failure_jump, begalt, b + 6, b);
+ pending_exact = 0;
+ b += 3;
+ /* The alternative before the previous alternative has a
+ jump after it which gets executed if it gets matched.
+ Adjust that jump so it will jump to the previous
+ alternative's analogous jump (put in below, which in
+ turn will jump to the next (if any) alternative's such
+ jump, etc.). The last such jump jumps to the correct
+ final destination. */
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+
+ /* Leave space for a jump after previous alternative---to be
+ filled in later. */
+ fixup_jump = b;
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+ case '{':
+ if (! (obscure_syntax & RE_INTERVALS)
+ /* Let \{ be a literal. */
+ || ((obscure_syntax & RE_INTERVALS)
+ && (obscure_syntax & RE_NO_BK_CURLY_BRACES))
+ /* If it's the string "\{". */
+ || (p - 2 == pattern && p == pend))
+ goto normal_backsl;
+ handle_interval:
+ beg_interval = p - 1; /* The {. */
+ /* If there is no previous pattern, this isn't an interval. */
+ if (!laststart)
+ {
+ if (obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
+ goto invalid_pattern;
+ else
+ goto normal_backsl;
+ }
+ /* It also isn't an interval if not preceded by an re
+ matching a single character or subexpression, or if
+ the current type of intervals can't handle back
+ references and the previous thing is a back reference. */
+ if (! (*laststart == anychar
+ || *laststart == charset
+ || *laststart == charset_not
+ || *laststart == start_memory
+ || (*laststart == exactn && laststart[1] == 1)
+ || (! (obscure_syntax & RE_NO_BK_REFS)
+ && *laststart == duplicate)))
+ {
+ if (obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ goto normal_char;
+
+ /* Posix extended syntax is handled in previous
+ statement; this is for Posix basic syntax. */
+ if (obscure_syntax & RE_INTERVALS)
+ goto invalid_pattern;
+
+ goto normal_backsl;
+ }
+ lower_bound = -1; /* So can see if are set. */
+ upper_bound = -1;
+ GET_UNSIGNED_NUMBER (lower_bound);
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0)
+ upper_bound = RE_DUP_MAX;
+ }
+ if (upper_bound < 0)
+ upper_bound = lower_bound;
+ if (! (obscure_syntax & RE_NO_BK_CURLY_BRACES))
+ {
+ if (c != '\\')
+ goto invalid_pattern;
+ PATFETCH (c);
+ }
+ if (c != '}' || lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound
+ || ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ && p != pend && *p == '{'))
+ {
+ if (obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ goto unfetch_interval;
+ else
+ goto invalid_pattern;
+ }
+
+ /* If upper_bound is zero, don't want to succeed at all;
+ jump from laststart to b + 3, which will be the end of
+ the buffer after this jump is inserted. */
+
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ insert_jump (jump, laststart, b + 3, b);
+ b += 3;
+ }
+
+ /* Otherwise, after lower_bound number of succeeds, jump
+ to after the jump_n which will be inserted at the end
+ of the buffer, and insert that jump_n. */
+ else
+ { /* Set to 5 if only one repetition is allowed and
+ hence no jump_n is inserted at the current end of
+ the buffer; then only space for the succeed_n is
+ needed. Otherwise, need space for both the
+ succeed_n and the jump_n. */
+
+ unsigned slots_needed = upper_bound == 1 ? 5 : 10;
+
+ GET_BUFFER_SPACE ((int) slots_needed);
+ /* Initialize the succeed_n to n, even though it will
+ be set by its attendant set_number_at, because
+ re_compile_fastmap will need to know it. Jump to
+ what the end of buffer will be after inserting
+ this succeed_n and possibly appending a jump_n. */
+ insert_jump_n (succeed_n, laststart, b + slots_needed,
+ b, lower_bound);
+ b += 5; /* Just increment for the succeed_n here. */
+
+ /* More than one repetition is allowed, so put in at
+ the end of the buffer a backward jump from b to the
+ succeed_n we put in above. By the time we've gotten
+ to this jump when matching, we'll have matched once
+ already, so jump back only upper_bound - 1 times. */
+
+ if (upper_bound > 1)
+ {
+ store_jump_n (b, jump_n, laststart, upper_bound - 1);
+ b += 5;
+ /* When hit this when matching, reset the
+ preceding jump_n's n to upper_bound - 1. */
+ BUFPUSH (set_number_at);
+ GET_BUFFER_SPACE (2);
+ STORE_NUMBER_AND_INCR (b, -5);
+ STORE_NUMBER_AND_INCR (b, upper_bound - 1);
+ }
+ /* When hit this when matching, set the succeed_n's n. */
+ GET_BUFFER_SPACE (5);
+ insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
+ b += 5;
+ }
+ pending_exact = 0;
+ beg_interval = 0;
+ break;
+
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ if (beg_interval)
+ p = beg_interval;
+ else
+ {
+ fprintf (stderr,
+ "regex: no interval beginning to which to backtrack.\n");
+ exit (1);
+ }
+
+ beg_interval = 0;
+ PATFETCH (c); /* normal_char expects char in `c'. */
+ goto normal_char;
+ break;
+
+#ifdef emacs
+ case '=':
+ BUFPUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ BUFPUSH (syntaxspec);
+ PATFETCH (c);
+ BUFPUSH (syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ BUFPUSH (notsyntaxspec);
+ PATFETCH (c);
+ BUFPUSH (syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+ case 'w':
+ laststart = b;
+ BUFPUSH (wordchar);
+ break;
+
+ case 'W':
+ laststart = b;
+ BUFPUSH (notwordchar);
+ break;
+
+ case '<':
+ BUFPUSH (wordbeg);
+ break;
+
+ case '>':
+ BUFPUSH (wordend);
+ break;
+
+ case 'b':
+ BUFPUSH (wordbound);
+ break;
+
+ case 'B':
+ BUFPUSH (notwordbound);
+ break;
+
+ case '`':
+ BUFPUSH (begbuf);
+ break;
+
+ case '\'':
+ BUFPUSH (endbuf);
+ break;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (obscure_syntax & RE_NO_BK_REFS)
+ goto normal_char;
+ c1 = c - '0';
+ if (c1 >= regnum)
+ {
+ if (obscure_syntax & RE_NO_EMPTY_BK_REF)
+ goto invalid_pattern;
+ else
+ goto normal_char;
+ }
+ /* Can't back reference to a subexpression if inside of it. */
+ for (stackt = stackp - 2; stackt > stackb; stackt -= 4)
+ if (*stackt == c1)
+ goto normal_char;
+ laststart = b;
+ BUFPUSH (duplicate);
+ BUFPUSH (c1);
+ break;
+
+ case '+':
+ case '?':
+ if (obscure_syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backsl;
+ break;
+
+ default:
+ normal_backsl:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ if (translate) c = translate[c];
+ goto normal_char;
+ }
+ break;
+
+ default:
+ normal_char: /* Expects the character in `c'. */
+ if (!pending_exact || pending_exact + *pending_exact + 1 != b
+ || *pending_exact == 0177 || *p == '*' || *p == '^'
+ || ((obscure_syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((obscure_syntax & RE_INTERVALS)
+ && ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ laststart = b;
+ BUFPUSH (exactn);
+ pending_exact = b;
+ BUFPUSH (0);
+ }
+ BUFPUSH (c);
+ (*pending_exact)++;
+ }
+ }
+
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+
+ if (stackp != stackb) goto unmatched_open;
+
+ bufp->used = b - bufp->buffer;
+ return 0;
+
+ invalid_pattern:
+ return "Invalid regular expression";
+
+ unmatched_open:
+ return "Unmatched \\(";
+
+ unmatched_close:
+ return "Unmatched \\)";
+
+ end_of_pattern:
+ return "Premature end of regular expression";
+
+ nesting_too_deep:
+ return "Nesting too deep";
+
+ too_big:
+ return "Regular expression too big";
+
+ memory_exhausted:
+ return "Memory exhausted";
+}
+
+
+/* Store a jump of the form <OPCODE> <relative address>.
+ Store in the location FROM a jump operation to jump to relative
+ address FROM - TO. OPCODE is the opcode to store. */
+
+static void
+store_jump (char *from, char opcode, char *to)
+{
+ from[0] = opcode;
+ STORE_NUMBER(from + 1, to - (from + 3));
+}
+
+
+/* Open up space before char FROM, and insert there a jump to TO.
+ CURRENT_END gives the end of the storage not in use, so we know
+ how much data to copy up. OP is the opcode of the jump to insert.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+insert_jump (char op, char *from, char *to, char *current_end)
+{
+ register char *pfrom = current_end; /* Copy from here... */
+ register char *pto = current_end + 3; /* ...to here. */
+
+ while (pfrom != from)
+ *--pto = *--pfrom;
+ store_jump (from, op, to);
+}
+
+
+/* Store a jump of the form <opcode> <relative address> <n> .
+
+ Store in the location FROM a jump operation to jump to relative
+ address FROM - TO. OPCODE is the opcode to store, N is a number the
+ jump uses, say, to decide how many times to jump.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+store_jump_n (char *from, char opcode, char *to, unsigned n)
+{
+ from[0] = opcode;
+ STORE_NUMBER (from + 1, to - (from + 3));
+ STORE_NUMBER (from + 3, n);
+}
+
+
+/* Similar to insert_jump, but handles a jump which needs an extra
+ number to handle minimum and maximum cases. Open up space at
+ location FROM, and insert there a jump to TO. CURRENT_END gives the
+ end of the storage in use, so we know how much data to copy up. OP is
+ the opcode of the jump to insert.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+insert_jump_n (char op, char *from, char *to, char *current_end, unsigned n)
+{
+ register char *pfrom = current_end; /* Copy from here... */
+ register char *pto = current_end + 5; /* ...to here. */
+
+ while (pfrom != from)
+ *--pto = *--pfrom;
+ store_jump_n (from, op, to, n);
+}
+
+
+/* Open up space at location THERE, and insert operation OP followed by
+ NUM_1 and NUM_2. CURRENT_END gives the end of the storage in use, so
+ we know how much data to copy up.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+insert_op_2 (char op, char *there, char *current_end, int num_1, int num_2)
+{
+ register char *pfrom = current_end; /* Copy from here... */
+ register char *pto = current_end + 5; /* ...to here. */
+
+ while (pfrom != there)
+ *--pto = *--pfrom;
+
+ there[0] = op;
+ STORE_NUMBER (there + 1, num_1);
+ STORE_NUMBER (there + 3, num_2);
+}
+
+
+
+/* Given a pattern, compute a fastmap from it. The fastmap records
+ which of the (1 << BYTEWIDTH) possible characters can start a string
+ that matches the pattern. This fastmap is used by re_search to skip
+ quickly over totally implausible text.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as bufp->fastmap.
+ The other components of bufp describe the pattern to be used. */
+
+void
+re_compile_fastmap (struct re_pattern_buffer *bufp)
+{
+ unsigned char *pattern = (unsigned char *) bufp->buffer;
+ int size = bufp->used;
+ register char *fastmap = bufp->fastmap;
+ register unsigned char *p = pattern;
+ register unsigned char *pend = pattern + size;
+ register int j, k;
+ unsigned char *translate = (unsigned char *) bufp->translate;
+
+ unsigned char *stackb[NFAILURES];
+ unsigned char **stackp = stackb;
+
+ unsigned is_a_succeed_n;
+
+ memset (fastmap, 0, (1 << BYTEWIDTH));
+ bufp->fastmap_accurate = 1;
+ bufp->can_be_null = 0;
+
+ while (p)
+ {
+ is_a_succeed_n = 0;
+ if (p == pend)
+ {
+ bufp->can_be_null = 1;
+ break;
+ }
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((enum regexpcode) *p++))
+#else
+ switch ((enum regexpcode) *p++)
+#endif
+ {
+ case exactn:
+ if (translate)
+ fastmap[translate[p[1]]] = 1;
+ else
+ fastmap[p[1]] = 1;
+ break;
+
+ case unused:
+ case begline:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ continue;
+
+ case endline:
+ if (translate)
+ fastmap[translate['\n']] = 1;
+ else
+ fastmap['\n'] = 1;
+
+ if (bufp->can_be_null != 1)
+ bufp->can_be_null = 2;
+ break;
+
+ case jump_n:
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+ /* Jump backward reached implies we just went through
+ the body of a loop and matched nothing.
+ Opcode jumped to should be an on_failure_jump.
+ Just treat it like an ordinary jump.
+ For a * loop, it has pushed its failure point already;
+ If so, discard that as redundant. */
+
+ if ((enum regexpcode) *p != on_failure_jump
+ && (enum regexpcode) *p != succeed_n)
+ continue;
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (stackp != stackb && *stackp == p)
+ stackp--;
+ continue;
+
+ case on_failure_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ *++stackp = p + j;
+ if (is_a_succeed_n)
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ continue;
+
+ case succeed_n:
+ is_a_succeed_n = 1;
+ /* Get to the number of times to succeed. */
+ p += 2;
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+ case start_memory:
+ case stop_memory:
+ p++;
+ continue;
+
+ case duplicate:
+ bufp->can_be_null = 1;
+ fastmap['\n'] = 1;
+ case anychar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (j != '\n')
+ fastmap[j] = 1;
+ if (bufp->can_be_null)
+ return;
+ /* Don't return; check the alternative paths
+ so we can set can_be_null if appropriate. */
+ break;
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+#endif /* not emacs */
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ {
+ if (translate)
+ fastmap[translate[j]] = 1;
+ else
+ fastmap[j] = 1;
+ }
+ break;
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ if (translate)
+ fastmap[translate[j]] = 1;
+ else
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ {
+ if (translate)
+ fastmap[translate[j]] = 1;
+ else
+ fastmap[j] = 1;
+ }
+ break;
+ }
+
+ /* Get here means we have successfully found the possible starting
+ characters of one path of the pattern. We need not follow this
+ path any farther. Instead, look at the next alternative
+ remembered in the stack. */
+ if (stackp != stackb)
+ p = *stackp--;
+ else
+ break;
+ }
+}
+
+
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (struct re_pattern_buffer *pbufp,
+ char *string,
+ int size,
+ int startpos,
+ int range,
+ struct re_registers *regs)
+{
+ return re_search_2 (pbufp, (char *) 0, 0, string, size, startpos, range,
+ regs, size);
+}
+
+
+/* Using the compiled pattern in PBUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on. RANGE is the number of
+ places to try before giving up. If RANGE is negative, it searches
+ backwards, i.e., the starting positions tried are STARTPOS, STARTPOS
+ - 1, etc. STRING1 and STRING2 are of SIZE1 and SIZE2, respectively.
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire PBUFP->buffer and its contained
+ subexpressions. Do not consider matching one past the index MSTOP in
+ the virtual concatenation of STRING1 and STRING2.
+
+ The value returned is the position in the strings at which the match
+ was found, or -1 if no match was found, or -2 if error (such as
+ failure stack overflow). */
+
+int
+re_search_2 (struct re_pattern_buffer *pbufp,
+ char *string1, int size1,
+ char *string2, int size2,
+ int startpos,
+ register int range,
+ struct re_registers *regs,
+ int mstop)
+{
+ register char *fastmap = pbufp->fastmap;
+ register unsigned char *translate = (unsigned char *) pbufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+ int val;
+
+ /* Check for out-of-range starting position. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up range if it would eventually take startpos outside of the
+ virtual concatenation of string1 and string2. */
+ if (endpos < -1)
+ range = -1 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !pbufp->fastmap_accurate)
+ re_compile_fastmap (pbufp);
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ long search for a pattern that says it is anchored. */
+ if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
+ && range > 0)
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+ while (1)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot possibly be the start of a match. Note, however, that
+ if the pattern can possibly match the null string, we must
+ test it at each starting point so that we take the first null
+ string we get. */
+
+ if (fastmap && startpos < total_size && pbufp->can_be_null != 1)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register int lim = 0;
+ register unsigned char *p;
+ int irange = range;
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ p = ((unsigned char *)
+ &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
+
+ while (range > lim && !fastmap[translate
+ ? translate[*p++]
+ : *p++])
+ range--;
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register unsigned char c;
+
+ if (string1 == 0 || startpos >= size1)
+ c = string2[startpos - size1];
+ else
+ c = string1[startpos];
+
+ c &= 0xff;
+ if (translate ? !fastmap[translate[c]] : !fastmap[c])
+ goto advance;
+ }
+ }
+
+ if (range >= 0 && startpos == total_size
+ && fastmap && pbufp->can_be_null == 0)
+ return -1;
+
+ val = re_match_2 (pbufp, string1, size1, string2, size2, startpos,
+ regs, mstop);
+ if (val >= 0)
+ return startpos;
+ if (val == -2)
+ return -2;
+
+#ifdef C_ALLOCA
+ alloca (0);
+#endif /* C_ALLOCA */
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+}
+
+
+
+#ifndef emacs /* emacs never uses this. */
+int
+re_match (struct re_pattern_buffer *pbufp,
+ char *string,
+ int size,
+ int pos,
+ struct re_registers *regs)
+{
+ return re_match_2 (pbufp, (char *) 0, 0, string, size, pos, regs, size);
+}
+#endif /* not emacs */
+
+
+/* The following are used for re_match_2, defined below: */
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always pushed MAX_NUM_FAILURE_ITEMS each time we failed. */
+
+int re_max_failures = 2000;
+
+/* Routine used by re_match_2. */
+static int bcmp_translate (char *, char *, int, unsigned char *);
+
+
+/* Structure and accessing macros used in re_match_2: */
+
+struct register_info
+{
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+};
+
+#define IS_ACTIVE(R) ((R).is_active)
+#define MATCHED_SOMETHING(R) ((R).matched_something)
+
+
+/* Macros used by re_match_2: */
+
+
+/* I.e., regstart, regend, and reg_info. */
+
+#define NUM_REG_ITEMS 3
+
+/* We push at most this many things on the stack whenever we
+ fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are
+ arguments to the PUSH_FAILURE_POINT macro. */
+
+#define MAX_NUM_FAILURE_ITEMS (RE_NREGS * NUM_REG_ITEMS + 2)
+
+
+/* We push this many things on the stack whenever we fail. */
+
+#define NUM_FAILURE_ITEMS (last_used_reg * NUM_REG_ITEMS + 2)
+
+
+/* This pushes most of the information about the current state we will want
+ if we ever fail back to it. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place) \
+ { \
+ short last_used_reg, this_reg; \
+ \
+ /* Find out how many registers are active or have been matched. \
+ (Aside from register zero, which is only set at the end.) */ \
+ for (last_used_reg = RE_NREGS - 1; last_used_reg > 0; last_used_reg--)\
+ if (regstart[last_used_reg] != (unsigned char *) -1) \
+ break; \
+ \
+ if (stacke - stackp < NUM_FAILURE_ITEMS) \
+ { \
+ unsigned char **stackx; \
+ int len = stacke - stackb; \
+ if (len > re_max_failures * MAX_NUM_FAILURE_ITEMS) \
+ return -2; \
+ \
+ /* Roughly double the size of the stack. */ \
+ stackx = (unsigned char **) alloca (2 * len \
+ * sizeof (unsigned char *));\
+ /* Only copy what is in use. */ \
+ memcpy (stackx, stackb, len * sizeof (char *)); \
+ stackp = stackx + (stackp - stackb); \
+ stackb = stackx; \
+ stacke = stackb + 2 * len; \
+ } \
+ \
+ /* Now push the info for each of those registers. */ \
+ for (this_reg = 1; this_reg <= last_used_reg; this_reg++) \
+ { \
+ *stackp++ = regstart[this_reg]; \
+ *stackp++ = regend[this_reg]; \
+ *stackp++ = (unsigned char *) &reg_info[this_reg]; \
+ } \
+ \
+ /* Push how many registers we saved. */ \
+ *stackp++ = (unsigned char *) last_used_reg; \
+ \
+ *stackp++ = pattern_place; \
+ *stackp++ = string_place; \
+ }
+
+
+/* This pops what PUSH_FAILURE_POINT pushes. */
+
+#define POP_FAILURE_POINT() \
+ { \
+ int temp; \
+ stackp -= 2; /* Remove failure points. */ \
+ temp = (int) *--stackp; /* How many regs pushed. */ \
+ temp *= NUM_REG_ITEMS; /* How much to take off the stack. */ \
+ stackp -= temp; /* Remove the register info. */ \
+ }
+
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Is true if there is a first string and if PTR is pointing anywhere
+ inside it or just past the end. */
+
+#define IS_IN_FIRST_STRING(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+
+#define PREFETCH \
+ while (d == dend) \
+ { \
+ /* end of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* end of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Call this when have matched something; it sets `matched' flags for the
+ registers corresponding to the subexpressions of which we currently
+ are inside. */
+#define SET_REGS_MATCHED \
+ { unsigned this_reg; \
+ for (this_reg = 0; this_reg < RE_NREGS; this_reg++) \
+ { \
+ if (IS_ACTIVE(reg_info[this_reg])) \
+ MATCHED_SOMETHING(reg_info[this_reg]) = 1; \
+ else \
+ MATCHED_SOMETHING(reg_info[this_reg]) = 0; \
+ } \
+ }
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of string1 and string2. If there is only one string, we've put it in
+ string2. */
+
+#define AT_STRINGS_BEG (d == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END (d == end2)
+
+#define AT_WORD_BOUNDARY \
+ (AT_STRINGS_BEG || AT_STRINGS_END || IS_A_LETTER (d - 1) != IS_A_LETTER (d))
+
+/* We have two special cases to check for:
+ 1) if we're past the end of string1, we have to look at the first
+ character in string2;
+ 2) if we're before the beginning of string2, we have to look at the
+ last character in string1; we assume there is a string1, so use
+ this in conjunction with AT_STRINGS_BEG. */
+#define IS_A_LETTER(d) \
+ (SYNTAX ((d) == end1 ? *string2 : (d) == string2 - 1 ? *(end1 - 1) : *(d))\
+ == Sword)
+
+
+/* Match the pattern described by PBUFP against the virtual
+ concatenation of STRING1 and STRING2, which are of SIZE1 and SIZE2,
+ respectively. Start the match at index POS in the virtual
+ concatenation of STRING1 and STRING2. In REGS, return the indices of
+ the virtual concatenation of STRING1 and STRING2 that matched the
+ entire PBUFP->buffer and its contained subexpressions. Do not
+ consider matching one past the index MSTOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ If pbufp->fastmap is nonzero, then it had better be up to date.
+
+ The reason that the data to match are specified as two components
+ which are to be regarded as concatenated is so this function can be
+ used directly on the contents of an Emacs buffer.
+
+ -1 is returned if there is no match. -2 is returned if there is an
+ error (such as match stack overflow). Otherwise the value is the
+ length of the substring which was matched. */
+
+int
+re_match_2 (struct re_pattern_buffer *pbufp,
+ char *string1_arg, int size1,
+ char *string2_arg, int size2,
+ int pos,
+ struct re_registers *regs,
+ int mstop)
+{
+ register unsigned char *p = (unsigned char *) pbufp->buffer;
+
+ /* Pointer to beyond end of buffer. */
+ register unsigned char *pend = p + pbufp->used;
+
+ unsigned char *string1 = (unsigned char *) string1_arg;
+ unsigned char *string2 = (unsigned char *) string2_arg;
+ unsigned char *end1; /* Just past end of first string. */
+ unsigned char *end2; /* Just past end of second string. */
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ unsigned char *end_match_1, *end_match_2;
+
+ register unsigned char *d, *dend;
+ register int mcnt; /* Multipurpose. */
+ unsigned char *translate = (unsigned char *) pbufp->translate;
+ unsigned is_a_jump_n = 0;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to the
+ subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where to
+ resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is a
+ ``dummy''; if a failure happens and the failure point is a dummy, it
+ gets discarded and the next next one is tried. */
+
+ unsigned char *initial_stack[MAX_NUM_FAILURE_ITEMS * NFAILURES];
+ unsigned char **stackb = initial_stack;
+ unsigned char **stackp = stackb;
+ unsigned char **stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES];
+
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+
+ unsigned char *regstart[RE_NREGS];
+ unsigned char *regend[RE_NREGS];
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+
+ struct register_info reg_info[RE_NREGS];
+
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+
+ unsigned best_regs_set = 0;
+ unsigned char *best_regstart[RE_NREGS];
+ unsigned char *best_regend[RE_NREGS];
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ \( or ( and \) or ) has been seen for. Also set all registers to
+ inactive and mark them as not having matched anything or ever
+ failed. */
+ for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt] = (unsigned char *) -1;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ if (regs)
+ for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+
+ /* Set up pointers to ends of strings.
+ Don't allow the second string to be empty unless both are empty. */
+ if (size2 == 0)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (mstop <= size1)
+ {
+ end_match_1 = string1 + mstop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + mstop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data. `dend'
+ is the end of the input string that `d' points within. `d' is
+ advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal string2. */
+
+ if (size1 != 0 && pos <= size1)
+ d = string1 + pos, dend = end_match_1;
+ else
+ d = string2 + pos - size1, dend = end_match_2;
+
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if match is complete, or it drops through if match fails
+ at this starting point in the input data. */
+
+ while (1)
+ {
+ is_a_jump_n = 0;
+ /* End of pattern means we might have succeeded. */
+ if (p == pend)
+ {
+ /* If not end of string, try backtracking. Otherwise done. */
+ if (d != end_match_2)
+ {
+ if (stackp != stackb)
+ {
+ /* More failure points to try. */
+
+ unsigned in_same_string =
+ IS_IN_FIRST_STRING (best_regend[0])
+ == MATCHING_IN_FIRST_STRING;
+
+ /* If exceeds best match so far, save it. */
+ if (! best_regs_set
+ || (in_same_string && d > best_regend[0])
+ || (! in_same_string && ! MATCHING_IN_FIRST_STRING))
+ {
+ best_regs_set = 1;
+ best_regend[0] = d; /* Never use regstart[0]. */
+
+ for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+ /* If no failure points, don't restore garbage. */
+ else if (best_regs_set)
+ {
+ restore_best_regs:
+ /* Restore best match. */
+ d = best_regend[0];
+
+ for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ }
+
+ /* If caller wants register contents data back, convert it
+ to indices. */
+ if (regs)
+ {
+ regs->start[0] = pos;
+ if (MATCHING_IN_FIRST_STRING)
+ regs->end[0] = d - string1;
+ else
+ regs->end[0] = d - string2 + size1;
+ for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
+ {
+ if (regend[mcnt] == (unsigned char *) -1)
+ {
+ regs->start[mcnt] = -1;
+ regs->end[mcnt] = -1;
+ continue;
+ }
+ if (IS_IN_FIRST_STRING (regstart[mcnt]))
+ regs->start[mcnt] = regstart[mcnt] - string1;
+ else
+ regs->start[mcnt] = regstart[mcnt] - string2 + size1;
+
+ if (IS_IN_FIRST_STRING (regend[mcnt]))
+ regs->end[mcnt] = regend[mcnt] - string1;
+ else
+ regs->end[mcnt] = regend[mcnt] - string2 + size1;
+ }
+ }
+ return d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+ }
+
+ /* Otherwise match next pattern command. */
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((enum regexpcode) *p++))
+#else
+ switch ((enum regexpcode) *p++)
+#endif
+ {
+
+ /* \( [or `(', as appropriate] is represented by start_memory,
+ \) by stop_memory. Both of those commands are followed by
+ a register number in the next byte. The text matched
+ within the \( and \) is recorded under that number. */
+ case start_memory:
+ regstart[*p] = d;
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+ p++;
+ break;
+
+ case stop_memory:
+ regend[*p] = d;
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* If just failed to match something this time around with a sub-
+ expression that's in a loop, try to force exit from the loop. */
+ if ((! MATCHED_SOMETHING (reg_info[*p])
+ || (enum regexpcode) p[-3] == start_memory)
+ && (p + 1) != pend)
+ {
+ register unsigned char *p2 = p + 1;
+ mcnt = 0;
+ switch (*p2++)
+ {
+ case jump_n:
+ is_a_jump_n = 1;
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p2);
+ if (is_a_jump_n)
+ p2 += 2;
+ break;
+ }
+ p2 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump, exit from the loop by forcing a
+ failure after pushing on the stack the on_failure_jump's
+ jump in the pattern, and d. */
+ if (mcnt < 0 && (enum regexpcode) *p2++ == on_failure_jump)
+ {
+ EXTRACT_NUMBER_AND_INCR (mcnt, p2);
+ PUSH_FAILURE_POINT (p2 + mcnt, d);
+ goto fail;
+ }
+ }
+ p++;
+ break;
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ int regno = *p++; /* Get which register to match against */
+ register unsigned char *d2, *dend2;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((IS_IN_FIRST_STRING (regstart[regno])
+ == IS_IN_FIRST_STRING (regend[regno]))
+ ? regend[regno] : end_match_1);
+ while (1)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+ d2 = string2, dend2 = regend[regno]; /* end of string1 => advance to string2. */
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH;
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate ((char*)d, (char*)d2, mcnt, translate)
+ : memcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+ }
+ }
+ break;
+
+ case anychar:
+ PREFETCH; /* Fetch a data character. */
+ /* Match anything but a newline, maybe even a null. */
+ if ((translate ? translate[*d] : *d) == '\n'
+ || ((obscure_syntax & RE_DOT_NOT_NULL)
+ && (translate ? translate[*d] : *d) == '\000'))
+ goto fail;
+ SET_REGS_MATCHED;
+ d++;
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ int not = 0; /* Nonzero for charset_not. */
+ register int c;
+ if (*(p - 1) == (unsigned char) charset_not)
+ not = 1;
+
+ PREFETCH; /* Fetch a data character. */
+
+ if (translate)
+ c = translate[*d];
+ else
+ c = *d;
+
+ if (c < *p * BYTEWIDTH
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+ SET_REGS_MATCHED;
+ d++;
+ break;
+ }
+
+ case begline:
+ if ((size1 != 0 && d == string1)
+ || (size1 == 0 && size2 != 0 && d == string2)
+ || (d && d[-1] == '\n')
+ || (size1 == 0 && size2 == 0))
+ break;
+ else
+ goto fail;
+
+ case endline:
+ if (d == end2
+ || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
+ break;
+ goto fail;
+
+ /* `or' constructs are handled by starting each alternative with
+ an on_failure_jump that points to the start of the next
+ alternative. Each alternative except the last ends with a
+ jump to the joining point. (Actually, each jump except for
+ the last one really jumps to the following jump, because
+ tensioning the jumps is a hassle.) */
+
+ /* The start of a stupid repeat has an on_failure_jump that points
+ past the end of the repeat text. This makes a failure point so
+ that on failure to match a repetition, matching restarts past
+ as many repetitions have been found with no way to fail and
+ look for another one. */
+
+ /* A smart repeat is similar but loops back to the on_failure_jump
+ so that each repetition makes another failure point. */
+
+ case on_failure_jump:
+ on_failure:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ PUSH_FAILURE_POINT (p + mcnt, d);
+ break;
+
+ /* The end of a smart repeat has a maybe_finalize_jump back.
+ Change it either to a finalize_jump or an ordinary jump. */
+ case maybe_finalize_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ {
+ register unsigned char *p2 = p;
+ /* Compare what follows with the beginning of the repeat.
+ If we can establish that there is nothing that they would
+ both match, we can change to finalize_jump. */
+ while (p2 + 1 != pend
+ && (*p2 == (unsigned char) stop_memory
+ || *p2 == (unsigned char) start_memory))
+ p2 += 2; /* Skip over reg number. */
+ if (p2 == pend)
+ p[-3] = (unsigned char) finalize_jump;
+ else if (*p2 == (unsigned char) exactn
+ || *p2 == (unsigned char) endline)
+ {
+ register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
+ register unsigned char *p1 = p + mcnt;
+ /* p1[0] ... p1[2] are an on_failure_jump.
+ Examine what follows that. */
+ if (p1[3] == (unsigned char) exactn && p1[5] != c)
+ p[-3] = (unsigned char) finalize_jump;
+ else if (p1[3] == (unsigned char) charset
+ || p1[3] == (unsigned char) charset_not)
+ {
+ int not = p1[3] == (unsigned char) charset_not;
+ if (c < p1[4] * BYTEWIDTH
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+ /* `not' is 1 if c would match. */
+ /* That means it is not safe to finalize. */
+ if (!not)
+ p[-3] = (unsigned char) finalize_jump;
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if (p[-1] != (unsigned char) finalize_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ goto nofinalize;
+ }
+ /* Note fall through. */
+
+ /* The end of a stupid repeat has a finalize_jump back to the
+ start, where another failure point will be made which will
+ point to after all the repetitions found so far. */
+
+ /* Take off failure points put on by matching on_failure_jump
+ because didn't fail. Also remove the register information
+ put on by the on_failure_jump. */
+ case finalize_jump:
+ POP_FAILURE_POINT ();
+ /* Note fall through. */
+
+ /* Jump without taking off any failure points. */
+ case jump:
+ nofinalize:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p += mcnt;
+ break;
+
+ case dummy_failure_jump:
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at finalize_jump. We will end up at
+ finalize_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for finalize_jump to pop. */
+ PUSH_FAILURE_POINT (0, 0);
+ goto nofinalize;
+
+
+ /* Have to succeed matching what follows at least n times. Then
+ just handle like an on_failure_jump. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ }
+ else if (mcnt == 0)
+ {
+ p[2] = unused;
+ p[3] = unused;
+ goto on_failure;
+ }
+ else
+ {
+ fprintf (stderr, "regex: the succeed_n's n is not set.\n");
+ exit (1);
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER(p + 2, mcnt);
+ goto nofinalize; /* Do the jump without taking off
+ any failure points. */
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ register unsigned char *p1;
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case unused:
+ break;
+
+ case wordbound:
+ if (AT_WORD_BOUNDARY)
+ break;
+ goto fail;
+
+ case notwordbound:
+ if (AT_WORD_BOUNDARY)
+ goto fail;
+ break;
+
+ case wordbeg:
+ /* Have to check if AT_STRINGS_BEG before looking at d - 1. */
+ if (IS_A_LETTER (d) && (AT_STRINGS_BEG || !IS_A_LETTER (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ /* Have to check if AT_STRINGS_BEG before looking at d - 1. */
+ if (!AT_STRINGS_BEG && IS_A_LETTER (d - 1)
+ && (!IS_A_LETTER (d) || AT_STRINGS_END))
+ break;
+ goto fail;
+
+#ifdef emacs
+ case before_dot:
+ if (PTR_CHAR_POS (d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ if (PTR_CHAR_POS (d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ if (PTR_CHAR_POS (d) <= point)
+ goto fail;
+ break;
+
+ case wordchar:
+ mcnt = (int) Sword;
+ goto matchsyntax;
+
+ case syntaxspec:
+ mcnt = *p++;
+ matchsyntax:
+ PREFETCH;
+ if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+ case notwordchar:
+ mcnt = (int) Sword;
+ goto matchnotsyntax;
+
+ case notsyntaxspec:
+ mcnt = *p++;
+ matchnotsyntax:
+ PREFETCH;
+ if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+#else /* not emacs */
+
+ case wordchar:
+ PREFETCH;
+ if (!IS_A_LETTER (d))
+ goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+ case notwordchar:
+ PREFETCH;
+ if (IS_A_LETTER (d))
+ goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+#endif /* not emacs */
+
+ case begbuf:
+ if (AT_STRINGS_BEG)
+ break;
+ goto fail;
+
+ case endbuf:
+ if (AT_STRINGS_END)
+ break;
+ goto fail;
+
+ case exactn:
+ /* Match the next few pattern characters exactly.
+ mcnt is how many characters to match. */
+ mcnt = *p++;
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH;
+ if (translate[*d++] != *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH;
+ if (*d++ != *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED;
+ break;
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+ /* Jump here if any matching operation fails. */
+ fail:
+ if (stackp != stackb)
+ /* A restart point is known. Restart there and pop it. */
+ {
+ short last_used_reg, this_reg;
+
+ /* If this failure point is from a dummy_failure_point, just
+ skip it. */
+ if (!stackp[-2])
+ {
+ POP_FAILURE_POINT ();
+ goto fail;
+ }
+
+ d = *--stackp;
+ p = *--stackp;
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ /* Restore register info. */
+ last_used_reg = (short) (int) *--stackp;
+
+ /* Make the ones that weren't saved -1 or 0 again. */
+ for (this_reg = RE_NREGS - 1; this_reg > last_used_reg; this_reg--)
+ {
+ regend[this_reg] = (unsigned char *) -1;
+ regstart[this_reg] = (unsigned char *) -1;
+ IS_ACTIVE (reg_info[this_reg]) = 0;
+ MATCHED_SOMETHING (reg_info[this_reg]) = 0;
+ }
+
+ /* And restore the rest from the stack. */
+ for ( ; this_reg > 0; this_reg--)
+ {
+ reg_info[this_reg] = *(struct register_info *) *--stackp;
+ regend[this_reg] = *--stackp;
+ regstart[this_reg] = *--stackp;
+ }
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ }
+
+ if (best_regs_set)
+ goto restore_best_regs;
+ return -1; /* Failure to match. */
+}
+
+
+static int
+bcmp_translate (char *s1, char *s2, int len, unsigned char *translate)
+{
+ register unsigned char *p1 = (unsigned char*)s1;
+ register unsigned char *p2 = (unsigned char*)s2;
+ while (len)
+ {
+ if (translate [*p1++] != translate [*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+
+
+/* Entry points compatible with 4.2 BSD regex library. */
+
+#if 0
+
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (char *s)
+{
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return "No previous regular expression";
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ if (!(re_comp_buf.buffer = (char *) malloc (200)))
+ return "Memory exhausted";
+ re_comp_buf.allocated = 200;
+ if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
+ return "Memory exhausted";
+ }
+ return re_compile_pattern (s, strlen (s), &re_comp_buf);
+}
+
+int
+re_exec (char *s)
+{
+ int len = strlen (s);
+ return 0 <= re_search (&re_comp_buf, s, len, 0, len,
+ (struct re_registers *) 0);
+}
+#endif /* not emacs */
+
+
+
+#ifdef test
+
+#include <stdio.h>
+
+/* Indexed by a character, gives the upper case equivalent of the
+ character. */
+
+char upcase[0400] =
+ { 000, 001, 002, 003, 004, 005, 006, 007,
+ 010, 011, 012, 013, 014, 015, 016, 017,
+ 020, 021, 022, 023, 024, 025, 026, 027,
+ 030, 031, 032, 033, 034, 035, 036, 037,
+ 040, 041, 042, 043, 044, 045, 046, 047,
+ 050, 051, 052, 053, 054, 055, 056, 057,
+ 060, 061, 062, 063, 064, 065, 066, 067,
+ 070, 071, 072, 073, 074, 075, 076, 077,
+ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+ 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+ };
+
+#ifdef canned
+
+#include "tests.h"
+
+typedef enum { extended_test, basic_test } test_type;
+
+/* Use this to run the tests we've thought of. */
+
+void
+main ()
+{
+ test_type t = extended_test;
+
+ if (t == basic_test)
+ {
+ printf ("Running basic tests:\n\n");
+ test_posix_basic ();
+ }
+ else if (t == extended_test)
+ {
+ printf ("Running extended tests:\n\n");
+ test_posix_extended ();
+ }
+}
+
+#else /* not canned */
+
+/* Use this to run interactive tests. */
+
+void
+main (int argc, char **argv)
+{
+ char pat[80];
+ struct re_pattern_buffer buf;
+ int i;
+ char c;
+ char fastmap[(1 << BYTEWIDTH)];
+
+ /* Allow a command argument to specify the style of syntax. */
+ if (argc > 1)
+ obscure_syntax = atoi (argv[1]);
+
+ buf.allocated = 40;
+ buf.buffer = (char *) malloc (buf.allocated);
+ buf.fastmap = fastmap;
+ buf.translate = upcase;
+
+ while (1)
+ {
+ gets (pat);
+
+ if (*pat)
+ {
+ re_compile_pattern (pat, strlen(pat), &buf);
+
+ for (i = 0; i < buf.used; i++)
+ printchar (buf.buffer[i]);
+
+ putchar ('\n');
+
+ printf ("%d allocated, %d used.\n", buf.allocated, buf.used);
+
+ re_compile_fastmap (&buf);
+ printf ("Allowed by fastmap: ");
+ for (i = 0; i < (1 << BYTEWIDTH); i++)
+ if (fastmap[i]) printchar (i);
+ putchar ('\n');
+ }
+
+ gets (pat); /* Now read the string to match against */
+
+ i = re_match (&buf, pat, strlen (pat), 0, 0);
+ printf ("Match value %d.\n", i);
+ }
+}
+
+#endif
+
+
+#ifdef NOTDEF
+void
+print_buf (struct re_pattern_buffer *bufpbufp)
+{
+ int i;
+
+ printf ("buf is :\n----------------\n");
+ for (i = 0; i < bufp->used; i++)
+ printchar (bufp->buffer[i]);
+
+ printf ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
+
+ printf ("Allowed by fastmap: ");
+ for (i = 0; i < (1 << BYTEWIDTH); i++)
+ if (bufp->fastmap[i])
+ printchar (i);
+ printf ("\nAllowed by translate: ");
+ if (bufp->translate)
+ for (i = 0; i < (1 << BYTEWIDTH); i++)
+ if (bufp->translate[i])
+ printchar (i);
+ printf ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
+ printf ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
+}
+#endif /* NOTDEF */
+
+void
+printchar (char c)
+{
+ if (c < 040 || c >= 0177)
+ {
+ putchar ('\\');
+ putchar (((c >> 6) & 3) + '0');
+ putchar (((c >> 3) & 7) + '0');
+ putchar ((c & 7) + '0');
+ }
+ else
+ putchar (c);
+}
+
+void
+error (char *string)
+{
+ puts (string);
+ exit (1);
+}
+#endif /* test */
diff --git a/gnu/lib/libg++/libg++/sqrt.cc b/gnu/lib/libg++/libg++/sqrt.cc
new file mode 100644
index 0000000..6df9af3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/sqrt.cc
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <math.h>
+
+long sqrt(long x)
+{
+ if (x <= 0)
+ return 0; // no int error handler, so ...
+ else if (x == 1)
+ return 1;
+ else
+ {
+ long r = x >> 1;
+ long q;
+ for(;;)
+ {
+ q = x / r;
+ if (q >= r)
+ return r;
+ else
+ r = (r + q) >> 1;
+ }
+ }
+}
diff --git a/gnu/lib/libg++/libg++/str.cc b/gnu/lib/libg++/libg++/str.cc
new file mode 100644
index 0000000..bf77c02
--- /dev/null
+++ b/gnu/lib/libg++/libg++/str.cc
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <AllocRing.h>
+
+extern AllocRing _libgxx_fmtq;
+
+char* str(const char* s, int width)
+{
+ int len = strlen(s);
+ int wrksiz = len + width + 1;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ char* fmt = fmtbase;
+ for (int blanks = width - len; blanks > 0; --blanks)
+ *fmt++ = ' ';
+ while (*s != 0)
+ *fmt++ = *s++;
+ *fmt = 0;
+ return fmtbase;
+}
diff --git a/gnu/lib/libg++/libg++/timer.c b/gnu/lib/libg++/libg++/timer.c
new file mode 100644
index 0000000..73a856a
--- /dev/null
+++ b/gnu/lib/libg++/libg++/timer.c
@@ -0,0 +1,135 @@
+/*
+Copyright (C) 1990, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+/* Timing functions from Doug Schmidt... */
+
+/* no such thing as "negative time"! */
+#define TIMER_ERROR_VALUE -1.0
+
+/* If this does not work on your system, change this to #if 0, and
+ report the problem. */
+
+#if 1
+
+#include <_G_config.h>
+#if _G_HAVE_SYS_RESOURCE
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#if !_G_HAVE_SYS_RESOURCE || !defined(RUSAGE_SELF)
+#define USE_TIMES
+#include <sys/param.h>
+#include <sys/times.h>
+#if !defined (HZ) && defined(CLK_TCK)
+#define HZ CLK_TCK
+#endif
+static struct tms Old_Time;
+static struct tms New_Time;
+#else
+static struct rusage Old_Time;
+static struct rusage New_Time;
+#endif
+static int Timer_Set = 0;
+
+double
+start_timer()
+{
+ Timer_Set = 1;
+#ifdef USE_TIMES
+ times(&Old_Time);
+ return((double) Old_Time.tms_utime / HZ);
+#else
+ getrusage(RUSAGE_SELF,&Old_Time); /* set starting process time */
+ return(Old_Time.ru_utime.tv_sec + (Old_Time.ru_utime.tv_usec / 1000000.0));
+#endif
+}
+
+/* Returns process time since Last_Time.
+ If parameter is 0.0, returns time since the Old_Time was set.
+ Returns TIMER_ERROR_VALUE if `start_timer' is not called first. */
+
+double
+return_elapsed_time(Last_Time)
+ double Last_Time;
+{
+ if (!Timer_Set) {
+ return(TIMER_ERROR_VALUE);
+ }
+ else {
+ /* get process time */
+#ifdef USE_TIMES
+ times(&New_Time);
+#else
+ getrusage(RUSAGE_SELF,&New_Time);
+#endif
+ if (Last_Time == 0.0) {
+#ifdef USE_TIMES
+ return((double) (New_Time.tms_utime - Old_Time.tms_utime) / HZ);
+#else
+ return((New_Time.ru_utime.tv_sec - Old_Time.ru_utime.tv_sec) +
+ ((New_Time.ru_utime.tv_usec - Old_Time.ru_utime.tv_usec)
+ / 1000000.0));
+#endif
+ }
+ else {
+#ifdef USE_TIMES
+ return((double) New_Time.tms_utime / HZ - Last_Time);
+#else
+ return((New_Time.ru_utime.tv_sec +
+ (New_Time.ru_utime.tv_usec / 1000000.0)) - Last_Time);
+#endif
+ }
+ }
+}
+
+#ifdef VMS
+void sys$gettim(unsigned int*) asm("sys$gettim");
+
+getrusage(int dummy,struct rusage* time){
+ double rtime;
+ unsigned int systime[2];
+ int i;
+ sys$gettim(&systime[0]);
+ rtime=systime[1];
+ for(i=0;i<4;i++) rtime *= 256;
+ rtime+= systime[0];
+/* we subtract an offset to make sure that the number fits in a long int*/
+ rtime=rtime/1.0e+7-4.144e+9;
+ time->ru_utime.tv_sec= rtime;
+ rtime=(rtime-time->ru_utime.tv_sec)*1.0e6;
+ time->ru_utime.tv_usec= rtime;
+}
+#endif
+#else /* dummy them out */
+
+double start_timer()
+{
+ return TIMER_ERROR_VALUE;
+}
+
+double return_elapsed_time(double)
+{
+ return TIMER_ERROR_VALUE;
+}
+
+#endif /* timing stuff */
+
+
diff --git a/gnu/lib/libg++/libiberty/strerror.c b/gnu/lib/libg++/libiberty/strerror.c
new file mode 100644
index 0000000..5c0a58d
--- /dev/null
+++ b/gnu/lib/libg++/libiberty/strerror.c
@@ -0,0 +1,823 @@
+/* Extended support for using errno values.
+ Copyright (C) 1992 Free Software Foundation, Inc.
+ Written by Fred Fish. fnf@cygnus.com
+
+This file is part of the libiberty library.
+Libiberty 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.
+
+Libiberty 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 libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include "config.h"
+
+#ifndef NEED_sys_errlist
+/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
+ might declare sys_errlist in a way that the compiler might consider
+ incompatible with our later declaration, perhaps by using const
+ attributes. So we hide the declaration in errno.h (if any) using a
+ macro. */
+#define sys_errlist sys_errlist__
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifndef NEED_sys_errlist
+#undef sys_errlist
+#endif
+
+/* Routines imported from standard C runtime libraries. */
+
+#ifdef __STDC__
+#include <stddef.h>
+extern void *malloc (size_t size); /* 4.10.3.3 */
+extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
+#else /* !__STDC__ */
+extern char *malloc (); /* Standard memory allocater */
+extern char *memset ();
+#endif /* __STDC__ */
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+/* Translation table for errno values. See intro(2) in most UNIX systems
+ Programmers Reference Manuals.
+
+ Note that this table is generally only accessed when it is used at runtime
+ to initialize errno name and message tables that are indexed by errno
+ value.
+
+ Not all of these errnos will exist on all systems. This table is the only
+ thing that should have to be updated as new error numbers are introduced.
+ It's sort of ugly, but at least its portable. */
+
+struct error_info
+{
+ int value; /* The numeric value from <errno.h> */
+ const char *name; /* The equivalent symbolic value */
+#ifdef NEED_sys_errlist
+ const char *msg; /* Short message about this value */
+#endif
+};
+
+#ifdef NEED_sys_errlist
+# define ENTRY(value, name, msg) {value, name, msg}
+#else
+# define ENTRY(value, name, msg) {value, name}
+#endif
+
+static const struct error_info error_table[] =
+{
+#if defined (EPERM)
+ ENTRY(EPERM, "EPERM", "Not owner"),
+#endif
+#if defined (ENOENT)
+ ENTRY(ENOENT, "ENOENT", "No such file or directory"),
+#endif
+#if defined (ESRCH)
+ ENTRY(ESRCH, "ESRCH", "No such process"),
+#endif
+#if defined (EINTR)
+ ENTRY(EINTR, "EINTR", "Interrupted system call"),
+#endif
+#if defined (EIO)
+ ENTRY(EIO, "EIO", "I/O error"),
+#endif
+#if defined (ENXIO)
+ ENTRY(ENXIO, "ENXIO", "No such device or address"),
+#endif
+#if defined (E2BIG)
+ ENTRY(E2BIG, "E2BIG", "Arg list too long"),
+#endif
+#if defined (ENOEXEC)
+ ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
+#endif
+#if defined (EBADF)
+ ENTRY(EBADF, "EBADF", "Bad file number"),
+#endif
+#if defined (ECHILD)
+ ENTRY(ECHILD, "ECHILD", "No child processes"),
+#endif
+#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
+ ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
+#endif
+#if defined (EAGAIN)
+ ENTRY(EAGAIN, "EAGAIN", "No more processes"),
+#endif
+#if defined (ENOMEM)
+ ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
+#endif
+#if defined (EACCES)
+ ENTRY(EACCES, "EACCES", "Permission denied"),
+#endif
+#if defined (EFAULT)
+ ENTRY(EFAULT, "EFAULT", "Bad address"),
+#endif
+#if defined (ENOTBLK)
+ ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
+#endif
+#if defined (EBUSY)
+ ENTRY(EBUSY, "EBUSY", "Device busy"),
+#endif
+#if defined (EEXIST)
+ ENTRY(EEXIST, "EEXIST", "File exists"),
+#endif
+#if defined (EXDEV)
+ ENTRY(EXDEV, "EXDEV", "Cross-device link"),
+#endif
+#if defined (ENODEV)
+ ENTRY(ENODEV, "ENODEV", "No such device"),
+#endif
+#if defined (ENOTDIR)
+ ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
+#endif
+#if defined (EISDIR)
+ ENTRY(EISDIR, "EISDIR", "Is a directory"),
+#endif
+#if defined (EINVAL)
+ ENTRY(EINVAL, "EINVAL", "Invalid argument"),
+#endif
+#if defined (ENFILE)
+ ENTRY(ENFILE, "ENFILE", "File table overflow"),
+#endif
+#if defined (EMFILE)
+ ENTRY(EMFILE, "EMFILE", "Too many open files"),
+#endif
+#if defined (ENOTTY)
+ ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
+#endif
+#if defined (ETXTBSY)
+ ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
+#endif
+#if defined (EFBIG)
+ ENTRY(EFBIG, "EFBIG", "File too large"),
+#endif
+#if defined (ENOSPC)
+ ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
+#endif
+#if defined (ESPIPE)
+ ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
+#endif
+#if defined (EROFS)
+ ENTRY(EROFS, "EROFS", "Read-only file system"),
+#endif
+#if defined (EMLINK)
+ ENTRY(EMLINK, "EMLINK", "Too many links"),
+#endif
+#if defined (EPIPE)
+ ENTRY(EPIPE, "EPIPE", "Broken pipe"),
+#endif
+#if defined (EDOM)
+ ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
+#endif
+#if defined (ERANGE)
+ ENTRY(ERANGE, "ERANGE", "Math result not representable"),
+#endif
+#if defined (ENOMSG)
+ ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
+#endif
+#if defined (EIDRM)
+ ENTRY(EIDRM, "EIDRM", "Identifier removed"),
+#endif
+#if defined (ECHRNG)
+ ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
+#endif
+#if defined (EL2NSYNC)
+ ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
+#endif
+#if defined (EL3HLT)
+ ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
+#endif
+#if defined (EL3RST)
+ ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
+#endif
+#if defined (ELNRNG)
+ ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
+#endif
+#if defined (EUNATCH)
+ ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
+#endif
+#if defined (ENOCSI)
+ ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
+#endif
+#if defined (EL2HLT)
+ ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
+#endif
+#if defined (EDEADLK)
+ ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
+#endif
+#if defined (ENOLCK)
+ ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
+#endif
+#if defined (EBADE)
+ ENTRY(EBADE, "EBADE", "Invalid exchange"),
+#endif
+#if defined (EBADR)
+ ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
+#endif
+#if defined (EXFULL)
+ ENTRY(EXFULL, "EXFULL", "Exchange full"),
+#endif
+#if defined (ENOANO)
+ ENTRY(ENOANO, "ENOANO", "No anode"),
+#endif
+#if defined (EBADRQC)
+ ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
+#endif
+#if defined (EBADSLT)
+ ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
+#endif
+#if defined (EDEADLOCK)
+ ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
+#endif
+#if defined (EBFONT)
+ ENTRY(EBFONT, "EBFONT", "Bad font file format"),
+#endif
+#if defined (ENOSTR)
+ ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
+#endif
+#if defined (ENODATA)
+ ENTRY(ENODATA, "ENODATA", "No data available"),
+#endif
+#if defined (ETIME)
+ ENTRY(ETIME, "ETIME", "Timer expired"),
+#endif
+#if defined (ENOSR)
+ ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
+#endif
+#if defined (ENONET)
+ ENTRY(ENONET, "ENONET", "Machine is not on the network"),
+#endif
+#if defined (ENOPKG)
+ ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
+#endif
+#if defined (EREMOTE)
+ ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
+#endif
+#if defined (ENOLINK)
+ ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
+#endif
+#if defined (EADV)
+ ENTRY(EADV, "EADV", "Advertise error"),
+#endif
+#if defined (ESRMNT)
+ ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
+#endif
+#if defined (ECOMM)
+ ENTRY(ECOMM, "ECOMM", "Communication error on send"),
+#endif
+#if defined (EPROTO)
+ ENTRY(EPROTO, "EPROTO", "Protocol error"),
+#endif
+#if defined (EMULTIHOP)
+ ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
+#endif
+#if defined (EDOTDOT)
+ ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
+#endif
+#if defined (EBADMSG)
+ ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
+#endif
+#if defined (ENAMETOOLONG)
+ ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
+#endif
+#if defined (EOVERFLOW)
+ ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
+#endif
+#if defined (ENOTUNIQ)
+ ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
+#endif
+#if defined (EBADFD)
+ ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
+#endif
+#if defined (EREMCHG)
+ ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
+#endif
+#if defined (ELIBACC)
+ ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"),
+#endif
+#if defined (ELIBBAD)
+ ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
+#endif
+#if defined (ELIBSCN)
+ ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
+#endif
+#if defined (ELIBMAX)
+ ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
+#endif
+#if defined (ELIBEXEC)
+ ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
+#endif
+#if defined (EILSEQ)
+ ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
+#endif
+#if defined (ENOSYS)
+ ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
+#endif
+#if defined (ELOOP)
+ ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
+#endif
+#if defined (ERESTART)
+ ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
+#endif
+#if defined (ESTRPIPE)
+ ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
+#endif
+#if defined (ENOTEMPTY)
+ ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
+#endif
+#if defined (EUSERS)
+ ENTRY(EUSERS, "EUSERS", "Too many users"),
+#endif
+#if defined (ENOTSOCK)
+ ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
+#endif
+#if defined (EDESTADDRREQ)
+ ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
+#endif
+#if defined (EMSGSIZE)
+ ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
+#endif
+#if defined (EPROTOTYPE)
+ ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
+#endif
+#if defined (ENOPROTOOPT)
+ ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
+#endif
+#if defined (EPROTONOSUPPORT)
+ ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
+#endif
+#if defined (ESOCKTNOSUPPORT)
+ ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
+#endif
+#if defined (EOPNOTSUPP)
+ ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
+#endif
+#if defined (EPFNOSUPPORT)
+ ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
+#endif
+#if defined (EAFNOSUPPORT)
+ ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
+#endif
+#if defined (EADDRINUSE)
+ ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
+#endif
+#if defined (EADDRNOTAVAIL)
+ ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
+#endif
+#if defined (ENETDOWN)
+ ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
+#endif
+#if defined (ENETUNREACH)
+ ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
+#endif
+#if defined (ENETRESET)
+ ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
+#endif
+#if defined (ECONNABORTED)
+ ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
+#endif
+#if defined (ECONNRESET)
+ ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
+#endif
+#if defined (ENOBUFS)
+ ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
+#endif
+#if defined (EISCONN)
+ ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
+#endif
+#if defined (ENOTCONN)
+ ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
+#endif
+#if defined (ESHUTDOWN)
+ ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
+#endif
+#if defined (ETOOMANYREFS)
+ ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
+#endif
+#if defined (ETIMEDOUT)
+ ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
+#endif
+#if defined (ECONNREFUSED)
+ ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
+#endif
+#if defined (EHOSTDOWN)
+ ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
+#endif
+#if defined (EHOSTUNREACH)
+ ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
+#endif
+#if defined (EALREADY)
+ ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
+#endif
+#if defined (EINPROGRESS)
+ ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
+#endif
+#if defined (ESTALE)
+ ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
+#endif
+#if defined (EUCLEAN)
+ ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
+#endif
+#if defined (ENOTNAM)
+ ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
+#endif
+#if defined (ENAVAIL)
+ ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
+#endif
+#if defined (EISNAM)
+ ENTRY(EISNAM, "EISNAM", "Is a named type file"),
+#endif
+#if defined (EREMOTEIO)
+ ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
+#endif
+ ENTRY(0, NULL, NULL)
+};
+
+/* Translation table allocated and initialized at runtime. Indexed by the
+ errno value to find the equivalent symbolic value. */
+
+static const char **error_names;
+static int num_error_names = 0;
+
+/* Translation table allocated and initialized at runtime, if it does not
+ already exist in the host environment. Indexed by the errno value to find
+ the descriptive string.
+
+ We don't export it for use in other modules because even though it has the
+ same name, it differs from other implementations in that it is dynamically
+ initialized rather than statically initialized. */
+
+#ifdef NEED_sys_errlist
+
+static int sys_nerr;
+static const char **sys_errlist;
+
+#else
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+#endif
+
+
+/*
+
+NAME
+
+ init_error_tables -- initialize the name and message tables
+
+SYNOPSIS
+
+ static void init_error_tables ();
+
+DESCRIPTION
+
+ Using the error_table, which is initialized at compile time, generate
+ the error_names and the sys_errlist (if needed) tables, which are
+ indexed at runtime by a specific errno value.
+
+BUGS
+
+ The initialization of the tables may fail under low memory conditions,
+ in which case we don't do anything particularly useful, but we don't
+ bomb either. Who knows, it might succeed at a later point if we free
+ some memory in the meantime. In any case, the other routines know
+ how to deal with lack of a table after trying to initialize it. This
+ may or may not be considered to be a bug, that we don't specifically
+ warn about this particular failure mode.
+
+*/
+
+static void
+init_error_tables ()
+{
+ const struct error_info *eip;
+ int nbytes;
+
+ /* If we haven't already scanned the error_table once to find the maximum
+ errno value, then go find it now. */
+
+ if (num_error_names == 0)
+ {
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ if (eip -> value >= num_error_names)
+ {
+ num_error_names = eip -> value + 1;
+ }
+ }
+ }
+
+ /* Now attempt to allocate the error_names table, zero it out, and then
+ initialize it from the statically initialized error_table. */
+
+ if (error_names == NULL)
+ {
+ nbytes = num_error_names * sizeof (char *);
+ if ((error_names = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (error_names, 0, nbytes);
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ error_names[eip -> value] = eip -> name;
+ }
+ }
+ }
+
+#ifdef NEED_sys_errlist
+
+ /* Now attempt to allocate the sys_errlist table, zero it out, and then
+ initialize it from the statically initialized error_table. */
+
+ if (sys_errlist == NULL)
+ {
+ nbytes = num_error_names * sizeof (char *);
+ if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (sys_errlist, 0, nbytes);
+ sys_nerr = num_error_names;
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ sys_errlist[eip -> value] = eip -> msg;
+ }
+ }
+ }
+
+#endif
+
+}
+
+/*
+
+NAME
+
+ errno_max -- return the max errno value
+
+SYNOPSIS
+
+ int errno_max ();
+
+DESCRIPTION
+
+ Returns the maximum errno value for which a corresponding symbolic
+ name or message is available. Note that in the case where
+ we use the sys_errlist supplied by the system, it is possible for
+ there to be more symbolic names than messages, or vice versa.
+ In fact, the manual page for perror(3C) explicitly warns that one
+ should check the size of the table (sys_nerr) before indexing it,
+ since new error codes may be added to the system before they are
+ added to the table. Thus sys_nerr might be smaller than value
+ implied by the largest errno value defined in <errno.h>.
+
+ We return the maximum value that can be used to obtain a meaningful
+ symbolic name or message.
+
+*/
+
+int
+errno_max ()
+{
+ int maxsize;
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+ maxsize = MAX (sys_nerr, num_error_names);
+ return (maxsize - 1);
+}
+
+#ifdef NEED_strerror
+
+/*
+
+NAME
+
+ strerror -- map an error number to an error message string
+
+SYNOPSIS
+
+ char *strerror (int errnoval)
+
+DESCRIPTION
+
+ Maps an errno number to an error message string, the contents of
+ which are implementation defined. On systems which have the external
+ variables sys_nerr and sys_errlist, these strings will be the same
+ as the ones used by perror().
+
+ If the supplied error number is within the valid range of indices
+ for the sys_errlist, but no message is available for the particular
+ error number, then returns the string "Error NUM", where NUM is the
+ error number.
+
+ If the supplied error number is not a valid index into sys_errlist,
+ returns NULL.
+
+ The returned string is only guaranteed to be valid only until the
+ next call to strerror.
+
+*/
+
+char *
+strerror (errnoval)
+ int errnoval;
+{
+ char *msg;
+ static char buf[32];
+
+#ifdef NEED_sys_errlist
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+
+#endif
+
+ if ((errnoval < 0) || (errnoval >= sys_nerr))
+ {
+ /* Out of range, just return NULL */
+ msg = NULL;
+ }
+ else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
+ {
+ /* In range, but no sys_errlist or no entry at this index. */
+ sprintf (buf, "Error %d", errnoval);
+ msg = buf;
+ }
+ else
+ {
+ /* In range, and a valid message. Just return the message. */
+ msg = (char *) sys_errlist[errnoval];
+ }
+
+ return (msg);
+}
+
+#endif /* NEED_strerror */
+
+
+/*
+
+NAME
+
+ strerrno -- map an error number to a symbolic name string
+
+SYNOPSIS
+
+ const char *strerrno (int errnoval)
+
+DESCRIPTION
+
+ Given an error number returned from a system call (typically
+ returned in errno), returns a pointer to a string containing the
+ symbolic name of that error number, as found in <errno.h>.
+
+ If the supplied error number is within the valid range of indices
+ for symbolic names, but no name is available for the particular
+ error number, then returns the string "Error NUM", where NUM is
+ the error number.
+
+ If the supplied error number is not within the range of valid
+ indices, then returns NULL.
+
+BUGS
+
+ The contents of the location pointed to are only guaranteed to be
+ valid until the next call to strerrno.
+
+*/
+
+const char *
+strerrno (errnoval)
+ int errnoval;
+{
+ const char *name;
+ static char buf[32];
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+
+ if ((errnoval < 0) || (errnoval >= num_error_names))
+ {
+ /* Out of range, just return NULL */
+ name = NULL;
+ }
+ else if ((error_names == NULL) || (error_names[errnoval] == NULL))
+ {
+ /* In range, but no error_names or no entry at this index. */
+ sprintf (buf, "Error %d", errnoval);
+ name = (const char *) buf;
+ }
+ else
+ {
+ /* In range, and a valid name. Just return the name. */
+ name = error_names[errnoval];
+ }
+
+ return (name);
+}
+
+/*
+
+NAME
+
+ strtoerrno -- map a symbolic errno name to a numeric value
+
+SYNOPSIS
+
+ int strtoerrno (char *name)
+
+DESCRIPTION
+
+ Given the symbolic name of a error number, map it to an errno value.
+ If no translation is found, returns 0.
+
+*/
+
+int
+strtoerrno (name)
+ const char *name;
+{
+ int errnoval = 0;
+
+ if (name != NULL)
+ {
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+ for (errnoval = 0; errnoval < num_error_names; errnoval++)
+ {
+ if ((error_names[errnoval] != NULL) &&
+ (strcmp (name, error_names[errnoval]) == 0))
+ {
+ break;
+ }
+ }
+ if (errnoval == num_error_names)
+ {
+ errnoval = 0;
+ }
+ }
+ return (errnoval);
+}
+
+
+/* A simple little main that does nothing but print all the errno translations
+ if MAIN is defined and this file is compiled and linked. */
+
+#ifdef MAIN
+
+#include <stdio.h>
+
+int
+main ()
+{
+ int errn;
+ int errnmax;
+ const char *name;
+ char *msg;
+ char *strerror ();
+
+ errnmax = errno_max ();
+ printf ("%d entries in names table.\n", num_error_names);
+ printf ("%d entries in messages table.\n", sys_nerr);
+ printf ("%d is max useful index.\n", errnmax);
+
+ /* Keep printing values until we get to the end of *both* tables, not
+ *either* table. Note that knowing the maximum useful index does *not*
+ relieve us of the responsibility of testing the return pointer for
+ NULL. */
+
+ for (errn = 0; errn <= errnmax; errn++)
+ {
+ name = strerrno (errn);
+ name = (name == NULL) ? "<NULL>" : name;
+ msg = strerror (errn);
+ msg = (msg == NULL) ? "<NULL>" : msg;
+ printf ("%-4d%-18s%s\n", errn, name, msg);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/libiberty/strsignal.c b/gnu/lib/libg++/libiberty/strsignal.c
new file mode 100644
index 0000000..7acb733
--- /dev/null
+++ b/gnu/lib/libg++/libiberty/strsignal.c
@@ -0,0 +1,643 @@
+/* Extended support for using signal values.
+ Copyright (C) 1992 Free Software Foundation, Inc.
+ Written by Fred Fish. fnf@cygnus.com
+
+This file is part of the libiberty library.
+Libiberty 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.
+
+Libiberty 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 libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include "config.h"
+
+#ifdef LOSING_SYS_SIGLIST
+#define sys_siglist no_such_symbol
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+
+/* Routines imported from standard C runtime libraries. */
+
+#ifdef __STDC__
+#include <stddef.h>
+extern void *malloc (size_t size); /* 4.10.3.3 */
+extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
+#else /* !__STDC__ */
+extern char *malloc (); /* Standard memory allocater */
+extern char *memset ();
+#endif /* __STDC__ */
+
+#ifdef LOSING_SYS_SIGLIST
+#undef sys_siglist
+#endif
+
+
+#ifndef NULL
+# ifdef __STDC__
+# define NULL (void *) 0
+# else
+# define NULL 0
+# endif
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+/* Translation table for signal values.
+
+ Note that this table is generally only accessed when it is used at runtime
+ to initialize signal name and message tables that are indexed by signal
+ value.
+
+ Not all of these signals will exist on all systems. This table is the only
+ thing that should have to be updated as new signal numbers are introduced.
+ It's sort of ugly, but at least its portable. */
+
+struct signal_info
+{
+ int value; /* The numeric value from <signal.h> */
+ const char *name; /* The equivalent symbolic value */
+#ifdef NEED_sys_siglist
+ const char *msg; /* Short message about this value */
+#endif
+};
+
+#ifdef NEED_sys_siglist
+# define ENTRY(value, name, msg) {value, name, msg}
+#else
+# define ENTRY(value, name, msg) {value, name}
+#endif
+
+static const struct signal_info signal_table[] =
+{
+#if defined (SIGHUP)
+ ENTRY(SIGHUP, "SIGHUP", "Hangup"),
+#endif
+#if defined (SIGINT)
+ ENTRY(SIGINT, "SIGINT", "Interrupt"),
+#endif
+#if defined (SIGQUIT)
+ ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
+#endif
+#if defined (SIGILL)
+ ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
+#endif
+#if defined (SIGTRAP)
+ ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
+#endif
+/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
+ overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
+#if defined (SIGIOT)
+ ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
+#endif
+#if defined (SIGABRT)
+ ENTRY(SIGABRT, "SIGABRT", "Aborted"),
+#endif
+#if defined (SIGEMT)
+ ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
+#endif
+#if defined (SIGFPE)
+ ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
+#endif
+#if defined (SIGKILL)
+ ENTRY(SIGKILL, "SIGKILL", "Killed"),
+#endif
+#if defined (SIGBUS)
+ ENTRY(SIGBUS, "SIGBUS", "Bus error"),
+#endif
+#if defined (SIGSEGV)
+ ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
+#endif
+#if defined (SIGSYS)
+ ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
+#endif
+#if defined (SIGPIPE)
+ ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
+#endif
+#if defined (SIGALRM)
+ ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
+#endif
+#if defined (SIGTERM)
+ ENTRY(SIGTERM, "SIGTERM", "Terminated"),
+#endif
+#if defined (SIGUSR1)
+ ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
+#endif
+#if defined (SIGUSR2)
+ ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
+#endif
+/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
+ overrides SIGCLD. SIGCHLD is in POXIX.1 */
+#if defined (SIGCLD)
+ ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
+#endif
+#if defined (SIGCHLD)
+ ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
+#endif
+#if defined (SIGPWR)
+ ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
+#endif
+#if defined (SIGWINCH)
+ ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
+#endif
+#if defined (SIGURG)
+ ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
+#endif
+#if defined (SIGIO)
+ /* "I/O pending" has also been suggested, but is misleading since the
+ signal only happens when the process has asked for it, not everytime
+ I/O is pending. */
+ ENTRY(SIGIO, "SIGIO", "I/O possible"),
+#endif
+#if defined (SIGPOLL)
+ ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
+#endif
+#if defined (SIGSTOP)
+ ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
+#endif
+#if defined (SIGTSTP)
+ ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
+#endif
+#if defined (SIGCONT)
+ ENTRY(SIGCONT, "SIGCONT", "Continued"),
+#endif
+#if defined (SIGTTIN)
+ ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
+#endif
+#if defined (SIGTTOU)
+ ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
+#endif
+#if defined (SIGVTALRM)
+ ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
+#endif
+#if defined (SIGPROF)
+ ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
+#endif
+#if defined (SIGXCPU)
+ ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
+#endif
+#if defined (SIGXFSZ)
+ ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
+#endif
+#if defined (SIGWIND)
+ ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
+#endif
+#if defined (SIGPHONE)
+ ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
+#endif
+#if defined (SIGLOST)
+ ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
+#endif
+#if defined (SIGWAITING)
+ ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
+#endif
+#if defined (SIGLWP)
+ ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
+#endif
+#if defined (SIGDANGER)
+ ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
+#endif
+#if defined (SIGGRANT)
+ ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
+#endif
+#if defined (SIGRETRACT)
+ ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
+#endif
+#if defined (SIGMSG)
+ ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
+#endif
+#if defined (SIGSOUND)
+ ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
+#endif
+#if defined (SIGSAK)
+ ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
+#endif
+ ENTRY(0, NULL, NULL)
+};
+
+/* Translation table allocated and initialized at runtime. Indexed by the
+ signal value to find the equivalent symbolic value. */
+
+static const char **signal_names;
+static int num_signal_names = 0;
+
+/* Translation table allocated and initialized at runtime, if it does not
+ already exist in the host environment. Indexed by the signal value to find
+ the descriptive string.
+
+ We don't export it for use in other modules because even though it has the
+ same name, it differs from other implementations in that it is dynamically
+ initialized rather than statically initialized. */
+
+#ifdef NEED_sys_siglist
+
+static int sys_nsig;
+static const char **sys_siglist;
+
+#else
+
+static int sys_nsig = NSIG;
+extern const char * const sys_siglist[];
+
+#endif
+
+
+/*
+
+NAME
+
+ init_signal_tables -- initialize the name and message tables
+
+SYNOPSIS
+
+ static void init_signal_tables ();
+
+DESCRIPTION
+
+ Using the signal_table, which is initialized at compile time, generate
+ the signal_names and the sys_siglist (if needed) tables, which are
+ indexed at runtime by a specific signal value.
+
+BUGS
+
+ The initialization of the tables may fail under low memory conditions,
+ in which case we don't do anything particularly useful, but we don't
+ bomb either. Who knows, it might succeed at a later point if we free
+ some memory in the meantime. In any case, the other routines know
+ how to deal with lack of a table after trying to initialize it. This
+ may or may not be considered to be a bug, that we don't specifically
+ warn about this particular failure mode.
+
+*/
+
+static void
+init_signal_tables ()
+{
+ const struct signal_info *eip;
+ int nbytes;
+
+ /* If we haven't already scanned the signal_table once to find the maximum
+ signal value, then go find it now. */
+
+ if (num_signal_names == 0)
+ {
+ for (eip = signal_table; eip -> name != NULL; eip++)
+ {
+ if (eip -> value >= num_signal_names)
+ {
+ num_signal_names = eip -> value + 1;
+ }
+ }
+ }
+
+ /* Now attempt to allocate the signal_names table, zero it out, and then
+ initialize it from the statically initialized signal_table. */
+
+ if (signal_names == NULL)
+ {
+ nbytes = num_signal_names * sizeof (char *);
+ if ((signal_names = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (signal_names, 0, nbytes);
+ for (eip = signal_table; eip -> name != NULL; eip++)
+ {
+ signal_names[eip -> value] = eip -> name;
+ }
+ }
+ }
+
+#ifdef NEED_sys_siglist
+
+ /* Now attempt to allocate the sys_siglist table, zero it out, and then
+ initialize it from the statically initialized signal_table. */
+
+ if (sys_siglist == NULL)
+ {
+ nbytes = num_signal_names * sizeof (char *);
+ if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (sys_siglist, 0, nbytes);
+ sys_nsig = num_signal_names;
+ for (eip = signal_table; eip -> name != NULL; eip++)
+ {
+ sys_siglist[eip -> value] = eip -> msg;
+ }
+ }
+ }
+
+#endif
+
+}
+
+
+/*
+
+NAME
+
+ signo_max -- return the max signo value
+
+SYNOPSIS
+
+ int signo_max ();
+
+DESCRIPTION
+
+ Returns the maximum signo value for which a corresponding symbolic
+ name or message is available. Note that in the case where
+ we use the sys_siglist supplied by the system, it is possible for
+ there to be more symbolic names than messages, or vice versa.
+ In fact, the manual page for psignal(3b) explicitly warns that one
+ should check the size of the table (NSIG) before indexing it,
+ since new signal codes may be added to the system before they are
+ added to the table. Thus NSIG might be smaller than value
+ implied by the largest signo value defined in <signal.h>.
+
+ We return the maximum value that can be used to obtain a meaningful
+ symbolic name or message.
+
+*/
+
+int
+signo_max ()
+{
+ int maxsize;
+
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+ maxsize = MAX (sys_nsig, num_signal_names);
+ return (maxsize - 1);
+}
+
+
+/*
+
+NAME
+
+ strsignal -- map a signal number to a signal message string
+
+SYNOPSIS
+
+ const char *strsignal (int signo)
+
+DESCRIPTION
+
+ Maps an signal number to an signal message string, the contents of
+ which are implementation defined. On systems which have the external
+ variable sys_siglist, these strings will be the same as the ones used
+ by psignal().
+
+ If the supplied signal number is within the valid range of indices
+ for the sys_siglist, but no message is available for the particular
+ signal number, then returns the string "Signal NUM", where NUM is the
+ signal number.
+
+ If the supplied signal number is not a valid index into sys_siglist,
+ returns NULL.
+
+ The returned string is only guaranteed to be valid only until the
+ next call to strsignal.
+
+*/
+
+const char *
+strsignal (signo)
+ int signo;
+{
+ const char *msg;
+ static char buf[32];
+
+#ifdef NEED_sys_siglist
+
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+
+#endif
+
+ if ((signo < 0) || (signo >= sys_nsig))
+ {
+ /* Out of range, just return NULL */
+ msg = NULL;
+ }
+ else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
+ {
+ /* In range, but no sys_siglist or no entry at this index. */
+ sprintf (buf, "Signal %d", signo);
+ msg = (const char *) buf;
+ }
+ else
+ {
+ /* In range, and a valid message. Just return the message. */
+ msg = (const char *) sys_siglist[signo];
+ }
+
+ return (msg);
+}
+
+
+/*
+
+NAME
+
+ strsigno -- map an signal number to a symbolic name string
+
+SYNOPSIS
+
+ const char *strsigno (int signo)
+
+DESCRIPTION
+
+ Given an signal number, returns a pointer to a string containing
+ the symbolic name of that signal number, as found in <signal.h>.
+
+ If the supplied signal number is within the valid range of indices
+ for symbolic names, but no name is available for the particular
+ signal number, then returns the string "Signal NUM", where NUM is
+ the signal number.
+
+ If the supplied signal number is not within the range of valid
+ indices, then returns NULL.
+
+BUGS
+
+ The contents of the location pointed to are only guaranteed to be
+ valid until the next call to strsigno.
+
+*/
+
+const char *
+strsigno (signo)
+ int signo;
+{
+ const char *name;
+ static char buf[32];
+
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+
+ if ((signo < 0) || (signo >= num_signal_names))
+ {
+ /* Out of range, just return NULL */
+ name = NULL;
+ }
+ else if ((signal_names == NULL) || (signal_names[signo] == NULL))
+ {
+ /* In range, but no signal_names or no entry at this index. */
+ sprintf (buf, "Signal %d", signo);
+ name = (const char *) buf;
+ }
+ else
+ {
+ /* In range, and a valid name. Just return the name. */
+ name = signal_names[signo];
+ }
+
+ return (name);
+}
+
+
+/*
+
+NAME
+
+ strtosigno -- map a symbolic signal name to a numeric value
+
+SYNOPSIS
+
+ int strtosigno (char *name)
+
+DESCRIPTION
+
+ Given the symbolic name of a signal, map it to a signal number.
+ If no translation is found, returns 0.
+
+*/
+
+int
+strtosigno (name)
+ const char *name;
+{
+ int signo = 0;
+
+ if (name != NULL)
+ {
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+ for (signo = 0; signo < num_signal_names; signo++)
+ {
+ if ((signal_names[signo] != NULL) &&
+ (strcmp (name, signal_names[signo]) == 0))
+ {
+ break;
+ }
+ }
+ if (signo == num_signal_names)
+ {
+ signo = 0;
+ }
+ }
+ return (signo);
+}
+
+
+/*
+
+NAME
+
+ psignal -- print message about signal to stderr
+
+SYNOPSIS
+
+ void psignal (unsigned signo, char *message);
+
+DESCRIPTION
+
+ Print to the standard error the message, followed by a colon,
+ followed by the description of the signal specified by signo,
+ followed by a newline.
+*/
+
+#ifdef NEED_psignal
+
+void
+psignal (signo, message)
+ unsigned signo;
+ char *message;
+{
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+ if ((signo <= 0) || (signo >= sys_nsig))
+ {
+ fprintf (stderr, "%s: unknown signal\n", message);
+ }
+ else
+ {
+ fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
+ }
+}
+
+#endif /* NEED_psignal */
+
+
+/* A simple little main that does nothing but print all the signal translations
+ if MAIN is defined and this file is compiled and linked. */
+
+#ifdef MAIN
+
+#include <stdio.h>
+
+int
+main ()
+{
+ int signo;
+ int maxsigno;
+ const char *name;
+ const char *msg;
+
+ maxsigno = signo_max ();
+ printf ("%d entries in names table.\n", num_signal_names);
+ printf ("%d entries in messages table.\n", sys_nsig);
+ printf ("%d is max useful index.\n", maxsigno);
+
+ /* Keep printing values until we get to the end of *both* tables, not
+ *either* table. Note that knowing the maximum useful index does *not*
+ relieve us of the responsibility of testing the return pointer for
+ NULL. */
+
+ for (signo = 0; signo <= maxsigno; signo++)
+ {
+ name = strsigno (signo);
+ name = (name == NULL) ? "<NULL>" : name;
+ msg = strsignal (signo);
+ msg = (msg == NULL) ? "<NULL>" : msg;
+ printf ("%-4d%-18s%s\n", signo, name, msg);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/libiberty/vasprintf.c b/gnu/lib/libg++/libiberty/vasprintf.c
new file mode 100644
index 0000000..b3ba0ca
--- /dev/null
+++ b/gnu/lib/libg++/libiberty/vasprintf.c
@@ -0,0 +1,139 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty 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.
+
+Libiberty 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 libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <varargs.h>
+
+#ifdef TEST
+int global_total_width;
+#endif
+
+unsigned long strtoul ();
+char *malloc ();
+
+int
+vasprintf (result, format, args)
+ char **result;
+ char *format;
+ va_list args;
+{
+ char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap = args;
+
+ while (*p != '\0')
+ {
+ if (*p++ == '%')
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, &p, 10);
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, &p, 10);
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ va_arg (ap, double);
+ break;
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ va_arg (ap, char *);
+ break;
+ }
+ }
+ }
+#ifdef TEST
+ global_total_width = total_width;
+#endif
+ *result = malloc (total_width);
+ if (*result != NULL)
+ return vsprintf (*result, format, args);
+ else
+ return 0;
+}
+
+#ifdef TEST
+void
+checkit (va_alist)
+ va_dcl
+{
+ va_list args;
+ char *format;
+ char *result;
+
+ va_start (args);
+ format = va_arg (args, char *);
+ vasprintf (&result, format, args);
+ if (strlen (result) < global_total_width)
+ printf ("PASS: ");
+ else
+ printf ("FAIL: ");
+ printf ("%d %s\n", global_total_width, result);
+}
+
+int
+main ()
+{
+ checkit ("%d", 0x12345678);
+ checkit ("%200d", 5);
+ checkit ("%.300d", 6);
+ checkit ("%100.150d", 7);
+ checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
+777777777777777777333333333333366666666666622222222222777777777777733333");
+ checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
+}
+#endif /* TEST */
diff --git a/gnu/lib/libg++/libio/PlotFile.cc b/gnu/lib/libg++/libio/PlotFile.cc
new file mode 100644
index 0000000..a5af5c1
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/SFile.cc b/gnu/lib/libg++/libio/SFile.cc
new file mode 100644
index 0000000..24f668b
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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, 675 Mass Ave, Cambridge, MA 02139, 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()->sseekoff(i * sz, ios::beg) == EOF)
+ set(ios::badbit);
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/builtinbuf.cc b/gnu/lib/libg++/libio/builtinbuf.cc
new file mode 100644
index 0000000..d6b9ebb
--- /dev/null
+++ b/gnu/lib/libg++/libio/builtinbuf.cc
@@ -0,0 +1,96 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
+
+int builtinbuf::overflow(int ch) { return (*_jumps->__overflow)(this, ch); }
+
+int builtinbuf::underflow() { return (*_jumps->__underflow)(this); }
+
+streamsize builtinbuf::xsgetn(char* buf, streamsize n)
+{ return (*_jumps->__xsgetn)(this, buf, n); }
+
+streamsize builtinbuf::xsputn(const char* buf, streamsize n)
+{ return _jumps->__xsputn (this, buf, n); }
+
+int builtinbuf::doallocate() { return _jumps->__doallocate(this); }
+
+builtinbuf::~builtinbuf() { _jumps->__finish(this); }
+
+int builtinbuf::sync() { return _jumps->__sync(this); }
+
+streambuf* builtinbuf::setbuf(char *buf, int n)
+{ return _jumps->__setbuf (this, buf, n) == 0 ? this : NULL; }
+
+streampos builtinbuf::seekoff(streamoff off, _seek_dir dir, int mode)
+{
+ return _jumps->__seekoff (this, off, convert_to_seekflags(dir, mode));
+}
+
+streampos builtinbuf::seekpos(streampos pos, int mode)
+{
+ int flags = 0;
+ if (!(mode & ios::in))
+ flags |= _IO_seek_not_in;
+ if (!(mode & ios::out))
+ flags |= _IO_seek_not_out;
+ return _jumps->__seekpos(this, pos, (_IO_seekflags)flags);
+}
+
+int builtinbuf::pbackfail(int c)
+{ return _jumps->__pbackfail(this, c); }
+
+streamsize builtinbuf::sys_read(char* buf, streamsize size)
+{ return _jumps->__read(this, buf, size); }
+
+streampos builtinbuf::sys_seek(streamoff off, _seek_dir dir)
+{ return _jumps->__seek(this, off, dir); }
+
+streamsize builtinbuf::sys_write(const char* buf, streamsize size)
+{ return _jumps->__write(this, buf, size); }
+
+int builtinbuf::sys_stat(void* buf) // Actually, a (struct stat*)
+{ return _jumps->__stat(this, buf); }
+
+int builtinbuf::sys_close()
+{ return _jumps->__close(this); }
+
+#ifdef _STREAM_COMPAT
+/* These methods are TEMPORARY, for binary compatibility! */
+#include <stdlib.h>
+void ios::_IO_fix_vtable() const
+{
+ abort ();
+}
+
+void ios::_IO_fix_vtable()
+{
+ ((const ios*) this)->_IO_fix_vtable();
+}
+#endif
diff --git a/gnu/lib/libg++/libio/cleanup.c b/gnu/lib/libg++/libio/cleanup.c
new file mode 100644
index 0000000..35c2ef1
--- /dev/null
+++ b/gnu/lib/libg++/libio/cleanup.c
@@ -0,0 +1,14 @@
+#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;
+#endif /* _G_HAVE_ATEXIT */
diff --git a/gnu/lib/libg++/libio/editbuf.cc b/gnu/lib/libg++/libio/editbuf.cc
new file mode 100644
index 0000000..87358fa
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 mode /* =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 *buf, struct edit_mark *mark, size_t count)
+{
+ 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/lib/libg++/libio/filebuf.cc b/gnu/lib/libg++/libio/filebuf.cc
new file mode 100644
index 0000000..6290636
--- /dev/null
+++ b/gnu/lib/libg++/libio/filebuf.cc
@@ -0,0 +1,199 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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);
+}
+
+/* This is like "new filebuf()", but it uses the _IO_file_jump jumptable,
+ for eficiency. */
+
+filebuf* filebuf::__new()
+{
+ filebuf *fb = new filebuf;
+ fb->_jumps = &_IO_file_jumps;
+ fb->_vtable() = builtinbuf_vtable;
+ return fb;
+}
+
+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 (!(xflags() & _IO_DELETE_DONT_CLOSE))
+ close();
+
+ _un_link();
+}
+
+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 & (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;
+ 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 (sseekoff(0, ios::end) == EOF)
+ return NULL;
+ }
+ _IO_link_in(this);
+ return this;
+}
+
+filebuf* filebuf::open(const char *filename, const char *mode)
+{
+ return (filebuf*)_IO_file_fopen(this, filename, mode);
+}
+
+filebuf* filebuf::attach(int fd)
+{
+ return (filebuf*)_IO_file_attach(this, fd);
+}
+
+streambuf* filebuf::setbuf(char* p, int len)
+{
+ return _IO_file_setbuf(this, p, len) == 0 ? this : NULL;
+}
+
+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::do_write(const char *data, int to_do)
+{
+ return _IO_do_write(this, data, to_do);
+}
+
+int filebuf::sync()
+{
+ return _IO_file_sync(this);
+}
+
+streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
+{
+ return _IO_file_seekoff (this, offset, convert_to_seekflags(dir, mode));
+}
+
+filebuf* filebuf::close()
+{
+ return (_IO_file_close_it(this) ? 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/lib/libg++/libio/filedoalloc.c b/gnu/lib/libg++/libio/filedoalloc.c
new file mode 100644
index 0000000..a85b846
--- /dev/null
+++ b/gnu/lib/libg++/libio/filedoalloc.c
@@ -0,0 +1,103 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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. */
+
+#define _POSIX_SOURCE
+#include "libioP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+/* If this function pointer is non-zero, we should call it.
+ It's supposed 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. */
+void (*_IO_cleanup_registration_needed)();
+
+/*
+ * 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)
+ register _IO_FILE *fp;
+{
+ register _IO_size_t size;
+ int couldbetty;
+ register char *p;
+ struct stat st;
+
+ if (_IO_cleanup_registration_needed)
+ (*_IO_cleanup_registration_needed)();
+
+ if (fp->_fileno < 0 || fp->_jumps->__stat(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
+ }
+ p = ALLOC_BUF(size);
+ if (p == NULL)
+ return EOF;
+ _IO_setb(fp, p, p+size, 1);
+ if (couldbetty && isatty(fp->_fileno))
+ fp->_flags |= _IO_LINE_BUF;
+ return 1;
+}
diff --git a/gnu/lib/libg++/libio/fileops.c b/gnu/lib/libg++/libio/fileops.c
new file mode 100644
index 0000000..47398a8
--- /dev/null
+++ b/gnu/lib/libg++/libio/fileops.c
@@ -0,0 +1,735 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 _POSIX_SOURCE
+#include "libioP.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#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 posistion
+ 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 file_ptr().
+ This is normally egptr(), except in putback mode, when it is _save_egptr.
+ 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, pbase() is non-NULL and equal to base().
+ Also, epptr() == ebuf().
+ Also, eback() == gptr() && gptr() == egptr().
+ The un-flushed character are those between pbase() and pptr().
+ 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, pbase()==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)
+ register _IO_FILE *fp;
+{
+ fp->_offset = _IO_pos_0;
+ fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
+
+ _IO_link_in(fp);
+ fp->_fileno = -1;
+}
+
+int
+_IO_file_close_it(fp)
+ register _IO_FILE* fp;
+{
+ int status;
+ if (!_IO_file_is_open(fp))
+ return EOF;
+
+ _IO_do_flush (fp);
+
+ _IO_unsave_markers(fp);
+
+ status = fp->_jumps->__close(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_0;
+
+ return status;
+}
+
+void
+_IO_file_finish(fp)
+ register _IO_FILE* fp;
+{
+ if (_IO_file_is_open(fp))
+ {
+ _IO_do_flush (fp);
+ if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
+ fp->_jumps->__close(fp);
+ }
+ _IO_default_finish(fp);
+}
+
+_IO_FILE *
+_IO_file_fopen(fp, filename, mode)
+ register _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:
+ 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 (fp->_jumps->__seekoff(fp, (_IO_off_t)0, _IO_seek_end) == _IO_pos_BAD)
+ 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;
+ fp->_offset = _IO_pos_BAD;
+ return fp;
+}
+
+int
+_IO_file_setbuf(fp, p, len)
+ register _IO_FILE *fp;
+ char* p;
+ _IO_ssize_t len;
+{
+ if (_IO_default_setbuf(fp, p, len) == EOF)
+ return EOF;
+
+ 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 0;
+}
+
+int
+_IO_do_write(fp, data, to_do)
+ register _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 = fp->_jumps->__seek(fp, fp->_IO_write_base - fp->_IO_read_end, 1);
+ if (new_pos == _IO_pos_BAD)
+ return EOF;
+ fp->_offset = new_pos;
+ }
+ count = fp->_jumps->__write(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)
+ register _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)
+ 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);
+
+ count = fp->_jumps->__read(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_base = fp->_IO_read_ptr = fp->_IO_buf_base;
+ fp->_IO_read_end = fp->_IO_buf_base + count;
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+ = fp->_IO_buf_base;
+ 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)
+ register _IO_FILE* f;
+ int ch;
+{
+ if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
+ return EOF;
+ /* If current reading or no buffer allocated. */
+ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
+ {
+ /* Allocate a buffer if needed. */
+ if (f->_IO_buf_base == 0)
+ {
+ _IO_doallocbuf(f);
+ f->_IO_read_end = f->_IO_buf_base;
+ f->_IO_write_ptr = f->_IO_buf_base;
+ }
+ else /* Must be currently reading. */
+ 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)
+ register _IO_FILE* fp;
+{
+ _IO_size_t delta;
+ /* 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 = fp->_jumps->__seek(fp, delta, 1);
+ if (new_pos == (_IO_off_t)EOF)
+ return EOF;
+ fp->_offset = new_pos;
+ fp->_IO_read_end = fp->_IO_read_ptr;
+ }
+ /* FIXME: Cleanup - can this be shared? */
+ /* setg(base(), ptr, ptr); */
+ return 0;
+}
+
+_IO_pos_t
+_IO_file_seekoff(fp, offset, mode)
+ register _IO_FILE *fp;
+ _IO_off_t offset;
+ _IO_seekflags mode;
+{
+ _IO_pos_t result;
+ _IO_off_t delta, new_offset;
+ long count;
+ int dir = mode & 3;
+
+ if ((mode & _IO_seek_not_in) && (mode & _IO_seek_not_out))
+ 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:
+ if (fp->_offset == _IO_pos_BAD)
+ goto dumb;
+ /* Adjust for read-ahead (bytes is buffer). */
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ /* 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 (fp->_jumps->__stat(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. */
+
+#ifdef TODO
+ /* If destination is within current buffer, optimize: */
+ if (fp->_offset != IO_pos_BAD && fp->_IO_read_base != NULL)
+ {
+ /* Offset relative to start of main get area. */
+ _IO_pos_t rel_offset = offset - _fb._offset
+ + (eGptr()-Gbase());
+ if (rel_offset >= 0)
+ {
+ if (_IO_in_backup(fp))
+ _IO_switch_to_main_get_area(fp);
+ if (rel_offset <= _IO_read_end - _IO_read_base)
+ {
+ _IO_setg(fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
+ fp->_IO_read_end);
+ _IO_setp(fp->_IO_buf_base, fp->_IO_buf_base);
+ return offset;
+ }
+ /* 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;
+ }
+ }
+ 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;
+ }
+ }
+
+ _IO_unsave_markers(fp);
+#endif
+
+ /* 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 = fp->_jumps->__seek(fp, new_offset, 0);
+ if (result < 0)
+ return EOF;
+ if (delta == 0)
+ count = 0;
+ else
+ {
+ count = fp->_jumps->__read(fp, fp->_IO_buf_base,
+ 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 = fp->_jumps->__seek(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)
+ register _IO_FILE* fp;
+ void* buf;
+ _IO_ssize_t size;
+{
+ for (;;)
+ {
+ _IO_ssize_t count = _IO_read(fp->_fileno, buf, size);
+#ifdef EINTR
+ if (count == -1 && errno == EINTR)
+ continue;
+#endif
+ return count;
+ }
+}
+
+_IO_pos_t
+_IO_file_seek(fp, offset, dir)
+ _IO_FILE *fp;
+ _IO_off_t offset;
+ int dir;
+{
+ return _IO_lseek(fp->_fileno, offset, dir);
+}
+
+int
+_IO_file_stat(fp, st)
+ _IO_FILE *fp;
+ void* st;
+{
+ return _IO_fstat(fp->_fileno, (struct stat*)st);
+}
+
+int
+_IO_file_close(fp)
+ _IO_FILE* fp;
+{
+ return _IO_close(fp->_fileno);
+}
+
+_IO_ssize_t
+_IO_file_write(f, data, n)
+ register _IO_FILE* f;
+ const void* data;
+ _IO_ssize_t n;
+{
+ _IO_ssize_t to_do = n;
+ while (to_do > 0)
+ {
+ _IO_ssize_t count = _IO_write(f->_fileno, data, to_do);
+ if (count == EOF)
+ {
+#ifdef EINTR
+ if (errno == EINTR)
+ continue;
+ else
+#endif
+ {
+ 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 = 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 (;;)
+ {
+ _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; /* Data available. */
+ 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 = fp->_jumps->__read (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 = {
+ _IO_file_overflow,
+ _IO_file_underflow,
+ _IO_file_xsputn,
+ _IO_default_xsgetn,
+ _IO_file_read,
+ _IO_file_write,
+ _IO_file_doallocate,
+ _IO_default_pbackfail,
+ _IO_file_setbuf,
+ _IO_file_sync,
+ _IO_file_finish,
+ _IO_file_close,
+ _IO_file_stat,
+ _IO_file_seek,
+ _IO_file_seekoff,
+ _IO_default_seekpos,
+ _IO_default_uflow
+};
diff --git a/gnu/lib/libg++/libio/floatconv.c b/gnu/lib/libg++/libio/floatconv.c
new file mode 100644
index 0000000..84eb848
--- /dev/null
+++ b/gnu/lib/libg++/libio/floatconv.c
@@ -0,0 +1,2357 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 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). */
+
+/* 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
+
+#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
+
+typedef _G_uint32_t unsigned32;
+
+#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 {
+ double d;
+ unsigned32 u[2];
+ } 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 {
+ double d;
+ unsigned32 x[2];
+} _temp;
+#endif
+#define word0(x) ((unsigned32 *)&x)[HIWORD]
+#if 0
+#define word0(X) (_temp.d = X, _temp.x[HIWORD])
+#define setword0(D,X) (_temp.d = D, _temp.x[HIWORD] = X, D = _temp.d)
+#endif
+#define word1(x) ((unsigned32 *)&x)[LOWORD]
+
+/* 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;
+ long 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;
+ long borrow, y; /* We need signed shifts here. */
+ unsigned32 *xa, *xae, *xb, *xbe, *xc;
+ long 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 long 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
+ word0(a) = L;
+ word1(a) = 0;
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ }
+ else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = 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;
+#ifdef VAX
+ unsigned32 d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ 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;
+ d1 = y << (32-Ebits) + k | w >> Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ d0 = Exp_1 | y << k | z >> 32 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k | y >> 32 - k;
+ }
+ else {
+ d0 = Exp_1 | y;
+ d1 = z;
+ }
+ ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return d;
+ }
+
+static Bigint *
+d2b
+#ifdef KR_headers
+ (result, d, e, bits) Bigint *result; double d; int *e, *bits;
+#else
+ (Bigint *result, double d, int *e, int *bits)
+#endif
+{
+ int de, i, k;
+ unsigned32 *x, y, z;
+#ifdef VAX
+ unsigned32 d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define 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
+
+ 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 {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = result->wds = 1;
+ k += 32;
+ }
+#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;
+ }
+#undef d0
+#undef d1
+
+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) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return da / db;
+ }
+
+static 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
+ };
+
+static double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static 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
+{
+ int 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;
+ long 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.;
+ 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:
+ word0(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;
+ word0(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. */
+ word0(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) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(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;
+ }
+ word0(rv) = Tiny0;
+ word1(rv) = 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*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(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
+ word0(rv) = L | Bndry_mask1;
+ word1(rv) = 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;
+ word0(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;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ continue;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ word0(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;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ continue;
+ }
+ else
+ word0(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 = (long)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;
+ long borrow, y;
+ unsigned32 carry, q, ys;
+ unsigned32 *bx, *bxe, *sx, *sxe;
+ long 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.
+ */
+
+ int 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;
+ long 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;
+ 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;
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= 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;
+ word0(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.;
+ word0(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 = (long)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 = (long)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 = (long)(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 /* USE_DTOA */
diff --git a/gnu/lib/libg++/libio/fstream.cc b/gnu/lib/libg++/libio/fstream.cc
new file mode 100644
index 0000000..a9ca9f6
--- /dev/null
+++ b/gnu/lib/libg++/libio/fstream.cc
@@ -0,0 +1,84 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+fstreambase::fstreambase()
+{
+ init(filebuf::__new());
+}
+
+fstreambase::fstreambase(int fd)
+{
+ init(filebuf::__new());
+ _IO_file_attach(rdbuf(), fd);
+}
+
+fstreambase::fstreambase(const char *name, int mode, int prot)
+{
+ init(filebuf::__new());
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+fstreambase::fstreambase(int fd, char *p, int l)
+{
+ init(filebuf::__new());
+ _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);
+}
+
+#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/lib/libg++/libio/genops.c b/gnu/lib/libg++/libio/genops.c
new file mode 100644
index 0000000..469694c
--- /dev/null
+++ b/gnu/lib/libg++/libio/genops.c
@@ -0,0 +1,867 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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. */
+
+_IO_size_t
+_IO_least_marker(fp)
+ register _IO_FILE *fp;
+{
+ _IO_ssize_t least_so_far = fp->_IO_read_end - fp->_IO_read_base;
+ register 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)
+ register _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)
+ register _IO_FILE *fp;
+{
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ if (fp->_jumps->__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)
+ register _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)
+ register _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 f->_jumps->__overflow(f, ch);
+}
+
+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 fp->_jumps->__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 fp->_jumps->__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);
+ 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)
+ register _IO_FILE *fp;
+{
+ if (fp->_IO_buf_base)
+ return;
+ if (!(fp->_flags & _IO_UNBUFFERED))
+ if (fp->_jumps->__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 = fp->_jumps->__underflow(fp);
+ if (ch == EOF)
+ return EOF;
+ return *(unsigned char*)fp->_IO_read_ptr++;
+}
+
+_IO_size_t
+_IO_default_xsputn(f, data, n)
+ register _IO_FILE *f;
+ const void *data;
+ _IO_size_t n;
+{
+ register const char *s = data;
+ register _IO_size_t more = n;
+ if (more <= 0)
+ return 0;
+ for (;;)
+ {
+ _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+ if (count > 0)
+ {
+ if (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
+ {
+ register char *p = f->_IO_write_ptr;
+ register _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 fp->_jumps->__xsgetn(fp, data, n);
+}
+
+_IO_size_t
+_IO_default_xsgetn(fp, data, n)
+ _IO_FILE *fp;
+ void *data;
+ _IO_size_t n;
+{
+ register _IO_size_t more = n;
+ register char *s = data;
+ for (;;)
+ {
+ _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; /* Data available. */
+ 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 (more == 0 || __underflow(fp) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+int
+_IO_sync(fp)
+ register _IO_FILE *fp;
+{
+ if (fp->_IO_read_ptr == fp->_IO_read_end && fp->_IO_write_ptr == fp->_IO_write_base)
+ return 0;
+ return EOF;
+}
+
+int
+_IO_default_setbuf(fp, p, len)
+ register _IO_FILE *fp;
+ char* p;
+ _IO_ssize_t len;
+{
+ if (fp->_jumps->__sync(fp) == EOF)
+ return EOF;
+ 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 0;
+}
+
+_IO_pos_t
+_IO_default_seekpos(fp, pos, mode)
+ _IO_FILE *fp;
+ _IO_pos_t pos;
+ _IO_seekflags mode;
+{
+ return fp->_jumps->__seekoff(fp, _IO_pos_as_off(pos), mode);
+}
+
+int
+_IO_default_doallocate(fp)
+ _IO_FILE *fp;
+{
+ char *buf = ALLOC_BUF(_IO_BUFSIZ);
+ if (buf == NULL)
+ return EOF;
+ _IO_setb(fp, buf, buf+_IO_BUFSIZ, 1);
+ return 1;
+}
+
+void
+_IO_init(fp, flags)
+ register _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;
+}
+
+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)
+ _IO_FILE *fp;
+{
+ struct _IO_marker *mark;
+ if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+ {
+ FREE_BUF(fp->_IO_buf_base);
+ 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;
+ }
+
+ _IO_un_link(fp);
+}
+
+_IO_pos_t
+_IO_default_seekoff(fp, offset, mode)
+ register _IO_FILE *fp;
+ _IO_off_t offset;
+ _IO_seekflags mode;
+{
+ return _IO_pos_BAD;
+}
+
+int
+_IO_sputbackc(fp, c) /* ungetc(c, fp) */
+ register _IO_FILE *fp;
+ int c;
+{
+ if (fp->_IO_read_ptr > fp->_IO_read_base
+ && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
+ {
+ fp->_IO_read_ptr--;
+ return (unsigned char)c;
+ }
+ return fp->_jumps->__pbackfail(fp, c);
+}
+
+int
+_IO_sungetc(fp)
+ register _IO_FILE *fp;
+{
+ if (fp->_IO_read_ptr > fp->_IO_read_base)
+ {
+ fp->_IO_read_ptr--;
+ return (unsigned char)*fp->_IO_read_ptr;
+ }
+ else
+ return fp->_jumps->__pbackfail(fp, EOF);
+}
+
+#if 0 /* Work in progress */
+void
+_IO_set_column(fp, c)
+ register _IO_FILE *fp;
+ int c;
+{
+ if (c == -1)
+ fp->_collumn = -1;
+ else
+ fp->_collumn = c - (fp->_IO_write_ptr - fp->_IO_write_base);
+}
+#else
+int
+_IO_set_column(fp, i)
+ register _IO_FILE *fp;
+ int i;
+{
+ fp->_cur_column = i+1;
+ return 0;
+}
+#endif
+
+
+unsigned
+_IO_adjust_column(start, line, count)
+ unsigned start;
+ const char *line;
+ int count;
+{
+ register const char *ptr = line + count;
+ while (ptr > line)
+ if (*--ptr == '\n')
+ return line + count - ptr - 1;
+ return start + count;
+}
+
+int
+_IO_get_column(fp)
+ register _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;
+}
+
+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
+ && fp->_jumps->__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_LINE_BUF)
+ fp->_jumps->__overflow(fp, EOF);
+}
+
+void
+_IO_unbuffer_all ()
+{
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if (! (fp->_flags & _IO_UNBUFFERED))
+ fp->_jumps->__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 destructord 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)
+ register struct _IO_marker * marker;
+{
+ /* Unlink from sb's chain. */
+ register 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 posistion 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)
+ register _IO_FILE *fp;
+{
+ register 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);
+}
+
+int
+_IO_nobackup_pbackfail(fp, c)
+ register _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;
+}
+
+int
+_IO_default_pbackfail(fp, c)
+ register _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)
+ register _IO_FILE* fp;
+ void* data;
+ _IO_ssize_t n;
+{
+ return -1;
+}
+
+_IO_ssize_t
+_IO_default_write(fp, data, n)
+ register _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 */
diff --git a/gnu/lib/libg++/libio/indstream.cc b/gnu/lib/libg++/libio/indstream.cc
new file mode 100644
index 0000000..1468d45
--- /dev/null
+++ b/gnu/lib/libg++/libio/indstream.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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();
+}
+
+int indirectbuf::xsputn(const char* s, int n)
+{
+ return put_stream()->sputn(s, n);
+}
+
+int indirectbuf::xsgetn(char* s, int 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()->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() : NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : 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() : NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : NULL;
+ if (gbuf == pbuf)
+ 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/lib/libg++/libio/ioextend.cc b/gnu/lib/libg++/libio/ioextend.cc
new file mode 100644
index 0000000..bc6a3e1
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioextend.cc
@@ -0,0 +1,129 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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
+| ios::unitbuf | ios::stdio | ios::dont_close;
+
+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 = (void*)0;
+ }
+ new_array[0].i = new_length;
+ new_array[0].p = (void*)0;
+ 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/lib/libg++/libio/iofclose.c b/gnu/lib/libg++/libio/iofclose.c
new file mode 100644
index 0000000..44664d9
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofclose.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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)
+ register _IO_FILE *fp;
+{
+ int status = 0;
+ COERCE_FILE(fp);
+ if ((fp->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC)
+ return EOF;
+ if (fp->_IO_file_flags & _IO_IS_FILEBUF)
+ status = _IO_file_close_it(fp);
+ fp->_jumps->__finish(fp);
+ if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
+ {
+ fp->_IO_file_flags = 0;
+ free(fp);
+ }
+ return status;
+}
diff --git a/gnu/lib/libg++/libio/iofgetpos.c b/gnu/lib/libg++/libio/iofgetpos.c
new file mode 100644
index 0000000..16ecec0
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofgetpos.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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. */
+
+int
+_IO_fgetpos(fp, posp)
+ _IO_FILE* fp;
+ _IO_fpos_t *posp;
+{
+ _IO_fpos_t pos;
+ COERCE_FILE(fp);
+ pos = _IO_seekoff(fp, 0, _IO_seek_cur|_IO_seek_not_in|_IO_seek_not_out);
+ if (pos == _IO_pos_BAD)
+ {
+#ifdef EIO
+ if (errno == 0)
+ errno = EIO;
+#endif
+ return EOF;
+ }
+ *posp = pos;
+ return 0;
+}
diff --git a/gnu/lib/libg++/libio/iofread.c b/gnu/lib/libg++/libio/iofread.c
new file mode 100644
index 0000000..c72c70f
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofread.c
@@ -0,0 +1,41 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+ COERCE_FILE(fp);
+ if (bytes_requested == 0)
+ return 0;
+ bytes_read = _IO_sgetn(fp, (char *)buf, bytes_requested);
+ return bytes_requested == bytes_read ? count : bytes_read / size;
+}
diff --git a/gnu/lib/libg++/libio/iofscanf.c b/gnu/lib/libg++/libio/iofscanf.c
new file mode 100644
index 0000000..7110401
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+ COERCE_FILE(fp);
+ _IO_va_start(args, format);
+ ret = _IO_vfscanf(fp, format, args, NULL);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/iofsetpos.c b/gnu/lib/libg++/libio/iofsetpos.c
new file mode 100644
index 0000000..763fbe6
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofsetpos.c
@@ -0,0 +1,44 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+{
+ COERCE_FILE(fp);
+ if (_IO_seekpos(fp, *posp, 0) == _IO_pos_BAD)
+ {
+ /*ANSI explicily requires setting errno to a positive value on failure.*/
+#ifdef EIO
+ if (errno == 0)
+ errno = EIO;
+#endif
+ return EOF;
+ }
+ return 0;
+}
diff --git a/gnu/lib/libg++/libio/iogetline.c b/gnu/lib/libg++/libio/iogetline.c
new file mode 100644
index 0000000..dcaa4a1
--- /dev/null
+++ b/gnu/lib/libg++/libio/iogetline.c
@@ -0,0 +1,77 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+/* 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(fp, buf, n, delim, extract_delim)
+ _IO_FILE *fp;
+ char* buf;
+ _IO_size_t n;
+ int delim;
+ int extract_delim;
+{
+ register char *ptr = buf;
+ do
+ {
+ _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr;
+ char *t;
+ if (len <= 0)
+ if (__underflow(fp) == EOF)
+ break;
+ else
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (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;
+}
diff --git a/gnu/lib/libg++/libio/ioignore.c b/gnu/lib/libg++/libio/ioignore.c
new file mode 100644
index 0000000..1b26503
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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)
+ register _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/lib/libg++/libio/iomanip.cc b/gnu/lib/libg++/libio/iomanip.cc
new file mode 100644
index 0000000..bb15f64
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/iopadn.c b/gnu/lib/libg++/libio/iopadn.c
new file mode 100644
index 0000000..84dcee6
--- /dev/null
+++ b/gnu/lib/libg++/libio/iopadn.c
@@ -0,0 +1,67 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+ register int i;
+ _IO_size_t written = 0, 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/lib/libg++/libio/iopopen.c b/gnu/lib/libg++/libio/iopopen.c
new file mode 100644
index 0000000..dfa3482
--- /dev/null
+++ b/gnu/lib/libg++/libio/iopopen.c
@@ -0,0 +1,221 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 _POSIX_SOURCE
+#include "libioP.h"
+#if _IO_HAVE_SYS_WAIT
+#include <signal.h>
+#include <unistd.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <sys/wait.h>
+
+#ifndef _IO_fork
+#define _IO_fork vfork /* defined in libiberty, if needed */
+_IO_pid_t _IO_fork();
+#endif
+
+#endif /* _IO_HAVE_SYS_WAIT */
+
+#ifndef _IO_pipe
+#define _IO_pipe pipe
+extern int _IO_pipe();
+#endif
+
+#ifndef _IO_dup2
+#define _IO_dup2 dup2
+extern int _IO_dup2();
+#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
+
+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
+ int read_or_write;
+ int pipe_fds[2];
+ int parent_end, child_end;
+ _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, NULL);
+ _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;
+{
+ _IO_proc_file *fpx = (_IO_proc_file*)malloc(sizeof(_IO_proc_file));
+ _IO_FILE *fp = (_IO_FILE*)fpx;
+ if (fp == NULL)
+ return NULL;
+ _IO_init(fp, 0);
+ fp->_jumps = &_IO_proc_jumps;
+ _IO_file_init(fp);
+ ((struct _IO_FILE_plus*)fp)->vtable = NULL;
+ if (_IO_proc_open (fp, command, mode) != NULL)
+ return fp;
+ free (fpx);
+ return NULL;
+}
+
+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 = {
+ _IO_file_overflow,
+ _IO_file_underflow,
+ _IO_file_xsputn,
+ _IO_default_xsgetn,
+ _IO_file_read,
+ _IO_file_write,
+ _IO_file_doallocate,
+ _IO_default_pbackfail,
+ _IO_file_setbuf,
+ _IO_file_sync,
+ _IO_file_finish,
+ _IO_proc_close,
+ _IO_file_stat,
+ _IO_file_seek,
+ _IO_file_seekoff,
+ _IO_default_seekpos,
+ _IO_default_uflow
+};
diff --git a/gnu/lib/libg++/libio/ioprims.c b/gnu/lib/libg++/libio/ioprims.c
new file mode 100644
index 0000000..4c41ed8
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioprims.c
@@ -0,0 +1,79 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+#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/lib/libg++/libio/ioprintf.c b/gnu/lib/libg++/libio/ioprintf.c
new file mode 100644
index 0000000..519785a
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/ioseekoff.c b/gnu/lib/libg++/libio/ioseekoff.c
new file mode 100644
index 0000000..7ebf183
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioseekoff.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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, flags)
+ _IO_FILE* fp;
+ _IO_off_t offset;
+ _IO_seekflags flags;
+{
+ int dir = flags & 3;
+
+ /* 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 */
+
+ 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);
+ }
+
+ return fp->_jumps->__seekoff(fp, offset, flags);
+}
diff --git a/gnu/lib/libg++/libio/ioseekpos.c b/gnu/lib/libg++/libio/ioseekpos.c
new file mode 100644
index 0000000..a99b703
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioseekpos.c
@@ -0,0 +1,41 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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, flags)
+ _IO_FILE* fp;
+ _IO_pos_t pos;
+ _IO_seekflags flags;
+{
+ /* 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 */
+
+ if (_IO_have_backup (fp))
+ _IO_free_backup_area (fp);
+
+ return fp->_jumps->__seekpos(fp, pos, flags);
+}
diff --git a/gnu/lib/libg++/libio/iostream.cc b/gnu/lib/libg++/libio/iostream.cc
new file mode 100644
index 0000000..db953d4
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostream.cc
@@ -0,0 +1,813 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+#include "floatio.h"
+
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+
+//#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
+
+istream::istream(streambuf *sb, ostream* tied)
+{
+ init (sb, tied);
+ _flags |= ios::dont_close;
+ _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;
+ }
+ }
+ 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 */)
+{
+ if (ipfx1()) {
+ register streambuf* sb = _strbuf;
+ if (delim == EOF) {
+ _gcount = sb->ignore(n);
+ return *this;
+ }
+ _gcount = 0;
+ 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, int n)
+{
+ if (ipfx1()) {
+ _gcount = _strbuf->sgetn(s, n);
+ if (_gcount != n)
+ set(ios::failbit|ios::eofbit);
+ }
+ return *this;
+}
+
+istream& istream::seekg(streampos pos)
+{
+ pos = _strbuf->sseekpos(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,
+ (_IO_seekflags)
+ ((int)dir | _IO_seek_not_out | _IO_seek_pos_ignored));
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos istream::tellg()
+{
+#if 0
+ streampos pos = _strbuf->sseekoff(0, ios::cur, ios::in);
+#else
+ streampos pos
+ = _IO_seekoff (_strbuf, 0,
+ (_IO_seekflags)(_IO_seek_cur | _IO_seek_not_out));
+#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(p == ptr ? (ios::eofbit|ios::failbit) : (ios::eofbit));
+ break;
+ }
+ else if (isspace(ch))
+ {
+ sb->sputbackc(ch);
+ break;
+ }
+ else if (w == 1)
+ {
+ set(ios::failbit);
+ sb->sputbackc(ch);
+ break;
+ }
+ else *p++ = ch;
+ w--;
+ }
+ }
+ *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>>(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()) {
+#if 1
+ // This is what the cfront implementation does.
+ if (_strbuf->sputc(c) == EOF)
+ 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)
+ goto failed;
+ if (sb->sputc(c) == EOF)
+ goto failed;
+ if (flags() & ios::left && padding) // Left adjustment.
+ if (_IO_padn(sb, fill_char, padding) < padding)
+ goto failed;
+#endif
+ osfx();
+ }
+ return *this;
+ failed:
+ set(ios::badbit);
+ osfx();
+ 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.
+ 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
+ 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()) {
+ 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);
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(unsigned int n)
+{
+ if (opfx())
+ write_int(*this, n, 0);
+ return *this;
+}
+
+
+ostream& ostream::operator<<(long n)
+{
+ if (opfx()) {
+ 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);
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(unsigned long n)
+{
+ if (opfx())
+ write_int(*this, n, 0);
+ return *this;
+}
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+ostream& ostream::operator<<(long long n)
+{
+ if (opfx()) {
+ 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);
+ }
+ return *this;
+}
+
+
+ostream& ostream::operator<<(unsigned long long n)
+{
+ if (opfx())
+ write_int(*this, n, 0);
+ return *this;
+}
+#endif /*__GNUC__*/
+
+ostream& ostream::operator<<(double n)
+{
+ if (opfx()) {
+ // 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.
+#ifdef 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();
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(const char *s)
+{
+ if (opfx())
+ {
+ 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)
+ goto failed;
+ if (_IO_sputn (sbuf, s, len) != len)
+ goto failed;
+ if (flags() & ios::left && padding > 0) // Left adjustment.
+ if (_IO_padn(sbuf, fill_char, padding) != padding)
+ goto failed;
+ osfx();
+ }
+ return *this;
+ failed:
+ set(ios::badbit);
+ osfx();
+ 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())
+ {
+ 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();
+ }
+ return *this;
+}
+
+ostream::ostream(streambuf* sb, ostream* tied)
+{
+ init (sb, tied);
+ _flags |= ios::dont_close;
+}
+
+ostream& ostream::seekp(streampos pos)
+{
+ pos = _strbuf->sseekpos(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,
+ (_IO_seekflags)
+ ((int)dir | _IO_seek_not_in | _IO_seek_pos_ignored));
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos ostream::tellp()
+{
+#if 1
+ streampos pos
+ = _IO_seekoff (_strbuf, 0,
+ (_IO_seekflags)(_IO_seek_cur | _IO_seek_not_in));
+#else
+ streampos pos = _strbuf->sseekoff(0, ios::cur, ios::out);
+#endif
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+ostream& ostream::flush()
+{
+ if (_strbuf->_jumps->__sync(_strbuf))
+ set(ios::badbit);
+ return *this;
+}
+
+ostream& flush(ostream& outs)
+{
+ return outs.flush();
+}
+
+istream& ws(istream& ins)
+{
+ if (ins.ipfx1()) {
+ int ch = skip_ws(ins._strbuf);
+ if (ch == EOF)
+ ins.set(ios::eofbit);
+ else
+ ins._strbuf->sputbackc(ch);
+ }
+ 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'));
+}
+
+ostream& ostream::write(const char *s, int n)
+{
+ if (opfx()) {
+ if (_IO_sputn(_strbuf, s, n) != n)
+ set(ios::failbit);
+ }
+ 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);
+ _flags |= ios::dont_close;
+}
+
+// NOTE: extension for compatibility with old libg++.
+// Not really compatible with fistream::close().
+#ifdef _STREAM_COMPAT
+void ios::close()
+{
+ if (!(_flags & (unsigned int)ios::dont_close))
+ delete rdbuf();
+ else if (_strbuf->_flags & _IO_IS_FILEBUF)
+ ((struct filebuf*)rdbuf())->close();
+ else if (_strbuf != NULL)
+ rdbuf()->sync();
+ _flags |= ios::dont_close;
+ _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/lib/libg++/libio/iostrerror.c b/gnu/lib/libg++/libio/iostrerror.c
new file mode 100644
index 0000000..2833fc7
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostrerror.c
@@ -0,0 +1,11 @@
+/* This should be replaced by whatever namespace-clean
+ version of strerror you have available. */
+
+extern char *strerror();
+
+char *
+_IO_strerror(errnum)
+ int errnum;
+{
+ return strerror(errnum);
+}
diff --git a/gnu/lib/libg++/libio/ioungetc.c b/gnu/lib/libg++/libio/ioungetc.c
new file mode 100644
index 0000000..7b983ed
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioungetc.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+{
+ COERCE_FILE(fp);
+ if (c == EOF)
+ return EOF;
+ return _IO_sputbackc(fp, (unsigned char)c);
+}
diff --git a/gnu/lib/libg++/libio/iovfprintf.c b/gnu/lib/libg++/libio/iovfprintf.c
new file mode 100644
index 0000000..feda569
--- /dev/null
+++ b/gnu/lib/libg++/libio/iovfprintf.c
@@ -0,0 +1,885 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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
+
+/*
+ * 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 = {
+ _IO_helper_overflow,
+ _IO_default_underflow,
+ _IO_default_xsputn,
+ _IO_default_xsgetn,
+ _IO_default_read,
+ _IO_default_write,
+ _IO_default_doallocate,
+ _IO_default_pbackfail,
+ _IO_default_setbuf,
+ _IO_default_sync,
+ _IO_default_finish,
+ _IO_default_close,
+ _IO_default_stat,
+ _IO_default_seek,
+ _IO_default_seekoff,
+ _IO_default_seekpos,
+ _IO_default_uflow
+};
+
+static int
+helper_vfprintf(fp, fmt0, ap)
+ register _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;
+ hp->_jumps = &_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)
+ register _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 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 (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 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 (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 (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(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; 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(USE_DTOA) */
diff --git a/gnu/lib/libg++/libio/iovfscanf.c b/gnu/lib/libg++/libio/iovfscanf.c
new file mode 100644
index 0000000..abf1e58
--- /dev/null
+++ b/gnu/lib/libg++/libio/iovfscanf.c
@@ -0,0 +1,784 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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
+
+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 USE_DTOA
+extern double atof();
+#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)
+ register _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 =
+ (*fp->_jumps->__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 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)
+ register char *tab;
+ register 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/lib/libg++/libio/isgetline.cc b/gnu/lib/libg++/libio/isgetline.cc
new file mode 100644
index 0000000..87722af
--- /dev/null
+++ b/gnu/lib/libg++/libio/isgetline.cc
@@ -0,0 +1,140 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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(sb, buf, len - 1, delim, -1);
+ 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();
+ long count = _IO_getline(sbuf, buf, len - 1, delim, -1);
+ if (count == 0 && sbuf->sgetc() == 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(sb, buf, CHUNK_SIZE, terminator, -1);
+ 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;
+ }
+
+ if (ptr = new char[total+1]) {
+ ptr[total] = '\0';
+ memcpy(ptr + total - count, buf, count);
+ return ptr;
+ }
+ else
+ return NULL;
+}
+
+/* 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/lib/libg++/libio/isgetsb.cc b/gnu/lib/libg++/libio/isgetsb.cc
new file mode 100644
index 0000000..2c5397f
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/isscan.cc b/gnu/lib/libg++/libio/isscan.cc
new file mode 100644
index 0000000..4e4ef83
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/osform.cc b/gnu/lib/libg++/libio/osform.cc
new file mode 100644
index 0000000..b4d4999
--- /dev/null
+++ b/gnu/lib/libg++/libio/osform.cc
@@ -0,0 +1,54 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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()) {
+ va_list ap;
+ va_start(ap, format);
+ _IO_vfprintf(rdbuf(), format, ap);
+ va_end(ap);
+ }
+ return *this;
+}
+
+ostream& ostream::vform(const char *format, _IO_va_list args)
+{
+ if (opfx())
+ _IO_vfprintf(rdbuf(), format, args);
+ return *this;
+}
+
+ostream& ostream::operator<<(const void *p)
+{
+ if (opfx()) {
+ form("%p", p);
+ osfx();
+ }
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/outfloat.c b/gnu/lib/libg++/libio/outfloat.c
new file mode 100644
index 0000000..7f4559b
--- /dev/null
+++ b/gnu/lib/libg++/libio/outfloat.c
@@ -0,0 +1,209 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
+
+/* 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;
+}
diff --git a/gnu/lib/libg++/libio/parsestream.cc b/gnu/lib/libg++/libio/parsestream.cc
new file mode 100644
index 0000000..3e986e3
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 = ALLOC_BUF(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 0; // Suppress warning.
+#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/lib/libg++/libio/pfstream.cc b/gnu/lib/libg++/libio/pfstream.cc
new file mode 100644
index 0000000..3dfa16f
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/procbuf.cc b/gnu/lib/libg++/libio/procbuf.cc
new file mode 100644
index 0000000..797bf48
--- /dev/null
+++ b/gnu/lib/libg++/libio/procbuf.cc
@@ -0,0 +1,51 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 _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/lib/libg++/libio/sbform.cc b/gnu/lib/libg++/libio/sbform.cc
new file mode 100644
index 0000000..42f91e3
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/sbgetline.cc b/gnu/lib/libg++/libio/sbgetline.cc
new file mode 100644
index 0000000..f8ee260
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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(this, buf, n, delim, extract_delim);
+}
diff --git a/gnu/lib/libg++/libio/sbscan.cc b/gnu/lib/libg++/libio/sbscan.cc
new file mode 100644
index 0000000..d9af571
--- /dev/null
+++ b/gnu/lib/libg++/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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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/lib/libg++/libio/stdiostream.cc b/gnu/lib/libg++/libio/stdiostream.cc
new file mode 100644
index 0000000..eb3dd16
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdiostream.cc
@@ -0,0 +1,146 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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)
+{
+ 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/lib/libg++/libio/stdstrbufs.cc b/gnu/lib/libg++/libio/stdstrbufs.cc
new file mode 100644
index 0000000..6598c1f
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdstrbufs.cc
@@ -0,0 +1,89 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+#ifndef STD_VTABLE
+#define STD_VTABLE builtinbuf_vtable
+#endif
+
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ struct _IO_FILE_plus NAME = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), STD_VTABLE}
+
+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 {
+ _IO_FILE file;
+ const void *vtable;
+ FILE *stdio_file;
+};
+
+/* Define stdiobuf_vtable as a name for the virtual function table
+ of the stdiobuf class. */
+#ifndef stdiobuf_vtable
+#ifdef __GNUC__
+extern char 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 char stdiobuf_vtable[];
+#endif /* !__GNUC__ */
+#endif /* !stdiobuf_vtable */
+
+#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, &_IO_streambuf_jumps, FD},\
+ stdiobuf_vtable, FILE}
+
+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.file);
+DEF_STDIOFILE(_IO_stderr_buf, 2, stderr, _IO_NO_READS, &_IO_stdout_buf.file);
+
+_IO_FILE *_IO_list_all = &_IO_stderr_buf.file;
+#endif /* !_STDIO_USES_IOSTREAM */
diff --git a/gnu/lib/libg++/libio/stdstreams.cc b/gnu/lib/libg++/libio/stdstreams.cc
new file mode 100644
index 0000000..18055a7
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdstreams.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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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];
+};
+
+#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
+ (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
+
+#ifdef __GNUC__
+#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
+ _fake_ostream NAME = { {&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. */
+OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0)
+
+// 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/lib/libg++/libio/stream.cc b/gnu/lib/libg++/libio/stream.cc
new file mode 100644
index 0000000..543071c
--- /dev/null
+++ b/gnu/lib/libg++/libio/stream.cc
@@ -0,0 +1,144 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 "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);
+}
diff --git a/gnu/lib/libg++/libio/streambuf.cc b/gnu/lib/libg++/libio/streambuf.cc
new file mode 100644
index 0000000..a484572
--- /dev/null
+++ b/gnu/lib/libg++/libio/streambuf.cc
@@ -0,0 +1,341 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1991, 1992, 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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::overflow(int c /* = 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()
+{
+ if (pptr() == pbase())
+ return 0;
+ return EOF;
+}
+
+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, convert_to_seekflags (0, 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); }
+
+/* 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, _IO_seekflags m)
+{
+ int mode = ((m & _IO_seek_not_in) ? 0 : ios::in)
+ + ((m & _IO_seek_not_out) ? 0 : ios::out);
+ return ((streambuf*)fp)->seekoff(pos, (_seek_dir)((int)m & 3), mode);
+}
+
+static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, _IO_seekflags m)
+{
+ int mode = ((m & _IO_seek_not_in) ? 0 : ios::in)
+ + ((m & _IO_seek_not_out) ? 0 : ios::out);
+ 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)
+{ ((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 int _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->setbuf(buf, n) == NULL ? EOF : 0; }
+
+/* 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 = {
+ _IO_sb_overflow,
+ _IO_sb_underflow,
+ _IO_sb_xsputn,
+ _IO_sb_xsgetn,
+ _IO_sb_read,
+ _IO_sb_write,
+ _IO_sb_doallocate,
+ _IO_sb_pbackfail,
+ _IO_sb_setbuf,
+ _IO_sb_sync,
+ _IO_sb_finish,
+ _IO_sb_close,
+ _IO_sb_stat,
+ _IO_sb_seek,
+ _IO_sb_seekoff,
+ _IO_sb_seekpos,
+ _IO_default_uflow
+};
+
+streambuf::streambuf(int flags)
+{
+ _IO_init(this, flags);
+ _jumps = &_IO_streambuf_jumps;
+}
+
+streambuf::~streambuf() { _IO_default_finish(this); }
+
+streampos
+streambuf::seekoff(streamoff, _seek_dir, int mode /*=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, convert_to_seekflags (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 */ }
+
+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/lib/libg++/libio/strops.c b/gnu/lib/libg++/libio/strops.c
new file mode 100644
index 0000000..f507343
--- /dev/null
+++ b/gnu/lib/libg++/libio/strops.c
@@ -0,0 +1,292 @@
+/*
+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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+#define LEN(fp) (((_IO_strfile*)(fp))->_s._len)
+
+#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 ... */
+#if 1
+ int s;
+ size = 512;
+ /* Try increasing powers of 2, as long as we don't wrap around.
+ This can lose in pathological cases (ptr near the end
+ of the address space). A better solution might be to
+ adjust the size on underflow/overflow. FIXME. */
+ for (s; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+ size = s;
+ size = s;
+#else
+ /* The following semi-portable kludge assumes that
+ sizeof(unsigned long) == sizeof(char*). Hence,
+ (unsigned long)(-1) should be the largest possible address. */
+ unsigned long highest = (unsigned long)(-1);
+ /* Pointers are signed on some brain-damaged systems, in
+ which case we divide by two to get the maximum signed address. */
+ if ((char*)highest < ptr)
+ highest >>= 1;
+ size = (char*)highest - ptr;
+#endif
+ }
+ _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;
+ }
+ LEN(fp) = 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)
+ register _IO_FILE* fp;
+ int c;
+{
+ int flush_only = c == EOF;
+ _IO_size_t pos = fp->_IO_write_ptr - fp->_IO_write_base;
+ _IO_size_t get_pos = fp->_IO_read_ptr - fp->_IO_read_base;
+ if (fp->_flags & _IO_NO_WRITES)
+ return flush_only ? 0 : EOF;
+ if (pos > LEN(fp)) LEN(fp) = pos;
+ if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ pos = get_pos;
+ fp->_flags |= _IO_CURRENTLY_PUTTING;
+ get_pos = LEN(fp);
+ }
+ if (pos >= _IO_blen(fp) + flush_only)
+ {
+ if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
+ {
+#ifdef TODO
+ if (indefinite size)
+ {
+ fp->_IO_buf_end += 512;
+ }
+ else
+#endif
+ return EOF;
+ }
+ else
+ {
+ char *new_buf;
+ _IO_size_t new_size = 2 * _IO_blen(fp);
+ new_buf
+ = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
+ if (new_buf == NULL)
+ {
+ /* __ferror(fp) = 1; */
+ return EOF;
+ }
+ memcpy(new_buf, fp->_IO_buf_base, _IO_blen(fp));
+#if 0
+ if (lenp == &LEN(fp)) /* use '\0'-filling */
+ memset(new_buf + pos, 0, blen() - pos);
+#endif
+ if (fp->_IO_buf_base)
+ {
+ (*((_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;
+ }
+ _IO_setb(fp, new_buf, new_buf + new_size, 1);
+ fp->_IO_write_base = new_buf;
+ }
+ fp->_IO_write_end = fp->_IO_buf_end;
+ }
+
+ fp->_IO_write_ptr = fp->_IO_buf_base + pos;
+
+ fp->_IO_read_base = fp->_IO_buf_base;
+ fp->_IO_read_ptr = fp->_IO_buf_base + get_pos;;
+ fp->_IO_read_end = fp->_IO_buf_base + LEN(fp);;
+
+ if (!flush_only)
+ *fp->_IO_write_ptr++ = (unsigned char) c;
+ return c;
+}
+
+int
+_IO_str_underflow (fp)
+ register _IO_FILE* fp;
+{
+ _IO_size_t ppos = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (ppos > LEN(fp)) LEN(fp) = ppos;
+ if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ fp->_IO_write_ptr = fp->_IO_write_end;
+ }
+ fp->_IO_read_end = fp->_IO_read_base + LEN(fp);
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *fp->_IO_read_ptr;
+ else
+ return EOF;
+}
+
+_IO_ssize_t
+_IO_str_count (fp)
+ register _IO_FILE *fp;
+{
+ _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (put_len < ((_IO_strfile*)fp)->_s._len)
+ put_len = ((_IO_strfile*)fp)->_s._len;
+ return put_len;
+}
+
+_IO_pos_t
+_IO_str_seekoff(fp, offset, mode)
+ register _IO_FILE *fp;
+ _IO_off_t offset;
+ _IO_seekflags mode;
+{
+ _IO_ssize_t cur_size = _IO_str_count(fp);
+ _IO_pos_t new_pos = EOF;
+ int dir = mode & 3;
+
+ /* Move the get pointer, if requested. */
+ if (!(mode & _IO_seek_not_in))
+ {
+ 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_size_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 & _IO_seek_not_out))
+ {
+ 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_size_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)
+ register _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)
+ register _IO_FILE* fp;
+{
+ 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);
+}
+
+struct _IO_jump_t _IO_str_jumps = {
+ _IO_str_overflow,
+ _IO_str_underflow,
+ _IO_default_xsputn,
+ _IO_default_xsgetn,
+ _IO_default_read,
+ _IO_default_write,
+ _IO_default_doallocate,
+ _IO_str_pbackfail,
+ _IO_default_setbuf,
+ _IO_default_sync,
+ _IO_str_finish,
+ _IO_default_close,
+ _IO_default_stat,
+ _IO_default_seek,
+ _IO_str_seekoff,
+ _IO_default_seekpos,
+ _IO_default_uflow
+};
diff --git a/gnu/lib/libg++/libio/strstream.cc b/gnu/lib/libg++/libio/strstream.cc
new file mode 100644
index 0000000..c17d683
--- /dev/null
+++ b/gnu/lib/libg++/libio/strstream.cc
@@ -0,0 +1,133 @@
+/* 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+}
+
+/* Set to use the _IO_str_jump jumptable, for efficiency */
+
+#define SET_STR_JUMPS(STRBUF) \
+ (STRBUF)->_jumps = &_IO_str_jumps,\
+ (STRBUF)->_vtable() = builtinbuf_vtable;
+
+istrstream::istrstream(const char *cp, int n)
+{
+ init(new strstreambuf(cp, n));
+ SET_STR_JUMPS(_strbuf);
+}
+
+ostrstream::ostrstream()
+{
+ init(new strstreambuf());
+ SET_STR_JUMPS(_strbuf);
+}
+
+strstreambase::strstreambase(char *cp, int n, int mode)
+{
+ char *pstart;
+ if (mode == ios::app || mode == ios::ate)
+ pstart = cp + strlen(cp);
+ else
+ pstart = cp;
+ init(new strstreambuf(cp, n, pstart));
+ SET_STR_JUMPS(_strbuf);
+}
+
+char *strstreambuf::str()
+{
+ freeze(1);
+ return base();
+}
+
+_IO_ssize_t strstreambuf::pcount() { return _IO_str_count (this); }
+
+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._len = 0;
+ if (initial_size < 16)
+ initial_size = 16;
+ _s._allocate_buffer = alloc ? alloc : default_alloc;
+ _s._free_buffer = free ? free : default_free;
+ 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, convert_to_seekflags(dir, mode));
+}
+
+int strstreambuf::pbackfail(int c)
+{
+ return _IO_str_pbackfail (this, c);
+}
OpenPOWER on IntegriCloud