summaryrefslogtreecommitdiff
path: root/gnu/lib
diff options
context:
space:
mode:
authorphil <phil@NetBSD.org>1996-03-09 00:00:51 +0000
committerphil <phil@NetBSD.org>1996-03-09 00:00:51 +0000
commit357744cd54478d5d74cb52cd1459eb7c26192abd (patch)
tree32a89fdf6e6be53376907dd269e63ad8a9584a79 /gnu/lib
parent2c11ad408cd834f9e23a25702550639628396204 (diff)
Import of libg++-2.7.1.
Diffstat (limited to 'gnu/lib')
-rw-r--r--gnu/lib/libg++/COPYING354
-rw-r--r--gnu/lib/libg++/include/gen/AVLMap.ccP614
-rw-r--r--gnu/lib/libg++/include/gen/AVLMap.hP141
-rw-r--r--gnu/lib/libg++/include/gen/AVLSet.ccP892
-rw-r--r--gnu/lib/libg++/include/gen/AVLSet.hP152
-rw-r--r--gnu/lib/libg++/include/gen/AVec.ccP397
-rw-r--r--gnu/lib/libg++/include/gen/AVec.hP118
-rw-r--r--gnu/lib/libg++/include/gen/BSTSet.ccP377
-rw-r--r--gnu/lib/libg++/include/gen/BSTSet.hP152
-rw-r--r--gnu/lib/libg++/include/gen/Bag.ccP74
-rw-r--r--gnu/lib/libg++/include/gen/Bag.hP79
-rw-r--r--gnu/lib/libg++/include/gen/CHBag.ccP210
-rw-r--r--gnu/lib/libg++/include/gen/CHBag.hP76
-rw-r--r--gnu/lib/libg++/include/gen/CHMap.ccP168
-rw-r--r--gnu/lib/libg++/include/gen/CHMap.hP104
-rw-r--r--gnu/lib/libg++/include/gen/CHNode.ccP21
-rw-r--r--gnu/lib/libg++/include/gen/CHNode.hP43
-rw-r--r--gnu/lib/libg++/include/gen/CHSet.ccP273
-rw-r--r--gnu/lib/libg++/include/gen/CHSet.hP84
-rw-r--r--gnu/lib/libg++/include/gen/DLDeque.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/DLDeque.hP130
-rw-r--r--gnu/lib/libg++/include/gen/DLList.ccP339
-rw-r--r--gnu/lib/libg++/include/gen/DLList.hP157
-rw-r--r--gnu/lib/libg++/include/gen/Deque.ccP11
-rw-r--r--gnu/lib/libg++/include/gen/Deque.hP57
-rw-r--r--gnu/lib/libg++/include/gen/FPQueue.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/FPQueue.hP112
-rw-r--r--gnu/lib/libg++/include/gen/FPStack.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/FPStack.hP114
-rw-r--r--gnu/lib/libg++/include/gen/FPlex.ccP167
-rw-r--r--gnu/lib/libg++/include/gen/FPlex.hP253
-rw-r--r--gnu/lib/libg++/include/gen/List.ccP972
-rw-r--r--gnu/lib/libg++/include/gen/List.hP279
-rw-r--r--gnu/lib/libg++/include/gen/MPlex.ccP848
-rw-r--r--gnu/lib/libg++/include/gen/MPlex.hP414
-rw-r--r--gnu/lib/libg++/include/gen/Map.ccP59
-rw-r--r--gnu/lib/libg++/include/gen/Map.hP87
-rw-r--r--gnu/lib/libg++/include/gen/OSLBag.ccP196
-rw-r--r--gnu/lib/libg++/include/gen/OSLBag.hP91
-rw-r--r--gnu/lib/libg++/include/gen/OSLSet.ccP321
-rw-r--r--gnu/lib/libg++/include/gen/OSLSet.hP101
-rw-r--r--gnu/lib/libg++/include/gen/OXPBag.ccP221
-rw-r--r--gnu/lib/libg++/include/gen/OXPBag.hP73
-rw-r--r--gnu/lib/libg++/include/gen/OXPSet.ccP280
-rw-r--r--gnu/lib/libg++/include/gen/OXPSet.hP102
-rw-r--r--gnu/lib/libg++/include/gen/PHPQ.ccP339
-rw-r--r--gnu/lib/libg++/include/gen/PHPQ.hP108
-rw-r--r--gnu/lib/libg++/include/gen/PQ.ccP63
-rw-r--r--gnu/lib/libg++/include/gen/PQ.hP78
-rw-r--r--gnu/lib/libg++/include/gen/PSList.hP32
-rw-r--r--gnu/lib/libg++/include/gen/PVec.hP79
-rw-r--r--gnu/lib/libg++/include/gen/Plex.ccP222
-rw-r--r--gnu/lib/libg++/include/gen/Plex.hP494
-rw-r--r--gnu/lib/libg++/include/gen/Queue.ccP14
-rw-r--r--gnu/lib/libg++/include/gen/Queue.hP51
-rw-r--r--gnu/lib/libg++/include/gen/RAVLMap.ccP690
-rw-r--r--gnu/lib/libg++/include/gen/RAVLMap.hP147
-rw-r--r--gnu/lib/libg++/include/gen/RPlex.ccP477
-rw-r--r--gnu/lib/libg++/include/gen/RPlex.hP257
-rw-r--r--gnu/lib/libg++/include/gen/SLBag.ccP105
-rw-r--r--gnu/lib/libg++/include/gen/SLBag.hP96
-rw-r--r--gnu/lib/libg++/include/gen/SLList.ccP292
-rw-r--r--gnu/lib/libg++/include/gen/SLList.hP137
-rw-r--r--gnu/lib/libg++/include/gen/SLQueue.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/SLQueue.hP108
-rw-r--r--gnu/lib/libg++/include/gen/SLSet.ccP77
-rw-r--r--gnu/lib/libg++/include/gen/SLSet.hP87
-rw-r--r--gnu/lib/libg++/include/gen/SLStack.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/SLStack.hP109
-rw-r--r--gnu/lib/libg++/include/gen/Set.ccP117
-rw-r--r--gnu/lib/libg++/include/gen/Set.hP78
-rw-r--r--gnu/lib/libg++/include/gen/SkipBag.ccP322
-rw-r--r--gnu/lib/libg++/include/gen/SkipBag.hP171
-rw-r--r--gnu/lib/libg++/include/gen/SkipMap.ccP307
-rw-r--r--gnu/lib/libg++/include/gen/SkipMap.hP176
-rw-r--r--gnu/lib/libg++/include/gen/SkipSet.ccP395
-rw-r--r--gnu/lib/libg++/include/gen/SkipSet.hP187
-rw-r--r--gnu/lib/libg++/include/gen/SplayBag.ccP445
-rw-r--r--gnu/lib/libg++/include/gen/SplayBag.hP126
-rw-r--r--gnu/lib/libg++/include/gen/SplayMap.ccP401
-rw-r--r--gnu/lib/libg++/include/gen/SplayMap.hP154
-rw-r--r--gnu/lib/libg++/include/gen/SplayNode.ccP21
-rw-r--r--gnu/lib/libg++/include/gen/SplayNode.hP44
-rw-r--r--gnu/lib/libg++/include/gen/SplayPQ.ccP523
-rw-r--r--gnu/lib/libg++/include/gen/SplayPQ.hP123
-rw-r--r--gnu/lib/libg++/include/gen/SplaySet.ccP499
-rw-r--r--gnu/lib/libg++/include/gen/SplaySet.hP145
-rw-r--r--gnu/lib/libg++/include/gen/Stack.ccP11
-rw-r--r--gnu/lib/libg++/include/gen/Stack.hP51
-rw-r--r--gnu/lib/libg++/include/gen/VHBag.ccP264
-rw-r--r--gnu/lib/libg++/include/gen/VHBag.hP84
-rw-r--r--gnu/lib/libg++/include/gen/VHMap.ccP210
-rw-r--r--gnu/lib/libg++/include/gen/VHMap.hP84
-rw-r--r--gnu/lib/libg++/include/gen/VHSet.ccP263
-rw-r--r--gnu/lib/libg++/include/gen/VHSet.hP96
-rw-r--r--gnu/lib/libg++/include/gen/VOHSet.ccP305
-rw-r--r--gnu/lib/libg++/include/gen/VOHSet.hP88
-rw-r--r--gnu/lib/libg++/include/gen/VQueue.ccP83
-rw-r--r--gnu/lib/libg++/include/gen/VQueue.hP130
-rw-r--r--gnu/lib/libg++/include/gen/VStack.ccP66
-rw-r--r--gnu/lib/libg++/include/gen/VStack.hP120
-rw-r--r--gnu/lib/libg++/include/gen/Vec.ccP470
-rw-r--r--gnu/lib/libg++/include/gen/Vec.hP135
-rw-r--r--gnu/lib/libg++/include/gen/XPBag.ccP72
-rw-r--r--gnu/lib/libg++/include/gen/XPBag.hP98
-rw-r--r--gnu/lib/libg++/include/gen/XPDeque.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/XPDeque.hP133
-rw-r--r--gnu/lib/libg++/include/gen/XPPQ.ccP143
-rw-r--r--gnu/lib/libg++/include/gen/XPPQ.hP105
-rw-r--r--gnu/lib/libg++/include/gen/XPQueue.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/XPQueue.hP114
-rw-r--r--gnu/lib/libg++/include/gen/XPSet.ccP63
-rw-r--r--gnu/lib/libg++/include/gen/XPSet.hP89
-rw-r--r--gnu/lib/libg++/include/gen/XPStack.ccP4
-rw-r--r--gnu/lib/libg++/include/gen/XPStack.hP115
-rw-r--r--gnu/lib/libg++/include/gen/XPlex.ccP397
-rw-r--r--gnu/lib/libg++/include/gen/XPlex.hP238
-rw-r--r--gnu/lib/libg++/include/gen/defs.hP57
-rw-r--r--gnu/lib/libg++/include/gen/intSList.hP33
-rw-r--r--gnu/lib/libg++/include/gen/intVec.hP80
-rw-r--r--gnu/lib/libg++/libg++/genclass/Makefile17
-rw-r--r--gnu/lib/libg++/libg++/genclass/genclass.sh452
-rw-r--r--gnu/lib/libg++/libg++/src/ACG.cc292
-rw-r--r--gnu/lib/libg++/libg++/src/ACG.h68
-rw-r--r--gnu/lib/libg++/libg++/src/AllocRing.cc110
-rw-r--r--gnu/lib/libg++/libg++/src/AllocRing.h62
-rw-r--r--gnu/lib/libg++/libg++/src/Binomial.cc34
-rw-r--r--gnu/lib/libg++/libg++/src/Binomial.h55
-rw-r--r--gnu/lib/libg++/libg++/src/BitSet.cc1101
-rw-r--r--gnu/lib/libg++/libg++/src/BitSet.h370
-rw-r--r--gnu/lib/libg++/libg++/src/BitString.cc1608
-rw-r--r--gnu/lib/libg++/libg++/src/BitString.h763
-rw-r--r--gnu/lib/libg++/libg++/src/Complex.h10
-rw-r--r--gnu/lib/libg++/libg++/src/CursesW.cc257
-rw-r--r--gnu/lib/libg++/libg++/src/CursesW.h603
-rw-r--r--gnu/lib/libg++/libg++/src/DLList.cc327
-rw-r--r--gnu/lib/libg++/libg++/src/DLList.h139
-rw-r--r--gnu/lib/libg++/libg++/src/DiscUnif.cc29
-rw-r--r--gnu/lib/libg++/libg++/src/DiscUnif.h72
-rw-r--r--gnu/lib/libg++/libg++/src/Erlang.cc32
-rw-r--r--gnu/lib/libg++/libg++/src/Erlang.h68
-rw-r--r--gnu/lib/libg++/libg++/src/Fix.cc670
-rw-r--r--gnu/lib/libg++/libg++/src/Fix.h523
-rw-r--r--gnu/lib/libg++/libg++/src/Fix16.cc238
-rw-r--r--gnu/lib/libg++/libg++/src/Fix16.h648
-rw-r--r--gnu/lib/libg++/libg++/src/Fix24.cc329
-rw-r--r--gnu/lib/libg++/libg++/src/Fix24.h597
-rw-r--r--gnu/lib/libg++/libg++/src/Geom.cc30
-rw-r--r--gnu/lib/libg++/libg++/src/Geom.h52
-rw-r--r--gnu/lib/libg++/libg++/src/GetOpt.cc253
-rw-r--r--gnu/lib/libg++/libg++/src/GetOpt.h129
-rw-r--r--gnu/lib/libg++/libg++/src/HypGeom.cc30
-rw-r--r--gnu/lib/libg++/libg++/src/HypGeom.h70
-rw-r--r--gnu/lib/libg++/libg++/src/Incremental.h12
-rw-r--r--gnu/lib/libg++/libg++/src/Intdouble.cc142
-rw-r--r--gnu/lib/libg++/libg++/src/Integer.cc2282
-rw-r--r--gnu/lib/libg++/libg++/src/Integer.h1121
-rw-r--r--gnu/lib/libg++/libg++/src/Integer.hP30
-rw-r--r--gnu/lib/libg++/libg++/src/LogNorm.cc36
-rw-r--r--gnu/lib/libg++/libg++/src/LogNorm.h78
-rw-r--r--gnu/lib/libg++/libg++/src/MLCG.cc103
-rw-r--r--gnu/lib/libg++/libg++/src/MLCG.h87
-rw-r--r--gnu/lib/libg++/libg++/src/Makefile25
-rw-r--r--gnu/lib/libg++/libg++/src/NegExp.cc28
-rw-r--r--gnu/lib/libg++/libg++/src/NegExp.h55
-rw-r--r--gnu/lib/libg++/libg++/src/Normal.cc60
-rw-r--r--gnu/lib/libg++/libg++/src/Normal.h66
-rw-r--r--gnu/lib/libg++/libg++/src/Obstack.cc127
-rw-r--r--gnu/lib/libg++/libg++/src/Obstack.h218
-rw-r--r--gnu/lib/libg++/libg++/src/Pix.h5
-rw-r--r--gnu/lib/libg++/libg++/src/Poisson.cc36
-rw-r--r--gnu/lib/libg++/libg++/src/Poisson.h51
-rw-r--r--gnu/lib/libg++/libg++/src/RNG.cc131
-rw-r--r--gnu/lib/libg++/libg++/src/RNG.h58
-rw-r--r--gnu/lib/libg++/libg++/src/Random.cc4
-rw-r--r--gnu/lib/libg++/libg++/src/Random.h54
-rw-r--r--gnu/lib/libg++/libg++/src/Rational.cc416
-rw-r--r--gnu/lib/libg++/libg++/src/Rational.h290
-rw-r--r--gnu/lib/libg++/libg++/src/Regex.cc140
-rw-r--r--gnu/lib/libg++/libg++/src/Regex.h78
-rw-r--r--gnu/lib/libg++/libg++/src/RndInt.cc4
-rw-r--r--gnu/lib/libg++/libg++/src/RndInt.h176
-rw-r--r--gnu/lib/libg++/libg++/src/SLList.cc247
-rw-r--r--gnu/lib/libg++/libg++/src/SLList.h129
-rw-r--r--gnu/lib/libg++/libg++/src/SmplHist.cc112
-rw-r--r--gnu/lib/libg++/libg++/src/SmplHist.h72
-rw-r--r--gnu/lib/libg++/libg++/src/SmplStat.cc160
-rw-r--r--gnu/lib/libg++/libg++/src/SmplStat.h69
-rw-r--r--gnu/lib/libg++/libg++/src/String.cc1307
-rw-r--r--gnu/lib/libg++/libg++/src/String.h1284
-rw-r--r--gnu/lib/libg++/libg++/src/Uniform.cc27
-rw-r--r--gnu/lib/libg++/libg++/src/Uniform.h71
-rw-r--r--gnu/lib/libg++/libg++/src/Weibull.cc33
-rw-r--r--gnu/lib/libg++/libg++/src/Weibull.h74
-rw-r--r--gnu/lib/libg++/libg++/src/bitand.c41
-rw-r--r--gnu/lib/libg++/libg++/src/bitany.c38
-rw-r--r--gnu/lib/libg++/libg++/src/bitblt.c97
-rw-r--r--gnu/lib/libg++/libg++/src/bitclear.c37
-rw-r--r--gnu/lib/libg++/libg++/src/bitcopy.c41
-rw-r--r--gnu/lib/libg++/libg++/src/bitcount.c64
-rw-r--r--gnu/lib/libg++/libg++/src/bitdo1.h32
-rw-r--r--gnu/lib/libg++/libg++/src/bitdo2.h184
-rw-r--r--gnu/lib/libg++/libg++/src/bitinvert.c37
-rw-r--r--gnu/lib/libg++/libg++/src/bitlcomp.c81
-rw-r--r--gnu/lib/libg++/libg++/src/bitprims.h124
-rw-r--r--gnu/lib/libg++/libg++/src/bitset1.c37
-rw-r--r--gnu/lib/libg++/libg++/src/bitxor.c41
-rw-r--r--gnu/lib/libg++/libg++/src/bool.h24
-rw-r--r--gnu/lib/libg++/libg++/src/builtin.cc4
-rw-r--r--gnu/lib/libg++/libg++/src/builtin.h125
-rw-r--r--gnu/lib/libg++/libg++/src/chr.cc37
-rw-r--r--gnu/lib/libg++/libg++/src/compare.cc4
-rw-r--r--gnu/lib/libg++/libg++/src/compare.h91
-rw-r--r--gnu/lib/libg++/libg++/src/error.cc49
-rw-r--r--gnu/lib/libg++/libg++/src/fmtq.cc29
-rw-r--r--gnu/lib/libg++/libg++/src/gcd.cc52
-rw-r--r--gnu/lib/libg++/libg++/src/generic.h54
-rw-r--r--gnu/lib/libg++/libg++/src/getpagesize.h27
-rw-r--r--gnu/lib/libg++/libg++/src/hash.cc56
-rw-r--r--gnu/lib/libg++/libg++/src/ioob.cc32
-rw-r--r--gnu/lib/libg++/libg++/src/lg.cc32
-rw-r--r--gnu/lib/libg++/libg++/src/libc.h1
-rw-r--r--gnu/lib/libg++/libg++/src/minmax.h65
-rw-r--r--gnu/lib/libg++/libg++/src/osfcn.h17
-rw-r--r--gnu/lib/libg++/libg++/src/pow.cc70
-rw-r--r--gnu/lib/libg++/libg++/src/rx.h3732
-rw-r--r--gnu/lib/libg++/libg++/src/shlib_version2
-rw-r--r--gnu/lib/libg++/libg++/src/sqrt.cc43
-rw-r--r--gnu/lib/libg++/libg++/src/std.h35
-rw-r--r--gnu/lib/libg++/libg++/src/str.cc38
-rw-r--r--gnu/lib/libg++/libg++/src/strclass.h5
-rw-r--r--gnu/lib/libg++/libg++/src/swap.h3
-rw-r--r--gnu/lib/libg++/libg++/src/sysent.h2
-rw-r--r--gnu/lib/libg++/libg++/src/timer.c165
-rw-r--r--gnu/lib/libg++/libg++/src/typemacros.h8
-rw-r--r--gnu/lib/libg++/libg++2netbsd643
-rw-r--r--gnu/lib/libg++/libio/Makefile18
-rw-r--r--gnu/lib/libg++/libio/PlotFile.cc157
-rw-r--r--gnu/lib/libg++/libio/PlotFile.h89
-rw-r--r--gnu/lib/libg++/libio/SFile.cc82
-rw-r--r--gnu/lib/libg++/libio/SFile.h55
-rw-r--r--gnu/lib/libg++/libio/_G_config.h78
-rw-r--r--gnu/lib/libg++/libio/builtinbuf.cc78
-rw-r--r--gnu/lib/libg++/libio/builtinbuf.h68
-rw-r--r--gnu/lib/libg++/libio/cleanup.c15
-rw-r--r--gnu/lib/libg++/libio/editbuf.cc717
-rw-r--r--gnu/lib/libg++/libio/editbuf.h185
-rw-r--r--gnu/lib/libg++/libio/filebuf.cc198
-rw-r--r--gnu/lib/libg++/libio/filedoalloc.c104
-rw-r--r--gnu/lib/libg++/libio/fileops.c738
-rw-r--r--gnu/lib/libg++/libio/floatconv.c2349
-rw-r--r--gnu/lib/libg++/libio/floatio.h51
-rw-r--r--gnu/lib/libg++/libio/fstream.cc110
-rw-r--r--gnu/lib/libg++/libio/fstream.h92
-rw-r--r--gnu/lib/libg++/libio/genops.c837
-rw-r--r--gnu/lib/libg++/libio/indstream.cc116
-rw-r--r--gnu/lib/libg++/libio/indstream.h76
-rw-r--r--gnu/lib/libg++/libio/ioassign.cc49
-rw-r--r--gnu/lib/libg++/libio/ioextend.cc132
-rw-r--r--gnu/lib/libg++/libio/iofclose.c47
-rw-r--r--gnu/lib/libg++/libio/iofdopen.c121
-rw-r--r--gnu/lib/libg++/libio/iofflush.c38
-rw-r--r--gnu/lib/libg++/libio/iofgetpos.c46
-rw-r--r--gnu/lib/libg++/libio/iofgets.c40
-rw-r--r--gnu/lib/libg++/libio/iofopen.c49
-rw-r--r--gnu/lib/libg++/libio/iofprintf.c48
-rw-r--r--gnu/lib/libg++/libio/iofputs.c37
-rw-r--r--gnu/lib/libg++/libio/iofread.c38
-rw-r--r--gnu/lib/libg++/libio/iofscanf.c48
-rw-r--r--gnu/lib/libg++/libio/iofsetpos.c43
-rw-r--r--gnu/lib/libg++/libio/ioftell.c45
-rw-r--r--gnu/lib/libg++/libio/iofwrite.c44
-rw-r--r--gnu/lib/libg++/libio/iogetdelim.c99
-rw-r--r--gnu/lib/libg++/libio/iogetline.c74
-rw-r--r--gnu/lib/libg++/libio/iogets.c47
-rw-r--r--gnu/lib/libg++/libio/ioignore.c46
-rw-r--r--gnu/lib/libg++/libio/iolibio.h53
-rw-r--r--gnu/lib/libg++/libio/iomanip.cc90
-rw-r--r--gnu/lib/libg++/libio/iomanip.h165
-rw-r--r--gnu/lib/libg++/libio/iopadn.c65
-rw-r--r--gnu/lib/libg++/libio/ioperror.c22
-rw-r--r--gnu/lib/libg++/libio/iopopen.c222
-rw-r--r--gnu/lib/libg++/libio/ioprims.c72
-rw-r--r--gnu/lib/libg++/libio/ioprintf.c47
-rw-r--r--gnu/lib/libg++/libio/ioputs.c38
-rw-r--r--gnu/lib/libg++/libio/ioscanf.c47
-rw-r--r--gnu/lib/libg++/libio/ioseekoff.c43
-rw-r--r--gnu/lib/libg++/libio/ioseekpos.c39
-rw-r--r--gnu/lib/libg++/libio/iosetbuffer.c36
-rw-r--r--gnu/lib/libg++/libio/iosetvbuf.c77
-rw-r--r--gnu/lib/libg++/libio/iosprintf.c47
-rw-r--r--gnu/lib/libg++/libio/iosscanf.c47
-rw-r--r--gnu/lib/libg++/libio/iostdio.h110
-rw-r--r--gnu/lib/libg++/libio/iostream.cc821
-rw-r--r--gnu/lib/libg++/libio/iostream.h248
-rw-r--r--gnu/lib/libg++/libio/iostreamP.h26
-rw-r--r--gnu/lib/libg++/libio/iostrerror.c12
-rw-r--r--gnu/lib/libg++/libio/ioungetc.c35
-rw-r--r--gnu/lib/libg++/libio/iovfprintf.c881
-rw-r--r--gnu/lib/libg++/libio/iovfscanf.c787
-rw-r--r--gnu/lib/libg++/libio/iovsprintf.c40
-rw-r--r--gnu/lib/libg++/libio/iovsscanf.c37
-rw-r--r--gnu/lib/libg++/libio/isgetline.cc139
-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/istream.h25
-rw-r--r--gnu/lib/libg++/libio/libio.h254
-rw-r--r--gnu/lib/libg++/libio/libioP.h481
-rw-r--r--gnu/lib/libg++/libio/osform.cc54
-rw-r--r--gnu/lib/libg++/libio/ostream.h25
-rw-r--r--gnu/lib/libg++/libio/outfloat.c204
-rw-r--r--gnu/lib/libg++/libio/parsestream.cc317
-rw-r--r--gnu/lib/libg++/libio/parsestream.h156
-rw-r--r--gnu/lib/libg++/libio/pfstream.cc92
-rw-r--r--gnu/lib/libg++/libio/pfstream.h59
-rw-r--r--gnu/lib/libg++/libio/procbuf.cc55
-rw-r--r--gnu/lib/libg++/libio/procbuf.h50
-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/shlib_version2
-rw-r--r--gnu/lib/libg++/libio/stdfiles.c44
-rw-r--r--gnu/lib/libg++/libio/stdiostream.cc159
-rw-r--r--gnu/lib/libg++/libio/stdiostream.h79
-rw-r--r--gnu/lib/libg++/libio/stdstrbufs.cc115
-rw-r--r--gnu/lib/libg++/libio/stdstreams.cc149
-rw-r--r--gnu/lib/libg++/libio/stream.cc144
-rw-r--r--gnu/lib/libg++/libio/stream.h57
-rw-r--r--gnu/lib/libg++/libio/streambuf.cc343
-rw-r--r--gnu/lib/libg++/libio/streambuf.h473
-rw-r--r--gnu/lib/libg++/libio/strfile.h46
-rw-r--r--gnu/lib/libg++/libio/strops.c285
-rw-r--r--gnu/lib/libg++/libio/strstream.cc168
-rw-r--r--gnu/lib/libg++/libio/strstream.h123
-rw-r--r--gnu/lib/libg++/libiostream/Makefile22
-rw-r--r--gnu/lib/libg++/libiostream/shlib_version2
-rw-r--r--gnu/lib/libg++/libstdc++/Makefile134
-rw-r--r--gnu/lib/libg++/libstdc++/algorithm7
-rw-r--r--gnu/lib/libg++/libstdc++/cassert6
-rw-r--r--gnu/lib/libg++/libstdc++/cctype6
-rw-r--r--gnu/lib/libg++/libstdc++/cerrno6
-rw-r--r--gnu/lib/libg++/libstdc++/cfloat6
-rw-r--r--gnu/lib/libg++/libstdc++/cinst.cc151
-rw-r--r--gnu/lib/libg++/libstdc++/ciso6466
-rw-r--r--gnu/lib/libg++/libstdc++/climits6
-rw-r--r--gnu/lib/libg++/libstdc++/clocale6
-rw-r--r--gnu/lib/libg++/libstdc++/cmath6
-rw-r--r--gnu/lib/libg++/libstdc++/cmathi.cc7
-rw-r--r--gnu/lib/libg++/libstdc++/complex6
-rw-r--r--gnu/lib/libg++/libstdc++/complex.h6
-rw-r--r--gnu/lib/libg++/libstdc++/csetjmp6
-rw-r--r--gnu/lib/libg++/libstdc++/csignal6
-rw-r--r--gnu/lib/libg++/libstdc++/cstdarg6
-rw-r--r--gnu/lib/libg++/libstdc++/cstddef6
-rw-r--r--gnu/lib/libg++/libstdc++/cstdio6
-rw-r--r--gnu/lib/libg++/libstdc++/cstdlib6
-rw-r--r--gnu/lib/libg++/libstdc++/cstdlibi.cc7
-rw-r--r--gnu/lib/libg++/libstdc++/cstring6
-rw-r--r--gnu/lib/libg++/libstdc++/cstringi.cc7
-rw-r--r--gnu/lib/libg++/libstdc++/ctime6
-rw-r--r--gnu/lib/libg++/libstdc++/cwchar6
-rw-r--r--gnu/lib/libg++/libstdc++/cwctype6
-rw-r--r--gnu/lib/libg++/libstdc++/deque7
-rw-r--r--gnu/lib/libg++/libstdc++/exception6
-rw-r--r--gnu/lib/libg++/libstdc++/exceptioni.cc78
-rw-r--r--gnu/lib/libg++/libstdc++/functional7
-rw-r--r--gnu/lib/libg++/libstdc++/iterator7
-rw-r--r--gnu/lib/libg++/libstdc++/list7
-rw-r--r--gnu/lib/libg++/libstdc++/map7
-rw-r--r--gnu/lib/libg++/libstdc++/memory7
-rw-r--r--gnu/lib/libg++/libstdc++/new6
-rw-r--r--gnu/lib/libg++/libstdc++/new.h7
-rw-r--r--gnu/lib/libg++/libstdc++/newi.cc7
-rw-r--r--gnu/lib/libg++/libstdc++/numeric7
-rw-r--r--gnu/lib/libg++/libstdc++/queue7
-rw-r--r--gnu/lib/libg++/libstdc++/set7
-rw-r--r--gnu/lib/libg++/libstdc++/shlib_version2
-rw-r--r--gnu/lib/libg++/libstdc++/sinst.cc147
-rw-r--r--gnu/lib/libg++/libstdc++/stack7
-rw-r--r--gnu/lib/libg++/libstdc++/std/bastring.cc483
-rw-r--r--gnu/lib/libg++/libstdc++/std/bastring.h574
-rw-r--r--gnu/lib/libg++/libstdc++/std/cassert.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cctype.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cerrno.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cfloat.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cinst.h112
-rw-r--r--gnu/lib/libg++/libstdc++/std/ciso646.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/climits.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/clocale.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cmath.h76
-rw-r--r--gnu/lib/libg++/libstdc++/std/complex.h18
-rw-r--r--gnu/lib/libg++/libstdc++/std/complext.cc273
-rw-r--r--gnu/lib/libg++/libstdc++/std/complext.h317
-rw-r--r--gnu/lib/libg++/libstdc++/std/csetjmp.h8
-rw-r--r--gnu/lib/libg++/libstdc++/std/csignal.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cstdarg.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cstddef.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cstdio.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cstdlib.h23
-rw-r--r--gnu/lib/libg++/libstdc++/std/cstring.h71
-rw-r--r--gnu/lib/libg++/libstdc++/std/ctime.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cwchar.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/cwctype.h7
-rw-r--r--gnu/lib/libg++/libstdc++/std/dcomplex.h89
-rw-r--r--gnu/lib/libg++/libstdc++/std/exception.h39
-rw-r--r--gnu/lib/libg++/libstdc++/std/fcomplex.h85
-rw-r--r--gnu/lib/libg++/libstdc++/std/ldcomplex.h93
-rw-r--r--gnu/lib/libg++/libstdc++/std/new.h34
-rw-r--r--gnu/lib/libg++/libstdc++/std/sinst.h73
-rw-r--r--gnu/lib/libg++/libstdc++/std/stddef.h25
-rw-r--r--gnu/lib/libg++/libstdc++/std/stdexcept.h126
-rw-r--r--gnu/lib/libg++/libstdc++/std/straits.h161
-rw-r--r--gnu/lib/libg++/libstdc++/std/string.h13
-rw-r--r--gnu/lib/libg++/libstdc++/std/typeinfo.h245
-rw-r--r--gnu/lib/libg++/libstdc++/stddef6
-rw-r--r--gnu/lib/libg++/libstdc++/stddefi.cc7
-rw-r--r--gnu/lib/libg++/libstdc++/stdexcept6
-rw-r--r--gnu/lib/libg++/libstdc++/stdexcepti.cc8
-rw-r--r--gnu/lib/libg++/libstdc++/stl.h15
-rw-r--r--gnu/lib/libg++/libstdc++/stl/algo.h2386
-rw-r--r--gnu/lib/libg++/libstdc++/stl/algobase.h232
-rw-r--r--gnu/lib/libg++/libstdc++/stl/bvector.h421
-rw-r--r--gnu/lib/libg++/libstdc++/stl/defalloc.h176
-rw-r--r--gnu/lib/libg++/libstdc++/stl/deque.h681
-rw-r--r--gnu/lib/libg++/libstdc++/stl/faralloc.h120
-rw-r--r--gnu/lib/libg++/libstdc++/stl/fdeque.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/flist.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/fmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/fmultmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/fmultset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/fset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/function.h282
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hdeque.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/heap.h193
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hlist.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hmultmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hmultset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hugalloc.h38
-rw-r--r--gnu/lib/libg++/libstdc++/stl/hvector.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/iterator.h395
-rw-r--r--gnu/lib/libg++/libstdc++/stl/lbvector.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/ldeque.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/list.h531
-rw-r--r--gnu/lib/libg++/libstdc++/stl/llist.h39
-rw-r--r--gnu/lib/libg++/libstdc++/stl/lmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/lmultmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/lmultset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/lngalloc.h54
-rw-r--r--gnu/lib/libg++/libstdc++/stl/lset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/map.h150
-rw-r--r--gnu/lib/libg++/libstdc++/stl/multimap.h142
-rw-r--r--gnu/lib/libg++/libstdc++/stl/multiset.h129
-rw-r--r--gnu/lib/libg++/libstdc++/stl/neralloc.h38
-rw-r--r--gnu/lib/libg++/libstdc++/stl/nmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/nmultmap.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/nmultset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/nset.h44
-rw-r--r--gnu/lib/libg++/libstdc++/stl/pair.h46
-rw-r--r--gnu/lib/libg++/libstdc++/stl/projectn.h33
-rw-r--r--gnu/lib/libg++/libstdc++/stl/random.cc60
-rw-r--r--gnu/lib/libg++/libstdc++/stl/set.h132
-rw-r--r--gnu/lib/libg++/libstdc++/stl/stack.h120
-rw-r--r--gnu/lib/libg++/libstdc++/stl/tempbuf.cc18
-rw-r--r--gnu/lib/libg++/libstdc++/stl/tempbuf.h55
-rw-r--r--gnu/lib/libg++/libstdc++/stl/tree.cc3
-rw-r--r--gnu/lib/libg++/libstdc++/stl/tree.h1246
-rw-r--r--gnu/lib/libg++/libstdc++/stl/vector.h355
-rw-r--r--gnu/lib/libg++/libstdc++/string6
-rw-r--r--gnu/lib/libg++/libstdc++/typeinfo6
-rw-r--r--gnu/lib/libg++/libstdc++/typeinfoi.cc129
-rw-r--r--gnu/lib/libg++/libstdc++/utility8
-rw-r--r--gnu/lib/libg++/libstdc++/vector7
474 files changed, 76736 insertions, 132 deletions
diff --git a/gnu/lib/libg++/COPYING b/gnu/lib/libg++/COPYING
index 9a170375811..a43ea2126fb 100644
--- a/gnu/lib/libg++/COPYING
+++ b/gnu/lib/libg++/COPYING
@@ -1,38 +1,40 @@
-
GNU GENERAL PUBLIC LICENSE
- Version 1, February 1989
+ Version 2, June 1991
- Copyright (C) 1989 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
- The license agreements of most software companies try to keep users
-at the mercy of those companies. By contrast, our General Public
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. The
-General Public License applies to the Free Software Foundation's
-software and to any other program whose authors commit to using it.
-You can use it for your programs, too.
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
When we speak of free software, we are referring to freedom, not
-price. Specifically, the General Public License is designed to make
-sure that you have the freedom to give away or sell copies of free
-software, that you receive source code or can get it if you want it,
-that you can change the software or use pieces of it in new free
-programs; and that you know you can do these things.
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
- For example, if you distribute copies of a such a program, whether
+ For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
-source code. And you must tell them their rights.
+source code. And you must show them these terms so they know their
+rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
@@ -45,120 +47,207 @@ want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- 0. This License Agreement applies to any program or other work which
-contains a notice placed by the copyright holder saying it may be
-distributed under the terms of this General Public License. The
-"Program", below, refers to any such program or work, and a "work based
-on the Program" means either the Program or any work containing the
-Program or a portion of it, either verbatim or with modifications. Each
-licensee is addressed as "you".
-
- 1. You may copy and distribute verbatim copies of the Program's source
-code as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this
-General Public License and to the absence of any warranty; and give any
-other recipients of the Program a copy of this General Public License
-along with the Program. You may charge a fee for the physical act of
-transferring a copy.
-
- 2. You may modify your copy or copies of the Program or any portion of
-it, and copy and distribute such modifications under the terms of Paragraph
-1 above, provided that you also do the following:
-
- a) cause the modified files to carry prominent notices stating that
- you changed the files and the date of any change; and
-
- b) cause the whole of any work that you distribute or publish, that
- in whole or in part contains the Program or any part thereof, either
- with or without modifications, to be licensed at no charge to all
- third parties under the terms of this General Public License (except
- that you may choose to grant warranty protection to some or all
- third parties, at your option).
-
- c) If the modified program normally reads commands interactively when
- run, you must cause it, when started running for such interactive use
- in the simplest and most usual way, to print or display an
- announcement including an appropriate copyright notice and a notice
- that there is no warranty (or else, saying that you provide a
- warranty) and that users may redistribute the program under these
- conditions, and telling the user how to view a copy of this General
- Public License.
-
- d) You may charge a fee for the physical act of transferring a
- copy, and you may at your option offer warranty protection in
- exchange for a fee.
-
-Mere aggregation of another independent work with the Program (or its
-derivative) on a volume of a storage or distribution medium does not bring
-the other work under the scope of these terms.
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
- 3. You may copy and distribute the Program (or a portion or derivative of
-it, under Paragraph 2) in object code or executable form under the terms of
-Paragraphs 1 and 2 above provided that you also do one of the following:
-
- a) accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of
- Paragraphs 1 and 2 above; or,
-
- b) accompany it with a written offer, valid for at least three
- years, to give any third party free (except for a nominal charge
- for the cost of distribution) a complete machine-readable copy of the
- corresponding source code, to be distributed under the terms of
- Paragraphs 1 and 2 above; or,
-
- c) accompany it with the information you received as to where the
- corresponding source code may be obtained. (This alternative is
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
- received the program in object code or executable form alone.)
-
-Source code for a work means the preferred form of the work for making
-modifications to it. For an executable file, complete source code means
-all the source code for all modules it contains; but, as a special
-exception, it need not include source code for modules which are standard
-libraries that accompany the operating system on which the executable
-file runs, or for standard header files or definitions files that
-accompany that operating system.
-
- 4. You may not copy, modify, sublicense, distribute or transfer the
-Program except as expressly provided under this General Public License.
-Any attempt otherwise to copy, modify, sublicense, distribute or transfer
-the Program is void, and will automatically terminate your rights to use
-the Program under this License. However, parties who have received
-copies, or rights to use copies, from you under this General Public
-License will not have their licenses terminated so long as such parties
-remain in full compliance.
-
- 5. By copying, distributing or modifying the Program (or any work based
-on the Program) you indicate your acceptance of this license to do so,
-and all its terms and conditions.
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the original
-licensor to copy, distribute or modify the Program subject to these
-terms and conditions. You may not impose any further restrictions on the
-recipients' exercise of the rights granted herein.
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
- 7. The Free Software Foundation may publish revised and/or new versions
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
-specifies a version number of the license which applies to it and "any
+specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
-the license, you may choose any version ever published by the Free Software
+this License, you may choose any version ever published by the Free Software
Foundation.
- 8. If you wish to incorporate parts of the Program into other free
+ 10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
@@ -168,7 +257,7 @@ of promoting the sharing and reuse of software generally.
NO WARRANTY
- 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
@@ -178,7 +267,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
- 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
@@ -193,22 +282,21 @@ POSSIBILITY OF SUCH DAMAGES.
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
-possible use to humanity, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
- To do so, attach the following notices to the program. It is safest to
-attach them to the start of each source file to most effectively convey
-the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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 1, or (at your option)
- any later version.
+ 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
@@ -224,26 +312,28 @@ Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
-The hypothetical commands `show w' and `show c' should show the
-appropriate parts of the General Public License. Of course, the
-commands you use may be called something other than `show w' and `show
-c'; they could even be mouse-clicks or menu items--whatever suits your
-program.
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here a sample; alter the names:
+necessary. Here is a sample; alter the names:
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- program `Gnomovision' (a program to direct compilers to make passes
- at assemblers) written by James Hacker.
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
-That's all there is to it!
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gnu/lib/libg++/include/gen/AVLMap.ccP b/gnu/lib/libg++/include/gen/AVLMap.ccP
new file mode 100644
index 00000000000..0e2c63542ad
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/AVLMap.ccP
@@ -0,0 +1,614 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.<C>.AVLMap.h"
+
+
+/*
+ constants & inlines for maintaining balance & thread status in tree nodes
+*/
+
+#define AVLBALANCEMASK 3
+#define AVLBALANCED 0
+#define AVLLEFTHEAVY 1
+#define AVLRIGHTHEAVY 2
+
+#define LTHREADBIT 4
+#define RTHREADBIT 8
+
+
+static inline int bf(<T><C>AVLNode* t)
+{
+ return t->stat & AVLBALANCEMASK;
+}
+
+static inline void set_bf(<T><C>AVLNode* t, int b)
+{
+ t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK);
+}
+
+
+static inline int rthread(<T><C>AVLNode* t)
+{
+ return t->stat & RTHREADBIT;
+}
+
+static inline void set_rthread(<T><C>AVLNode* t, int b)
+{
+ if (b)
+ t->stat |= RTHREADBIT;
+ else
+ t->stat &= ~RTHREADBIT;
+}
+
+static inline int lthread(<T><C>AVLNode* t)
+{
+ return t->stat & LTHREADBIT;
+}
+
+static inline void set_lthread(<T><C>AVLNode* t, int b)
+{
+ if (b)
+ t->stat |= LTHREADBIT;
+ else
+ t->stat &= ~LTHREADBIT;
+}
+
+/*
+ traversal primitives
+*/
+
+
+<T><C>AVLNode* <T><C>AVLMap::leftmost()
+{
+ <T><C>AVLNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T><C>AVLNode* <T><C>AVLMap::rightmost()
+{
+ <T><C>AVLNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T><C>AVLNode* <T><C>AVLMap::succ(<T><C>AVLNode* t)
+{
+ <T><C>AVLNode* r = t->rt;
+ if (!rthread(t)) while (!lthread(r)) r = r->lt;
+ return r;
+}
+
+<T><C>AVLNode* <T><C>AVLMap::pred(<T><C>AVLNode* t)
+{
+ <T><C>AVLNode* l = t->lt;
+ if (!lthread(t)) while (!rthread(l)) l = l->rt;
+ return l;
+}
+
+
+Pix <T><C>AVLMap::seek(<T&> key)
+{
+ <T><C>AVLNode* t = root;
+ if (t == 0)
+ return 0;
+ for (;;)
+ {
+ int cmp = <T>CMP(key, t->item);
+ if (cmp == 0)
+ return Pix(t);
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ return 0;
+ else
+ t = t->lt;
+ }
+ else if (rthread(t))
+ return 0;
+ else
+ t = t->rt;
+ }
+}
+
+
+/*
+ The combination of threads and AVL bits make adding & deleting
+ interesting, but very awkward.
+
+ We use the following statics to avoid passing them around recursively
+*/
+
+static int _need_rebalancing; // to send back balance info from rec. calls
+static <T>* _target_item; // add/del_item target
+static <T><C>AVLNode* _found_node; // returned added/deleted node
+static int _already_found; // for deletion subcases
+
+
+void <T><C>AVLMap:: _add(<T><C>AVLNode*& t)
+{
+ int cmp = <T>CMP(*_target_item, t->item);
+ if (cmp == 0)
+ {
+ _found_node = t;
+ return;
+ }
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ {
+ ++count;
+ _found_node = new <T><C>AVLNode(*_target_item, def);
+ set_lthread(_found_node, 1);
+ set_rthread(_found_node, 1);
+ _found_node->lt = t->lt;
+ _found_node->rt = t;
+ t->lt = _found_node;
+ set_lthread(t, 0);
+ _need_rebalancing = 1;
+ }
+ else
+ _add(t->lt);
+ if (_need_rebalancing)
+ {
+ switch(bf(t))
+ {
+ case AVLRIGHTHEAVY:
+ set_bf(t, AVLBALANCED);
+ _need_rebalancing = 0;
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLLEFTHEAVY);
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T><C>AVLNode* l = t->lt;
+ if (bf(l) == AVLLEFTHEAVY)
+ {
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ _need_rebalancing = 0;
+ }
+ else
+ {
+ <T><C>AVLNode* r = l->rt;
+ set_rthread(l, lthread(r));
+ if (lthread(r))
+ l->rt = r;
+ else
+ l->rt = r->lt;
+ r->lt = l;
+ set_lthread(r, 0);
+ set_lthread(t, rthread(r));
+ if (rthread(r))
+ t->lt = r;
+ else
+ t->lt = r->rt;
+ r->rt = t;
+ set_rthread(r, 0);
+ if (bf(r) == AVLLEFTHEAVY)
+ set_bf(t, AVLRIGHTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(r) == AVLRIGHTHEAVY)
+ set_bf(l, AVLLEFTHEAVY);
+ else
+ set_bf(l, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ _need_rebalancing = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (rthread(t))
+ {
+ ++count;
+ _found_node = new <T><C>AVLNode(*_target_item, def);
+ set_rthread(t, 0);
+ set_lthread(_found_node, 1);
+ set_rthread(_found_node, 1);
+ _found_node->lt = t;
+ _found_node->rt = t->rt;
+ t->rt = _found_node;
+ _need_rebalancing = 1;
+ }
+ else
+ _add(t->rt);
+ if (_need_rebalancing)
+ {
+ switch(bf(t))
+ {
+ case AVLLEFTHEAVY:
+ set_bf(t, AVLBALANCED);
+ _need_rebalancing = 0;
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLRIGHTHEAVY);
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T><C>AVLNode* r = t->rt;
+ if (bf(r) == AVLRIGHTHEAVY)
+ {
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ _need_rebalancing = 0;
+ }
+ else
+ {
+ <T><C>AVLNode* l = r->lt;
+ set_lthread(r, rthread(l));
+ if (rthread(l))
+ r->lt = l;
+ else
+ r->lt = l->rt;
+ l->rt = r;
+ set_rthread(l, 0);
+ set_rthread(t, lthread(l));
+ if (lthread(l))
+ t->rt = l;
+ else
+ t->rt = l->lt;
+ l->lt = t;
+ set_lthread(l, 0);
+ if (bf(l) == AVLRIGHTHEAVY)
+ set_bf(t, AVLLEFTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(l) == AVLLEFTHEAVY)
+ set_bf(r, AVLRIGHTHEAVY);
+ else
+ set_bf(r, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ _need_rebalancing = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+<C>& <T><C>AVLMap::operator [] (<T&> item)
+{
+ if (root == 0)
+ {
+ ++count;
+ root = new <T><C>AVLNode(item, def);
+ set_rthread(root, 1);
+ set_lthread(root, 1);
+ return root->cont;
+ }
+ else
+ {
+ _target_item = &item;
+ _need_rebalancing = 0;
+ _add(root);
+ return _found_node->cont;
+ }
+}
+
+
+void <T><C>AVLMap::_del(<T><C>AVLNode* par, <T><C>AVLNode*& t)
+{
+ int comp;
+ if (_already_found)
+ {
+ if (rthread(t))
+ comp = 0;
+ else
+ comp = 1;
+ }
+ else
+ comp = <T>CMP(*_target_item, t->item);
+ if (comp == 0)
+ {
+ if (lthread(t) && rthread(t))
+ {
+ _found_node = t;
+ if (t == par->lt)
+ {
+ set_lthread(par, 1);
+ par->lt = t->lt;
+ }
+ else
+ {
+ set_rthread(par, 1);
+ par->rt = t->rt;
+ }
+ _need_rebalancing = 1;
+ return;
+ }
+ else if (lthread(t))
+ {
+ _found_node = t;
+ <T><C>AVLNode* s = succ(t);
+ if (s != 0 && lthread(s))
+ s->lt = t->lt;
+ t = t->rt;
+ _need_rebalancing = 1;
+ return;
+ }
+ else if (rthread(t))
+ {
+ _found_node = t;
+ <T><C>AVLNode* p = pred(t);
+ if (p != 0 && rthread(p))
+ p->rt = t->rt;
+ t = t->lt;
+ _need_rebalancing = 1;
+ return;
+ }
+ else // replace item & find someone deletable
+ {
+ <T><C>AVLNode* p = pred(t);
+ t->item = p->item;
+ t->cont = p->cont;
+ _already_found = 1;
+ comp = -1; // fall through below to left
+ }
+ }
+
+ if (comp < 0)
+ {
+ if (lthread(t))
+ return;
+ _del(t, t->lt);
+ if (!_need_rebalancing)
+ return;
+ switch (bf(t))
+ {
+ case AVLLEFTHEAVY:
+ set_bf(t, AVLBALANCED);
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLRIGHTHEAVY);
+ _need_rebalancing = 0;
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T><C>AVLNode* r = t->rt;
+ switch (bf(r))
+ {
+ case AVLBALANCED:
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLRIGHTHEAVY);
+ set_bf(r, AVLLEFTHEAVY);
+ _need_rebalancing = 0;
+ t = r;
+ return;
+ case AVLRIGHTHEAVY:
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T><C>AVLNode* l = r->lt;
+ set_lthread(r, rthread(l));
+ if (rthread(l))
+ r->lt = l;
+ else
+ r->lt = l->rt;
+ l->rt = r;
+ set_rthread(l, 0);
+ set_rthread(t, lthread(l));
+ if (lthread(l))
+ t->rt = l;
+ else
+ t->rt = l->lt;
+ l->lt = t;
+ set_lthread(l, 0);
+ if (bf(l) == AVLRIGHTHEAVY)
+ set_bf(t, AVLLEFTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(l) == AVLLEFTHEAVY)
+ set_bf(r, AVLRIGHTHEAVY);
+ else
+ set_bf(r, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (rthread(t))
+ return;
+ _del(t, t->rt);
+ if (!_need_rebalancing)
+ return;
+ switch (bf(t))
+ {
+ case AVLRIGHTHEAVY:
+ set_bf(t, AVLBALANCED);
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLLEFTHEAVY);
+ _need_rebalancing = 0;
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T><C>AVLNode* l = t->lt;
+ switch (bf(l))
+ {
+ case AVLBALANCED:
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLLEFTHEAVY);
+ set_bf(l, AVLRIGHTHEAVY);
+ _need_rebalancing = 0;
+ t = l;
+ return;
+ case AVLLEFTHEAVY:
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T><C>AVLNode* r = l->rt;
+ set_rthread(l, lthread(r));
+ if (lthread(r))
+ l->rt = r;
+ else
+ l->rt = r->lt;
+ r->lt = l;
+ set_lthread(r, 0);
+ set_lthread(t, rthread(r));
+ if (rthread(r))
+ t->lt = r;
+ else
+ t->lt = r->rt;
+ r->rt = t;
+ set_rthread(r, 0);
+ if (bf(r) == AVLLEFTHEAVY)
+ set_bf(t, AVLRIGHTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(r) == AVLRIGHTHEAVY)
+ set_bf(l, AVLLEFTHEAVY);
+ else
+ set_bf(l, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+void <T><C>AVLMap::del(<T&> item)
+{
+ if (root == 0) return;
+ _need_rebalancing = 0;
+ _already_found = 0;
+ _found_node = 0;
+ _target_item = &item;
+ _del(root, root);
+ if (_found_node)
+ {
+ delete(_found_node);
+ if (--count == 0)
+ root = 0;
+ }
+}
+
+void <T><C>AVLMap::_kill(<T><C>AVLNode* t)
+{
+ if (t != 0)
+ {
+ if (!lthread(t)) _kill(t->lt);
+ if (!rthread(t)) _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T><C>AVLMap::<T><C>AVLMap(<T><C>AVLMap& b) :<T><C>Map(b.def)
+{
+ root = 0;
+ count = 0;
+ for (Pix i = b.first(); i != 0; b.next(i))
+ (*this)[b.key(i)] = b.contents(i);
+}
+
+
+int <T><C>AVLMap::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T><C>AVLNode* trail = leftmost();
+ <T><C>AVLNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/AVLMap.hP b/gnu/lib/libg++/include/gen/AVLMap.hP
new file mode 100644
index 00000000000..a5c0884be0d
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/AVLMap.hP
@@ -0,0 +1,141 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T><C>AVLMap_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>AVLMap_h 1
+
+#include "<T>.<C>.Map.h"
+
+struct <T><C>AVLNode
+{
+ <T><C>AVLNode* lt;
+ <T><C>AVLNode* rt;
+ <T> item;
+ <C> cont;
+ char stat;
+ <T><C>AVLNode(<T&> h, <C&> c,
+ <T><C>AVLNode* l=0, <T><C>AVLNode* r=0);
+ ~<T><C>AVLNode();
+};
+
+inline <T><C>AVLNode::<T><C>AVLNode(<T&> h, <C&> c,
+ <T><C>AVLNode* l, <T><C>AVLNode* r)
+ :lt(l), rt(r), item(h), cont(c), stat(0) {}
+
+inline <T><C>AVLNode::~<T><C>AVLNode() {}
+
+typedef <T><C>AVLNode* <T><C>AVLNodePtr;
+
+
+class <T><C>AVLMap : public <T><C>Map
+{
+protected:
+ <T><C>AVLNode* root;
+
+ <T><C>AVLNode* leftmost();
+ <T><C>AVLNode* rightmost();
+ <T><C>AVLNode* pred(<T><C>AVLNode* t);
+ <T><C>AVLNode* succ(<T><C>AVLNode* t);
+ void _kill(<T><C>AVLNode* t);
+ void _add(<T><C>AVLNode*& t);
+ void _del(<T><C>AVLNode* p, <T><C>AVLNode*& t);
+
+public:
+ <T><C>AVLMap(<C&> dflt);
+ <T><C>AVLMap(<T><C>AVLMap& a);
+ inline ~<T><C>AVLMap();
+
+ <C>& operator [] (<T&> key);
+
+ void del(<T&> key);
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& key(Pix i);
+ inline <C>& contents(Pix i);
+
+ Pix seek(<T&> key);
+ inline int contains(<T&> key);
+
+ inline void clear();
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+inline <T><C>AVLMap::~<T><C>AVLMap()
+{
+ _kill(root);
+}
+
+inline <T><C>AVLMap::<T><C>AVLMap(<C&> dflt) :<T><C>Map(dflt)
+{
+ root = 0;
+}
+
+inline Pix <T><C>AVLMap::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T><C>AVLMap::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T><C>AVLMap::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T><C>AVLNode*)i));
+}
+
+inline void <T><C>AVLMap::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T><C>AVLNode*)i));
+}
+
+inline <T>& <T><C>AVLMap::key(Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>AVLNode*)i)->item;
+}
+
+inline <C>& <T><C>AVLMap::contents(Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>AVLNode*)i)->cont;
+}
+
+inline void <T><C>AVLMap::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T><C>AVLMap::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/AVLSet.ccP b/gnu/lib/libg++/include/gen/AVLSet.ccP
new file mode 100644
index 00000000000..98c07d18914
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/AVLSet.ccP
@@ -0,0 +1,892 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.AVLSet.h"
+#include <stdlib.h>
+
+
+/*
+ constants & inlines for maintaining balance & thread status in tree nodes
+*/
+
+#define AVLBALANCEMASK 3
+#define AVLBALANCED 0
+#define AVLLEFTHEAVY 1
+#define AVLRIGHTHEAVY 2
+
+#define LTHREADBIT 4
+#define RTHREADBIT 8
+
+
+static inline int bf(<T>AVLNode* t)
+{
+ return t->stat & AVLBALANCEMASK;
+}
+
+static inline void set_bf(<T>AVLNode* t, int b)
+{
+ t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK);
+}
+
+
+static inline int rthread(<T>AVLNode* t)
+{
+ return t->stat & RTHREADBIT;
+}
+
+static inline void set_rthread(<T>AVLNode* t, int b)
+{
+ if (b)
+ t->stat |= RTHREADBIT;
+ else
+ t->stat &= ~RTHREADBIT;
+}
+
+static inline int lthread(<T>AVLNode* t)
+{
+ return t->stat & LTHREADBIT;
+}
+
+static inline void set_lthread(<T>AVLNode* t, int b)
+{
+ if (b)
+ t->stat |= LTHREADBIT;
+ else
+ t->stat &= ~LTHREADBIT;
+}
+
+/*
+ traversal primitives
+*/
+
+
+<T>AVLNode* <T>AVLSet::leftmost()
+{
+ <T>AVLNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T>AVLNode* <T>AVLSet::rightmost()
+{
+ <T>AVLNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T>AVLNode* <T>AVLSet::succ(<T>AVLNode* t)
+{
+ <T>AVLNode* r = t->rt;
+ if (!rthread(t)) while (!lthread(r)) r = r->lt;
+ return r;
+}
+
+<T>AVLNode* <T>AVLSet::pred(<T>AVLNode* t)
+{
+ <T>AVLNode* l = t->lt;
+ if (!lthread(t)) while (!rthread(l)) l = l->rt;
+ return l;
+}
+
+
+Pix <T>AVLSet::seek(<T&> key)
+{
+ <T>AVLNode* t = root;
+ if (t == 0)
+ return 0;
+ for (;;)
+ {
+ int cmp = <T>CMP(key, t->item);
+ if (cmp == 0)
+ return Pix(t);
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ return 0;
+ else
+ t = t->lt;
+ }
+ else if (rthread(t))
+ return 0;
+ else
+ t = t->rt;
+ }
+}
+
+
+/*
+ The combination of threads and AVL bits make adding & deleting
+ interesting, but very awkward.
+
+ We use the following statics to avoid passing them around recursively
+*/
+
+static int _need_rebalancing; // to send back balance info from rec. calls
+static <T>* _target_item; // add/del_item target
+static <T>AVLNode* _found_node; // returned added/deleted node
+static int _already_found; // for deletion subcases
+
+static <T>AVLNode** _hold_nodes; // used for rebuilding trees
+static int _max_hold_index; // # elements-1 in _hold_nodes
+
+
+void <T>AVLSet:: _add(<T>AVLNode*& t)
+{
+ int cmp = <T>CMP(*_target_item, t->item);
+ if (cmp == 0)
+ {
+ _found_node = t;
+ return;
+ }
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ {
+ ++count;
+ _found_node = new <T>AVLNode(*_target_item);
+ set_lthread(_found_node, 1);
+ set_rthread(_found_node, 1);
+ _found_node->lt = t->lt;
+ _found_node->rt = t;
+ t->lt = _found_node;
+ set_lthread(t, 0);
+ _need_rebalancing = 1;
+ }
+ else
+ _add(t->lt);
+ if (_need_rebalancing)
+ {
+ switch(bf(t))
+ {
+ case AVLRIGHTHEAVY:
+ set_bf(t, AVLBALANCED);
+ _need_rebalancing = 0;
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLLEFTHEAVY);
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T>AVLNode* l = t->lt;
+ if (bf(l) == AVLLEFTHEAVY)
+ {
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ _need_rebalancing = 0;
+ }
+ else
+ {
+ <T>AVLNode* r = l->rt;
+ set_rthread(l, lthread(r));
+ if (lthread(r))
+ l->rt = r;
+ else
+ l->rt = r->lt;
+ r->lt = l;
+ set_lthread(r, 0);
+ set_lthread(t, rthread(r));
+ if (rthread(r))
+ t->lt = r;
+ else
+ t->lt = r->rt;
+ r->rt = t;
+ set_rthread(r, 0);
+ if (bf(r) == AVLLEFTHEAVY)
+ set_bf(t, AVLRIGHTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(r) == AVLRIGHTHEAVY)
+ set_bf(l, AVLLEFTHEAVY);
+ else
+ set_bf(l, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ _need_rebalancing = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (rthread(t))
+ {
+ ++count;
+ _found_node = new <T>AVLNode(*_target_item);
+ set_rthread(t, 0);
+ set_lthread(_found_node, 1);
+ set_rthread(_found_node, 1);
+ _found_node->lt = t;
+ _found_node->rt = t->rt;
+ t->rt = _found_node;
+ _need_rebalancing = 1;
+ }
+ else
+ _add(t->rt);
+ if (_need_rebalancing)
+ {
+ switch(bf(t))
+ {
+ case AVLLEFTHEAVY:
+ set_bf(t, AVLBALANCED);
+ _need_rebalancing = 0;
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLRIGHTHEAVY);
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T>AVLNode* r = t->rt;
+ if (bf(r) == AVLRIGHTHEAVY)
+ {
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ _need_rebalancing = 0;
+ }
+ else
+ {
+ <T>AVLNode* l = r->lt;
+ set_lthread(r, rthread(l));
+ if (rthread(l))
+ r->lt = l;
+ else
+ r->lt = l->rt;
+ l->rt = r;
+ set_rthread(l, 0);
+ set_rthread(t, lthread(l));
+ if (lthread(l))
+ t->rt = l;
+ else
+ t->rt = l->lt;
+ l->lt = t;
+ set_lthread(l, 0);
+ if (bf(l) == AVLRIGHTHEAVY)
+ set_bf(t, AVLLEFTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(l) == AVLLEFTHEAVY)
+ set_bf(r, AVLRIGHTHEAVY);
+ else
+ set_bf(r, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ _need_rebalancing = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+Pix <T>AVLSet::add(<T&> item)
+{
+ if (root == 0)
+ {
+ ++count;
+ root = new <T>AVLNode(item);
+ set_rthread(root, 1);
+ set_lthread(root, 1);
+ return Pix(root);
+ }
+ else
+ {
+ _target_item = &item;
+ _need_rebalancing = 0;
+ _add(root);
+ return Pix(_found_node);
+ }
+}
+
+
+void <T>AVLSet::_del(<T>AVLNode* par, <T>AVLNode*& t)
+{
+ int comp;
+ if (_already_found)
+ {
+ if (rthread(t))
+ comp = 0;
+ else
+ comp = 1;
+ }
+ else
+ comp = <T>CMP(*_target_item, t->item);
+ if (comp == 0)
+ {
+ if (lthread(t) && rthread(t))
+ {
+ _found_node = t;
+ if (t == par->lt)
+ {
+ set_lthread(par, 1);
+ par->lt = t->lt;
+ }
+ else
+ {
+ set_rthread(par, 1);
+ par->rt = t->rt;
+ }
+ _need_rebalancing = 1;
+ return;
+ }
+ else if (lthread(t))
+ {
+ _found_node = t;
+ <T>AVLNode* s = succ(t);
+ if (s != 0 && lthread(s))
+ s->lt = t->lt;
+ t = t->rt;
+ _need_rebalancing = 1;
+ return;
+ }
+ else if (rthread(t))
+ {
+ _found_node = t;
+ <T>AVLNode* p = pred(t);
+ if (p != 0 && rthread(p))
+ p->rt = t->rt;
+ t = t->lt;
+ _need_rebalancing = 1;
+ return;
+ }
+ else // replace item & find someone deletable
+ {
+ <T>AVLNode* p = pred(t);
+ t->item = p->item;
+ _already_found = 1;
+ comp = -1; // fall through below to left
+ }
+ }
+
+ if (comp < 0)
+ {
+ if (lthread(t))
+ return;
+ _del(t, t->lt);
+ if (!_need_rebalancing)
+ return;
+ switch (bf(t))
+ {
+ case AVLLEFTHEAVY:
+ set_bf(t, AVLBALANCED);
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLRIGHTHEAVY);
+ _need_rebalancing = 0;
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T>AVLNode* r = t->rt;
+ switch (bf(r))
+ {
+ case AVLBALANCED:
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLRIGHTHEAVY);
+ set_bf(r, AVLLEFTHEAVY);
+ _need_rebalancing = 0;
+ t = r;
+ return;
+ case AVLRIGHTHEAVY:
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T>AVLNode* l = r->lt;
+ set_lthread(r, rthread(l));
+ if (rthread(l))
+ r->lt = l;
+ else
+ r->lt = l->rt;
+ l->rt = r;
+ set_rthread(l, 0);
+ set_rthread(t, lthread(l));
+ if (lthread(l))
+ t->rt = l;
+ else
+ t->rt = l->lt;
+ l->lt = t;
+ set_lthread(l, 0);
+ if (bf(l) == AVLRIGHTHEAVY)
+ set_bf(t, AVLLEFTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(l) == AVLLEFTHEAVY)
+ set_bf(r, AVLRIGHTHEAVY);
+ else
+ set_bf(r, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (rthread(t))
+ return;
+ _del(t, t->rt);
+ if (!_need_rebalancing)
+ return;
+ switch (bf(t))
+ {
+ case AVLRIGHTHEAVY:
+ set_bf(t, AVLBALANCED);
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLLEFTHEAVY);
+ _need_rebalancing = 0;
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T>AVLNode* l = t->lt;
+ switch (bf(l))
+ {
+ case AVLBALANCED:
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLLEFTHEAVY);
+ set_bf(l, AVLRIGHTHEAVY);
+ _need_rebalancing = 0;
+ t = l;
+ return;
+ case AVLLEFTHEAVY:
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T>AVLNode* r = l->rt;
+ set_rthread(l, lthread(r));
+ if (lthread(r))
+ l->rt = r;
+ else
+ l->rt = r->lt;
+ r->lt = l;
+ set_lthread(r, 0);
+ set_lthread(t, rthread(r));
+ if (rthread(r))
+ t->lt = r;
+ else
+ t->lt = r->rt;
+ r->rt = t;
+ set_rthread(r, 0);
+ if (bf(r) == AVLLEFTHEAVY)
+ set_bf(t, AVLRIGHTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(r) == AVLRIGHTHEAVY)
+ set_bf(l, AVLLEFTHEAVY);
+ else
+ set_bf(l, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+void <T>AVLSet::del(<T&> item)
+{
+ if (root == 0) return;
+ _need_rebalancing = 0;
+ _already_found = 0;
+ _found_node = 0;
+ _target_item = &item;
+ _del(root, root);
+ if (_found_node)
+ {
+ delete(_found_node);
+ if (--count == 0)
+ root = 0;
+ }
+}
+
+// build an ordered array of pointers to tree nodes back into a tree
+// we know that at least one element exists
+
+static <T>AVLNode* _do_treeify(int lo, int hi, int& h)
+{
+ int lh, rh;
+ int mid = (lo + hi) / 2;
+ <T>AVLNode* t = _hold_nodes[mid];
+ if (lo > mid - 1)
+ {
+ set_lthread(t, 1);
+ if (mid == 0)
+ t->lt = 0;
+ else
+ t->lt = _hold_nodes[mid-1];
+ lh = 0;
+ }
+ else
+ {
+ set_lthread(t, 0);
+ t->lt = _do_treeify(lo, mid-1, lh);
+ }
+ if (hi < mid + 1)
+ {
+ set_rthread(t, 1);
+ if (mid == _max_hold_index)
+ t->rt = 0;
+ else
+ t->rt = _hold_nodes[mid+1];
+ rh = 0;
+ }
+ else
+ {
+ set_rthread(t, 0);
+ t->rt = _do_treeify(mid+1, hi, rh);
+ }
+ if (lh == rh)
+ {
+ set_bf(t, AVLBALANCED);
+ h = lh + 1;
+ }
+ else if (lh == rh - 1)
+ {
+ set_bf(t, AVLRIGHTHEAVY);
+ h = rh + 1;
+ }
+ else if (rh == lh - 1)
+ {
+ set_bf(t, AVLLEFTHEAVY);
+ h = lh + 1;
+ }
+ else // can't happen
+ abort();
+
+ return t;
+}
+
+static <T>AVLNode* _treeify(int n)
+{
+ <T>AVLNode* t;
+ if (n == 0)
+ t = 0;
+ else
+ {
+ int b;
+ _max_hold_index = n-1;
+ t = _do_treeify(0, _max_hold_index, b);
+ }
+ delete _hold_nodes;
+ return t;
+}
+
+
+void <T>AVLSet::_kill(<T>AVLNode* t)
+{
+ if (t != 0)
+ {
+ if (!lthread(t)) _kill(t->lt);
+ if (!rthread(t)) _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T>AVLSet::<T>AVLSet(<T>AVLSet& b)
+{
+ if ((count = b.count) == 0)
+ {
+ root = 0;
+ }
+ else
+ {
+ _hold_nodes = new <T>AVLNodePtr [count];
+ <T>AVLNode* t = b.leftmost();
+ int i = 0;
+ while (t != 0)
+ {
+ _hold_nodes[i++] = new <T>AVLNode(t->item);
+ t = b.succ(t);
+ }
+ root = _treeify(count);
+ }
+}
+
+
+int <T>AVLSet::operator == (<T>AVLSet& y)
+{
+ if (count != y.count)
+ return 0;
+ else
+ {
+ <T>AVLNode* t = leftmost();
+ <T>AVLNode* u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (!(<T>EQ(t->item, u->item)))
+ return 0;
+ else
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ }
+ }
+}
+
+int <T>AVLSet::operator <= (<T>AVLSet& y)
+{
+ if (count > y.count)
+ return 0;
+ else
+ {
+ <T>AVLNode* t = leftmost();
+ <T>AVLNode* u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (u == 0)
+ return 0;
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ u = y.succ(u);
+ }
+ }
+}
+
+void <T>AVLSet::operator |=(<T>AVLSet& y)
+{
+ <T>AVLNode* t = leftmost();
+ <T>AVLNode* u = y.leftmost();
+ int rsize = count + y.count;
+ _hold_nodes = new <T>AVLNodePtr [rsize];
+ int k = 0;
+ for (;;)
+ {
+ if (t == 0)
+ {
+ while (u != 0)
+ {
+ _hold_nodes[k++] = new <T>AVLNode(u->item);
+ u = y.succ(u);
+ }
+ break;
+ }
+ else if (u == 0)
+ {
+ while (t != 0)
+ {
+ _hold_nodes[k++] = t;
+ t = succ(t);
+ }
+ break;
+ }
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ _hold_nodes[k++] = t;
+ t = succ(t);
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ {
+ _hold_nodes[k++] = t;
+ t = succ(t);
+ }
+ else
+ {
+ _hold_nodes[k++] = new <T>AVLNode(u->item);
+ u = y.succ(u);
+ }
+ }
+ root = _treeify(k);
+ count = k;
+}
+
+void <T>AVLSet::operator &= (<T>AVLSet& y)
+{
+ <T>AVLNode* t = leftmost();
+ <T>AVLNode* u = y.leftmost();
+ int rsize = (count < y.count)? count : y.count;
+ _hold_nodes = new <T>AVLNodePtr [rsize];
+ int k = 0;
+ for (;;)
+ {
+ if (t == 0)
+ break;
+ if (u == 0)
+ {
+ while (t != 0)
+ {
+ <T>AVLNode* tmp = succ(t);
+ delete t;
+ t = tmp;
+ }
+ break;
+ }
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ _hold_nodes[k++] = t;
+ t = succ(t);
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ {
+ <T>AVLNode* tmp = succ(t);
+ delete t;
+ t = tmp;
+ }
+ else
+ u = y.succ(u);
+ }
+ root = _treeify(k);
+ count = k;
+}
+
+
+void <T>AVLSet::operator -=(<T>AVLSet& y)
+{
+ <T>AVLNode* t = leftmost();
+ <T>AVLNode* u = y.leftmost();
+ int rsize = count;
+ _hold_nodes = new <T>AVLNodePtr [rsize];
+ int k = 0;
+ for (;;)
+ {
+ if (t == 0)
+ break;
+ else if (u == 0)
+ {
+ while (t != 0)
+ {
+ _hold_nodes[k++] = t;
+ t = succ(t);
+ }
+ break;
+ }
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ <T>AVLNode* tmp = succ(t);
+ delete t;
+ t = tmp;
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ {
+ _hold_nodes[k++] = t;
+ t = succ(t);
+ }
+ else
+ u = y.succ(u);
+ }
+ root = _treeify(k);
+ count = k;
+}
+
+int <T>AVLSet::owns(Pix i)
+{
+ if (i == 0) return 0;
+ for (<T>AVLNode* t = leftmost(); t != 0; t = succ(t))
+ if (Pix(t) == i) return 1;
+ return 0;
+}
+
+int <T>AVLSet::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T>AVLNode* trail = leftmost();
+ <T>AVLNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/AVLSet.hP b/gnu/lib/libg++/include/gen/AVLSet.hP
new file mode 100644
index 00000000000..c1aa8fad6ac
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/AVLSet.hP
@@ -0,0 +1,152 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>AVL_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>AVL_h 1
+
+#include "<T>.Set.h"
+
+struct <T>AVLNode
+{
+ <T>AVLNode* lt;
+ <T>AVLNode* rt;
+ <T> item;
+ char stat;
+ <T>AVLNode(<T&> h, <T>AVLNode* l=0, <T>AVLNode* r=0);
+ ~<T>AVLNode();
+};
+
+inline <T>AVLNode::<T>AVLNode(<T&> h, <T>AVLNode* l, <T>AVLNode* r)
+:lt(l), rt(r), item(h), stat(0) {}
+
+inline <T>AVLNode::~<T>AVLNode() {}
+
+typedef <T>AVLNode* <T>AVLNodePtr;
+
+
+class <T>AVLSet : public <T>Set
+{
+protected:
+ <T>AVLNode* root;
+
+ <T>AVLSet(<T>AVLNode* p, int l);
+
+ <T>AVLNode* leftmost();
+ <T>AVLNode* rightmost();
+ <T>AVLNode* pred(<T>AVLNode* t);
+ <T>AVLNode* succ(<T>AVLNode* t);
+ void _kill(<T>AVLNode* t);
+ void _add(<T>AVLNode*& t);
+ void _del(<T>AVLNode* p, <T>AVLNode*& t);
+
+public:
+ <T>AVLSet();
+ <T>AVLSet(<T>AVLSet& a);
+ inline ~<T>AVLSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item);
+
+ Pix last();
+ void prev(Pix& i);
+
+ void operator |= (<T>AVLSet& b);
+ void operator -= (<T>AVLSet& b);
+ void operator &= (<T>AVLSet& b);
+
+ int operator == (<T>AVLSet& b);
+ int operator != (<T>AVLSet& b);
+ int operator <= (<T>AVLSet& b);
+
+ int OK();
+};
+
+inline <T>AVLSet::~<T>AVLSet()
+{
+ _kill(root);
+}
+
+inline <T>AVLSet::<T>AVLSet()
+{
+ root = 0;
+ count = 0;
+}
+
+inline <T>AVLSet::<T>AVLSet(<T>AVLNode* p, int l)
+{
+ root = p;
+ count = l;
+}
+
+inline int <T>AVLSet::operator != (<T>AVLSet& b)
+{
+ return ! ((*this) == b);
+}
+
+inline Pix <T>AVLSet::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>AVLSet::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T>AVLSet::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>AVLNode*)i));
+}
+
+inline void <T>AVLSet::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>AVLNode*)i));
+}
+
+inline <T>& <T>AVLSet::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>AVLNode*)i)->item;
+}
+
+inline void <T>AVLSet::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T>AVLSet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/AVec.ccP b/gnu/lib/libg++/include/gen/AVec.ccP
new file mode 100644
index 00000000000..57a92708d9f
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/AVec.ccP
@@ -0,0 +1,397 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <builtin.h>
+#include "<T>.AVec.h"
+
+/*
+ The following brought to you by the department of redundancy department
+*/
+
+<T>AVec& <T>AVec::operator = (const <T>AVec& v)
+{
+ if (len != 0 && len != v.capacity())
+ error("nonconformant vectors.");
+ if (len == 0)
+ s = new <T> [len = v.capacity()];
+ if (s != v.vec())
+ {
+ for (int i = 0; i < len; ++i)
+ s[i] = v.vec()[i];
+ }
+ return *this;
+}
+
+<T>AVec& <T>AVec::operator = (<T&> f)
+{
+ for (int i = 0; i < len; ++i) s[i] = f;
+ return *this;
+}
+
+
+<T>AVec concat(<T>AVec & a, <T>AVec & b)
+{
+ int newl = a.capacity() + b.capacity();
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ while (t < top) *p++ = *t++;
+ top = &(b.vec()[b.capacity()]);
+ t = b.vec();
+ while (t < top) *p++ = *t++;
+ return <T>AVec(newl, news);
+}
+
+
+<T>AVec combine(<T>Combiner f, <T>AVec& a, <T>AVec& b)
+{
+ int newl = (a.capacity() < b.capacity())? a.capacity() : b.capacity();
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ <T>* top = &(a.vec()[newl]);
+ <T>* t = a.vec();
+ <T>* u = b.vec();
+ while (t < top) *p++ = (*f)(*t++, *u++);
+ return <T>AVec(newl, news);
+}
+
+<T>AVec reverse(<T>AVec& a)
+{
+ <T>* news = new <T> [a.capacity()];
+ if (a.capacity() != 0)
+ {
+ <T>* lo = news;
+ <T>* hi = &(news[a.capacity() - 1]);
+ while (lo < hi)
+ {
+ <T> tmp = *lo;
+ *lo++ = *hi;
+ *hi-- = tmp;
+ }
+ }
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec map(<T>Mapper f, <T>AVec& a)
+{
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ while(t < top) *p++ = (*f)(*t++);
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec <T>AVec::at(int from, int n)
+{
+ int to;
+ if (n < 0)
+ {
+ n = len - from;
+ to = len - 1;
+ }
+ else
+ to = from + n - 1;
+ if ((unsigned)from > (unsigned)to)
+ range_error();
+ <T>* news = new <T> [n];
+ <T>* p = news;
+ <T>* t = &(s[from]);
+ <T>* top = &(s[to]);
+ while (t <= top) *p++ = *t++;
+ return <T>AVec(n, news);
+}
+
+<T>AVec merge(<T>AVec & a, <T>AVec & b, <T>Comparator f)
+{
+ int newl = a.capacity() + b.capacity();
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ <T>* topa = &(a.vec()[a.capacity()]);
+ <T>* as = a.vec();
+ <T>* topb = &(b.vec()[b.capacity()]);
+ <T>* bs = b.vec();
+
+ for (;;)
+ {
+ if (as >= topa)
+ {
+ while (bs < topb) *p++ = *bs++;
+ break;
+ }
+ else if (bs >= topb)
+ {
+ while (as < topa) *p++ = *as++;
+ break;
+ }
+ else if ((*f)(*as, *bs) <= 0)
+ *p++ = *as++;
+ else
+ *p++ = *bs++;
+ }
+ return <T>AVec(newl, news);
+}
+
+<T>AVec operator + (<T>AVec& a, <T>AVec& b)
+{
+ a.check_len(b.capacity());
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ <T>* u = b.vec();
+ while (t < top) *p++ = *t++ + *u++;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec operator - (<T>AVec& a, <T>AVec& b)
+{
+ a.check_len(b.capacity());
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ <T>* u = b.vec();
+ while (t < top) *p++ = *t++ - *u++;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec product (<T>AVec& a, <T>AVec& b)
+{
+ a.check_len(b.capacity());
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ <T>* u = b.vec();
+ while (t < top) *p++ = *t++ * *u++;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec quotient(<T>AVec& a, <T>AVec& b)
+{
+ a.check_len(b.capacity());
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ <T>* u = b.vec();
+ while (t < top) *p++ = *t++ / *u++;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec operator + (<T>AVec& a, <T&> b)
+{
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ while (t < top) *p++ = *t++ + b;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec operator - (<T>AVec& a, <T&> b)
+{
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ while (t < top) *p++ = *t++ - b;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec operator * (<T>AVec& a, <T&> b)
+{
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ while (t < top) *p++ = *t++ * b;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec operator / (<T>AVec& a, <T&> b)
+{
+ <T>* news = new <T> [a.capacity()];
+ <T>* p = news;
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ while (t < top) *p++ = *t++ / b;
+ return <T>AVec(a.capacity(), news);
+}
+
+<T>AVec <T>AVec::operator - ()
+{
+ <T>* news = new <T> [len];
+ <T>* p = news;
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *p++ = -(*t++);
+ return <T>AVec(len, news);
+}
+
+<T>AVec& <T>AVec::operator += (<T>AVec& b)
+{
+ check_len(b.capacity());
+ <T>* u = b.vec();
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ += *u++;
+ return *this;
+}
+
+<T>AVec& <T>AVec::operator -= (<T>AVec& b)
+{
+ check_len(b.capacity());
+ <T>* u = b.vec();
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ -= *u++;
+ return *this;
+}
+
+<T>AVec& <T>AVec::product(<T>AVec& b)
+{
+ check_len(b.capacity());
+ <T>* u = b.vec();
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ *= *u++;
+ return *this;
+}
+
+<T>AVec& <T>AVec::quotient(<T>AVec& b)
+{
+ check_len(b.capacity());
+ <T>* u = b.vec();
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ /= *u++;
+ return *this;
+}
+
+<T>AVec& <T>AVec::operator += (<T&> b)
+{
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ += b;
+ return *this;
+}
+
+<T>AVec& <T>AVec::operator -= (<T&> b)
+{
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ -= b;
+ return *this;
+}
+
+<T>AVec& <T>AVec::operator *= (<T&> b)
+{
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ *= b;
+ return *this;
+}
+
+<T>AVec& <T>AVec::operator /= (<T&> b)
+{
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ /= b;
+ return *this;
+}
+
+<T> <T>AVec::max()
+{
+ if (len == 0)
+ return 0;
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ <T> res = *t++;
+ for (; t < top; ++t) if (*t > res) res = *t;
+ return res;
+}
+
+int <T>AVec::max_index()
+{
+ if (len == 0)
+ return -1;
+ int ind = 0;
+ for (int i = 1; i < len; ++i)
+ if (s[i] > s[ind])
+ ind = i;
+ return ind;
+}
+
+<T> <T>AVec::min()
+{
+ if (len == 0)
+ return 0;
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ <T> res = *t++;
+ for (; t < top; ++t) if (*t < res) res = *t;
+ return res;
+}
+
+int <T>AVec::min_index()
+{
+ if (len == 0)
+ return -1;
+ int ind = 0;
+ for (int i = 1; i < len; ++i)
+ if (s[i] < s[ind])
+ ind = i;
+ return ind;
+}
+
+<T> <T>AVec::sum()
+{
+ <T> res = 0;
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) res += *t++;
+ return res;
+}
+
+
+<T> <T>AVec::sumsq()
+{
+ <T> res = 0;
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ for (; t < top; ++t) res += *t * *t;
+ return res;
+}
+
+<T> operator * (<T>AVec& a, <T>AVec& b)
+{
+ a.check_len(b.capacity());
+ <T>* top = &(a.vec()[a.capacity()]);
+ <T>* t = a.vec();
+ <T>* u = b.vec();
+ <T> res = 0;
+ while (t < top) res += *t++ * *u++;
+ return res;
+}
diff --git a/gnu/lib/libg++/include/gen/AVec.hP b/gnu/lib/libg++/include/gen/AVec.hP
new file mode 100644
index 00000000000..c59720e93cc
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/AVec.hP
@@ -0,0 +1,118 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>AVec_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>AVec_h 1
+
+#include "<T>.Vec.h"
+
+class <T>AVec : public <T>Vec
+{
+protected:
+ void check_len(int l);
+ <T>* vec();
+ const <T>* vec() const;
+ <T>AVec(int l, <T>* d);
+ public:
+ <T>AVec ();
+ <T>AVec (int l);
+ <T>AVec (int l, <T&> fill_value);
+ <T>AVec (<T>AVec&);
+ ~<T>AVec ();
+
+ <T>AVec& operator = (const <T>AVec& a);
+ <T>AVec& operator = (<T&> fill_value);
+
+// vector by scalar -> vector operations
+
+ friend <T>AVec operator + (<T>AVec& a, <T&> b);
+ friend <T>AVec operator - (<T>AVec& a, <T&> b);
+ friend <T>AVec operator * (<T>AVec& a, <T&> b);
+ friend <T>AVec operator / (<T>AVec& a, <T&> b);
+
+ <T>AVec& operator += (<T&> b);
+ <T>AVec& operator -= (<T&> b);
+ <T>AVec& operator *= (<T&> b);
+ <T>AVec& operator /= (<T&> b);
+
+// vector by vector -> vector operations
+
+ friend <T>AVec operator + (<T>AVec& a, <T>AVec& b);
+ friend <T>AVec operator - (<T>AVec& a, <T>AVec& b);
+ <T>AVec& operator += (<T>AVec& b);
+ <T>AVec& operator -= (<T>AVec& b);
+
+ <T>AVec operator - ();
+
+ friend <T>AVec product(<T>AVec& a, <T>AVec& b);
+ <T>AVec& product(<T>AVec& b);
+ friend <T>AVec quotient(<T>AVec& a, <T>AVec& b);
+ <T>AVec& quotient(<T>AVec& b);
+
+// vector -> scalar operations
+
+ friend <T> operator * (<T>AVec& a, <T>AVec& b);
+
+ <T> sum();
+ <T> min();
+ <T> max();
+ <T> sumsq();
+
+// indexing
+
+ int min_index();
+ int max_index();
+
+// redundant but necesssary
+ friend <T>AVec concat(<T>AVec& a, <T>AVec& b);
+ friend <T>AVec map(<T>Mapper f, <T>AVec& a);
+ friend <T>AVec merge(<T>AVec& a, <T>AVec& b, <T>Comparator f);
+ friend <T>AVec combine(<T>Combiner f, <T>AVec& a, <T>AVec& b);
+ friend <T>AVec reverse(<T>AVec& a);
+ <T>AVec at(int from = 0, int n = -1);
+};
+
+inline <T>AVec::<T>AVec() {}
+inline <T>AVec::<T>AVec(int l) :<T>Vec(l) {}
+inline <T>AVec::<T>AVec(int l, <T&> fill_value) : <T>Vec (l, fill_value) {}
+inline <T>AVec::<T>AVec(<T>AVec& v) :<T>Vec(v) {}
+inline <T>AVec::<T>AVec(int l, <T>* d) :<T>Vec(l, d) {}
+inline <T>AVec::~<T>AVec() {}
+
+
+inline <T>* <T>AVec::vec()
+{
+ return s;
+}
+
+inline const <T>* <T>AVec::vec() const
+{
+ return s;
+}
+
+inline void <T>AVec::check_len(int l)
+{
+ if (l != len)
+ error("nonconformant vectors.");
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/BSTSet.ccP b/gnu/lib/libg++/include/gen/BSTSet.ccP
new file mode 100644
index 00000000000..da7d73a3a03
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/BSTSet.ccP
@@ -0,0 +1,377 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.BSTSet.h"
+
+
+/*
+ traversal primitives
+*/
+
+
+<T>BSTNode* <T>BSTSet::leftmost()
+{
+ <T>BSTNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T>BSTNode* <T>BSTSet::rightmost()
+{
+ <T>BSTNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T>BSTNode* <T>BSTSet::succ(<T>BSTNode* t)
+{
+ if (t == 0)
+ return 0;
+ if (t->rt != 0)
+ {
+ t = t->rt;
+ while (t->lt != 0) t = t->lt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->lt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+<T>BSTNode* <T>BSTSet::pred(<T>BSTNode* t)
+{
+ if (t == 0)
+ return 0;
+ else if (t->lt != 0)
+ {
+ t = t->lt;
+ while (t->rt != 0) t = t->rt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->rt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+
+Pix <T>BSTSet::seek(<T&> key)
+{
+ <T>BSTNode* t = root;
+ for (;;)
+ {
+ if (t == 0)
+ return 0;
+ int comp = <T>CMP(key, t->item);
+ if (comp == 0)
+ return Pix(t);
+ else if (comp < 0)
+ t = t->lt;
+ else
+ t = t->rt;
+ }
+}
+
+
+Pix <T>BSTSet::add(<T&> item)
+{
+ if (root == 0)
+ {
+ ++count;
+ root = new <T>BSTNode(item);
+ return Pix(root);
+ }
+
+ <T>BSTNode* t = root;
+ <T>BSTNode* p = root;
+ for (;;)
+ {
+ int comp = <T>CMP(t->item, item);
+ if (comp == 0)
+ return Pix(t);
+ else if (comp > 0)
+ t = t->lt;
+ else
+ t = t->rt;
+ if (t == 0)
+ {
+ ++count;
+ t = new <T>BSTNode(item);
+ if (comp > 0)
+ p->lt = t;
+ else
+ p->rt = t;
+ t->par = p;
+ return Pix(t);
+ }
+ p = t;
+ }
+}
+
+
+void <T>BSTSet::del(<T&> key)
+{
+ <T>BSTNode* t = root;
+ <T>BSTNode* p = root;
+ int comp;
+ for (;;)
+ {
+ if (t == 0)
+ return;
+ comp = <T>CMP(key, t->item);
+ if (comp == 0)
+ {
+ --count;
+ <T>BSTNode* repl;
+ if (t->lt == 0)
+ repl = t->rt;
+ else if (t->rt == 0)
+ repl = t->lt;
+ else
+ {
+ <T>BSTNode* prepl = t;
+ repl = t->lt;
+ while (repl->rt != 0)
+ {
+ prepl = repl;
+ repl = repl->rt;
+ }
+ if (prepl != t)
+ {
+ prepl->rt = repl->lt;
+ if (prepl->rt != 0) prepl->rt->par = prepl;
+ repl->lt = t->lt;
+ if (repl->lt != 0) repl->lt->par = repl;
+ }
+ repl->rt = t->rt;
+ if (repl->rt != 0) repl->rt->par = repl;
+ }
+ if (t == root)
+ {
+ root = repl;
+ if (repl != 0) repl->par = 0;
+ }
+ else
+ {
+ if (t == p->lt)
+ p->lt = repl;
+ else
+ p->rt = repl;
+ if (repl != 0) repl->par = p;
+ }
+ delete t;
+ return;
+ }
+ p = t;
+ if (comp < 0)
+ t = t->lt;
+ else
+ t = t->rt;
+ }
+}
+
+
+void <T>BSTSet::_kill(<T>BSTNode* t)
+{
+ if (t != 0)
+ {
+ _kill(t->lt);
+ _kill(t->rt);
+ delete t;
+ }
+}
+
+<T>BSTNode* <T>BSTSet::_copy(<T>BSTNode* t)
+{
+ if (t == 0)
+ return 0;
+ else
+ {
+ <T>BSTNode* u = new <T>BSTNode(t->item, _copy(t->lt), _copy(t->rt));
+ if (u->lt != 0) u->lt->par = u;
+ if (u->rt != 0) u->rt->par = u;
+ return u;
+ }
+}
+
+
+int <T>BSTSet::operator == (<T>BSTSet& y)
+{
+ if (count != y.count)
+ return 0;
+ else
+ {
+ <T>BSTNode* t = leftmost();
+ <T>BSTNode* u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (!<T>EQ(t->item, u->item))
+ return 0;
+ else
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ }
+ }
+}
+
+int <T>BSTSet::operator <= (<T>BSTSet& y)
+{
+ if (count > y.count)
+ return 0;
+ else
+ {
+ <T>BSTNode* t = leftmost();
+ <T>BSTNode* u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (u == 0)
+ return 0;
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ u = y.succ(u);
+ }
+ }
+}
+
+
+// linear-time, zero space overhead binary tree rebalancing from
+// Stout & Warren, ``Tree rebalancing in linear space and time''
+// CACM, Sept, 1986, p902.
+
+
+void <T>BSTSet::balance()
+{
+ if (count <= 2) return; // don't bother --
+ // also we assume non-null root, below
+
+ // make re-attaching the root easy via trickery
+
+ struct _fake_node { _fake_node *lt, *rt, *par; } fake_root;
+
+ fake_root.rt = (_fake_node*)root;
+ fake_root.par = 0;
+ <T>BSTNode* pseudo_root = (<T>BSTNode*)&fake_root;
+
+ // phase 1: tree-to-vine
+
+ <T>BSTNode* vine_tail = pseudo_root;
+ <T>BSTNode* remainder = root;
+
+ while (remainder != 0)
+ {
+ if (remainder->lt == 0)
+ {
+ vine_tail = remainder;
+ remainder = remainder->rt;
+ }
+ else
+ {
+ <T>BSTNode* tmp = remainder->lt;
+ remainder->lt = tmp->rt;
+ if (remainder->lt != 0) remainder->lt->par = remainder;
+ tmp->rt = remainder;
+ remainder->par = tmp;
+ vine_tail->rt = remainder = tmp;
+ }
+ }
+
+ // phase 2: vine-to-tree
+
+ // Uses the slightly simpler version adapted from
+ // Day ``Balancing a binary tree'' Computer Journal, Nov. 1976,
+ // since it's not generally important whether the `stray' leaves are
+ // on the left or on the right.
+
+ unsigned int spines = count - 1;
+ while (spines > 1)
+ {
+ int compressions = spines >> 1; // compress every other node
+ spines -= compressions + 1; // halve for next time
+
+ <T>BSTNode* scanner = pseudo_root;
+ while (compressions-- > 0)
+ {
+ <T>BSTNode* child = scanner->rt;
+ <T>BSTNode* grandchild = child->rt;
+ scanner->rt = grandchild;
+ grandchild->par = scanner;
+ child->rt = grandchild->lt;
+ if (child->rt != 0) child->rt->par = child;
+ grandchild->lt = child;
+ child->par = grandchild;
+ scanner = grandchild;
+ }
+ }
+
+ root = pseudo_root->rt;
+ root->par = 0;
+}
+
+
+int <T>BSTSet::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T>BSTNode* trail = leftmost();
+ <T>BSTNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/BSTSet.hP b/gnu/lib/libg++/include/gen/BSTSet.hP
new file mode 100644
index 00000000000..79a3dd36edf
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/BSTSet.hP
@@ -0,0 +1,152 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>BSTSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>BSTSet_h 1
+
+#include "<T>.Set.h"
+
+#ifndef _<T>BSTNode
+#define _<T>BSTNode 1
+
+struct <T>BSTNode
+{
+ <T>BSTNode* lt;
+ <T>BSTNode* rt;
+ <T>BSTNode* par;
+ <T> item;
+ <T>BSTNode(<T&> h, <T>BSTNode* l=0, <T>BSTNode* r=0,
+ <T>BSTNode* p = 0);
+ ~<T>BSTNode();
+};
+
+inline <T>BSTNode::<T>BSTNode(<T&> h, <T>BSTNode* l, <T>BSTNode* r,
+ <T>BSTNode* p)
+:lt(l), rt(r), par(p), item(h) {}
+
+inline <T>BSTNode::~<T>BSTNode() {}
+
+typedef <T>BSTNode* <T>BSTNodePtr;
+
+#endif
+
+class <T>BSTSet : public <T>Set
+{
+protected:
+ <T>BSTNode* root;
+
+ <T>BSTNode* leftmost();
+ <T>BSTNode* rightmost();
+ <T>BSTNode* pred(<T>BSTNode* t);
+ <T>BSTNode* succ(<T>BSTNode* t);
+ void _kill(<T>BSTNode* t);
+ <T>BSTNode* _copy(<T>BSTNode* t);
+
+public:
+ <T>BSTSet();
+ <T>BSTSet(<T>BSTSet& a);
+ inline ~<T>BSTSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item);
+
+ Pix last();
+ void prev(Pix& i);
+
+ int operator == (<T>BSTSet& b);
+ int operator != (<T>BSTSet& b);
+ int operator <= (<T>BSTSet& b);
+
+ void balance();
+ int OK();
+};
+
+inline <T>BSTSet::~<T>BSTSet()
+{
+ _kill(root);
+}
+
+inline <T>BSTSet::<T>BSTSet()
+{
+ root = 0;
+ count = 0;
+}
+
+
+inline <T>BSTSet::<T>BSTSet(<T>BSTSet& a)
+{
+ count = a.count;
+ root = _copy(a.root);
+}
+
+inline int <T>BSTSet::operator != (<T>BSTSet& b)
+{
+ return ! (*this == b);
+}
+
+inline Pix <T>BSTSet::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>BSTSet::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T>BSTSet::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>BSTNode*)i));
+}
+
+inline void <T>BSTSet::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>BSTNode*)i));
+}
+
+inline <T>& <T>BSTSet::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>BSTNode*)i)->item;
+}
+
+inline void <T>BSTSet::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T>BSTSet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Bag.ccP b/gnu/lib/libg++/include/gen/Bag.ccP
new file mode 100644
index 00000000000..3f9f06c00bc
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Bag.ccP
@@ -0,0 +1,74 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include "<T>.Bag.h"
+
+// error handling
+
+void <T>Bag::error(const char* msg)
+{
+ (*lib_error_handler)("Bag", msg);
+}
+
+
+Pix <T>Bag::seek(<T&> item, Pix i)
+{
+ if (i == 0)
+ i = first();
+ else
+ next(i);
+ for (;i != 0 && (!(<T>EQ((*this)(i), item))); next(i));
+ return i;
+}
+
+int <T>Bag::owns(Pix p)
+{
+ if (p == 0) return 0;
+ for (Pix i = first(); i != 0; next(i)) if (i == p) return 1;
+ return 0;
+}
+
+void <T>Bag::remove(<T&> item)
+{
+ int i = nof(item);
+ while (i-- > 0) del(item);
+}
+
+
+int <T>Bag::nof(<T&> item)
+{
+ int n = 0;
+ for (Pix p = first(); p; next(p)) if (<T>EQ((*this)(p), item)) ++n;
+ return n;
+}
+
+void <T>Bag::clear()
+{
+ Pix i = first();
+ while (i != 0)
+ {
+ del((*this)(i));
+ i = first();
+ }
+}
+
+
diff --git a/gnu/lib/libg++/include/gen/Bag.hP b/gnu/lib/libg++/include/gen/Bag.hP
new file mode 100644
index 00000000000..de6dc5c4ca0
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Bag.hP
@@ -0,0 +1,79 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>Bag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Bag_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T>Bag
+{
+protected:
+ int count;
+
+public:
+ inline virtual ~<T>Bag();
+
+ int length(); // current number of items
+ int empty();
+
+ virtual Pix add(<T&> item) = 0; // add item; return Pix
+
+ virtual void del(<T&> item) = 0; // delete 1 occurrence of item
+#undef remove
+ virtual void remove(<T&> item); // delete all occurrences
+ virtual void clear(); // delete all items
+
+ inline virtual int contains(<T&> item); // is item in Bag?
+ virtual int nof(<T&> item); // how many in Bag?
+
+ virtual Pix first() = 0; // Pix of first item or 0
+ virtual void next(Pix& i) = 0; // advance to next or 0
+
+ virtual <T>& operator () (Pix i) = 0; // access item at i
+
+ virtual Pix seek(<T&> item, Pix from=0); // Pix of next occurrence
+ virtual int owns(Pix i); // is i a valid Pix ?
+
+ void error(const char* msg);
+ virtual int OK() = 0; // rep invariant
+};
+
+inline <T>Bag::~<T>Bag() {}
+
+inline int <T>Bag::length()
+{
+ return count;
+}
+
+inline int <T>Bag::empty()
+{
+ return count == 0;
+}
+
+inline int <T>Bag::contains(<T&> item)
+{
+ return seek(item) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/CHBag.ccP b/gnu/lib/libg++/include/gen/CHBag.ccP
new file mode 100644
index 00000000000..22c9d707a59
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHBag.ccP
@@ -0,0 +1,210 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.CHBag.h"
+
+// The nodes are linked together serially via a version
+// of a trick used in some vtables: odd pointers are
+// actually links to the next table entry.
+// Not terrible, but not wonderful either
+
+static inline int goodCHptr(<T>CHNode* t)
+{
+ return ((((unsigned)t) & 1) == 0);
+}
+
+static inline <T>CHNode* index_to_CHptr(int i)
+{
+ return (<T>CHNode*)((i << 1) + 1);
+}
+
+static inline int CHptr_to_index(<T>CHNode* t)
+{
+ return ( ((unsigned) t) >> 1);
+}
+
+<T>CHBag::<T>CHBag(unsigned int sz)
+{
+ tab = (<T>CHNode**)(new <T>CHNodePtr[size = sz]);
+ for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
+ count = 0;
+}
+
+<T>CHBag::<T>CHBag(<T>CHBag& a)
+{
+ tab = (<T>CHNode**)(new <T>CHNodePtr[size = a.size]);
+ for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
+ count = 0;
+ for (Pix p = a.first(); p; a.next(p)) add(a(p));
+}
+
+
+Pix <T>CHBag::seek(<T&> key, Pix i)
+{
+ <T>CHNode* p = (<T>CHNode*)i;
+ if (p == 0 || !<T>EQ(p->hd, key))
+ {
+ unsigned int h = <T>HASH(key) % size;
+ for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl)
+ if (<T>EQ(key, t->hd))
+ return Pix(t);
+ }
+ else
+ {
+ for (p = p->tl; goodCHptr(p); p = p->tl)
+ if (<T>EQ(p->hd, key))
+ return Pix(p);
+ }
+ return 0;
+}
+
+int <T>CHBag::nof(<T&> key)
+{
+ int n = 0;
+ unsigned int h = <T>HASH(key) % size;
+ for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl)
+ if (<T>EQ(key, t->hd)) ++n;
+ return n;
+}
+
+
+Pix <T>CHBag::add(<T&> item)
+{
+ unsigned int h = <T>HASH(item) % size;
+ <T>CHNode* t = new <T>CHNode(item);
+ t->tl = tab[h];
+ tab[h] = t;
+ ++count;
+ return Pix(t);
+}
+
+void <T>CHBag::del(<T&> key)
+{
+ unsigned int h = <T>HASH(key) % size;
+
+ <T>CHNode* t = tab[h];
+ <T>CHNode* trail = t;
+ while (goodCHptr(t))
+ {
+ if (<T>EQ(key, t->hd))
+ {
+ if (trail == t)
+ tab[h] = t->tl;
+ else
+ trail->tl = t->tl;
+ delete t;
+ --count;
+ return;
+ }
+ trail = t;
+ t = t->tl;
+ }
+}
+
+void <T>CHBag::remove(<T&> key)
+{
+ unsigned int h = <T>HASH(key) % size;
+
+ <T>CHNode* t = tab[h];
+ <T>CHNode* trail = t;
+ while (goodCHptr(t))
+ {
+ if (<T>EQ(key, t->hd))
+ {
+ --count;
+ if (trail == t)
+ {
+ tab[h] = t->tl;
+ delete t;
+ t = trail = tab[h];
+ }
+ else
+ {
+ trail->tl = t->tl;
+ delete t;
+ t = trail->tl;
+ }
+ }
+ else
+ {
+ trail = t;
+ t = t->tl;
+ }
+ }
+}
+
+
+void <T>CHBag::clear()
+{
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T>CHNode* p = tab[i];
+ tab[i] = index_to_CHptr(i+1);
+ while (goodCHptr(p))
+ {
+ <T>CHNode* nxt = p->tl;
+ delete(p);
+ p = nxt;
+ }
+ }
+ count = 0;
+}
+
+Pix <T>CHBag::first()
+{
+ for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]);
+ return 0;
+}
+
+void <T>CHBag::next(Pix& p)
+{
+ if (p == 0) return;
+ <T>CHNode* t = ((<T>CHNode*)p)->tl;
+ if (goodCHptr(t))
+ p = Pix(t);
+ else
+ {
+ for (unsigned int i = CHptr_to_index(t); i < size; ++i)
+ {
+ if (goodCHptr(tab[i]))
+ {
+ p = Pix(tab[i]);
+ return;
+ }
+ }
+ p = 0;
+ }
+}
+
+int <T>CHBag::OK()
+{
+ int v = tab != 0;
+ int n = 0;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T>CHNode* p;
+ for (p = tab[i]; goodCHptr(p); p = p->tl) ++n;
+ v &= CHptr_to_index(p) == i + 1;
+ }
+ v &= count == n;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/CHBag.hP b/gnu/lib/libg++/include/gen/CHBag.hP
new file mode 100644
index 00000000000..b2fe61f6707
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHBag.hP
@@ -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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>CHBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>CHBag_h 1
+
+#include "<T>.Bag.h"
+
+
+#include "<T>.CHNode.h"
+
+class <T>CHBag : public <T>Bag
+{
+protected:
+ <T>CHNode** tab;
+ unsigned int size;
+
+public:
+ <T>CHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>CHBag(<T>CHBag& a);
+ inline ~<T>CHBag();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ inline int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+
+inline <T>CHBag::~<T>CHBag()
+{
+ clear();
+ delete tab;
+}
+
+inline int <T>CHBag::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>& <T>CHBag::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>CHNode*)i)->hd;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/CHMap.ccP b/gnu/lib/libg++/include/gen/CHMap.ccP
new file mode 100644
index 00000000000..af28fc305a8
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHMap.ccP
@@ -0,0 +1,168 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.<C>.CHMap.h"
+
+// The nodes are linked together serially via a version
+// of a trick used in some vtables: odd pointers are
+// actually links to the next table entry.
+// Not terrible, but not wonderful either
+
+static inline int goodCHptr(<T><C>CHNode* t)
+{
+ return ((((unsigned)t) & 1) == 0);
+}
+
+static inline <T><C>CHNode* index_to_CHptr(int i)
+{
+ return (<T><C>CHNode*)((i << 1) + 1);
+}
+
+static inline int CHptr_to_index(<T><C>CHNode* t)
+{
+ return ( ((unsigned) t) >> 1);
+}
+
+<T><C>CHMap::<T><C>CHMap(<C&> dflt, unsigned int sz)
+ :<T><C>Map(dflt)
+{
+ tab = (<T><C>CHNode**)(new <T><C>CHNodePtr[size = sz]);
+ for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
+ count = 0;
+}
+
+<T><C>CHMap::<T><C>CHMap(<T><C>CHMap& a) :<T><C>Map(a.def)
+{
+ tab = (<T><C>CHNode**)(new <T><C>CHNodePtr[size = a.size]);
+ for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
+ count = 0;
+ for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p);
+}
+
+
+Pix <T><C>CHMap::seek(<T&> key)
+{
+ unsigned int h = <T>HASH(key) % size;
+
+ for (<T><C>CHNode* t = tab[h]; goodCHptr(t); t = t->tl)
+ if (<T>EQ(key, t->hd))
+ return Pix(t);
+
+ return 0;
+}
+
+
+<C>& <T><C>CHMap::operator [](<T&> item)
+{
+ unsigned int h = <T>HASH(item) % size;
+ <T><C>CHNode* t;
+
+ for (t = tab[h]; goodCHptr(t); t = t->tl)
+ if (<T>EQ(item, t->hd))
+ return t->cont;
+
+ t = new <T><C>CHNode(item, def, tab[h]);
+ tab[h] = t;
+ ++count;
+ return t->cont;
+}
+
+
+void <T><C>CHMap::del(<T&> key)
+{
+ unsigned int h = <T>HASH(key) % size;
+
+ <T><C>CHNode* t = tab[h];
+ <T><C>CHNode* trail = t;
+ while (goodCHptr(t))
+ {
+ if (<T>EQ(key, t->hd))
+ {
+ if (trail == t)
+ tab[h] = t->tl;
+ else
+ trail->tl = t->tl;
+ delete t;
+ --count;
+ return;
+ }
+ trail = t;
+ t = t->tl;
+ }
+}
+
+
+void <T><C>CHMap::clear()
+{
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T><C>CHNode* p = tab[i];
+ tab[i] = index_to_CHptr(i+1);
+ while (goodCHptr(p))
+ {
+ <T><C>CHNode* nxt = p->tl;
+ delete(p);
+ p = nxt;
+ }
+ }
+ count = 0;
+}
+
+Pix <T><C>CHMap::first()
+{
+ for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]);
+ return 0;
+}
+
+void <T><C>CHMap::next(Pix& p)
+{
+ <T><C>CHNode* t = ((<T><C>CHNode*)p)->tl;
+ if (goodCHptr(t))
+ p = Pix(t);
+ else
+ {
+ for (unsigned int i = CHptr_to_index(t); i < size; ++i)
+ {
+ if (goodCHptr(tab[i]))
+ {
+ p = Pix(tab[i]);
+ return;
+ }
+ }
+ p = 0;
+ }
+}
+
+
+int <T><C>CHMap::OK()
+{
+ int v = tab != 0;
+ int n = 0;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T><C>CHNode* p;
+ for (p = tab[i]; goodCHptr(p); p = p->tl) ++n;
+ v &= CHptr_to_index(p) == i + 1;
+ }
+ v &= count == n;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/CHMap.hP b/gnu/lib/libg++/include/gen/CHMap.hP
new file mode 100644
index 00000000000..2b4e25a284b
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHMap.hP
@@ -0,0 +1,104 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T><C>CHMap_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>CHMap_h 1
+
+#include "<T>.<C>.Map.h"
+
+#ifndef _<T><C>CHNode_h
+#define _<T><C>CHNode_h 1
+
+struct <T><C>CHNode
+{
+ <T><C>CHNode* tl;
+ <T> hd;
+ <C> cont;
+ <T><C>CHNode();
+ <T><C>CHNode(<T&> h, <C&> c, <T><C>CHNode* t = 0);
+ ~<T><C>CHNode();
+};
+
+inline <T><C>CHNode::<T><C>CHNode() {}
+
+inline <T><C>CHNode::<T><C>CHNode(<T&> h, <C&> c, <T><C>CHNode* t)
+ : tl(t), hd(h), cont(c) {}
+
+inline <T><C>CHNode::~<T><C>CHNode() {}
+
+typedef <T><C>CHNode* <T><C>CHNodePtr;
+
+#endif
+
+
+class <T><C>CHMap : public <T><C>Map
+{
+protected:
+ <T><C>CHNode** tab;
+ unsigned int size;
+
+public:
+ <T><C>CHMap(<C&> dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY);
+ <T><C>CHMap(<T><C>CHMap& a);
+ inline ~<T><C>CHMap();
+
+ <C>& operator [] (<T&> key);
+
+ void del(<T&> key);
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& key(Pix i);
+ inline <C>& contents(Pix i);
+
+ Pix seek(<T&> key);
+ inline int contains(<T&> key);
+
+ void clear();
+ int OK();
+};
+
+
+inline <T><C>CHMap::~<T><C>CHMap()
+{
+ clear();
+ delete tab;
+}
+
+inline int <T><C>CHMap::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>& <T><C>CHMap::key(Pix p)
+{
+ if (p == 0) error("null Pix");
+ return ((<T><C>CHNode*)p)->hd;
+}
+
+inline <C>& <T><C>CHMap::contents(Pix p)
+{
+ if (p == 0) error("null Pix");
+ return ((<T><C>CHNode*)p)->cont;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/CHNode.ccP b/gnu/lib/libg++/include/gen/CHNode.ccP
new file mode 100644
index 00000000000..b9a1e176ef4
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHNode.ccP
@@ -0,0 +1,21 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1992 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.CHNode.h"
diff --git a/gnu/lib/libg++/include/gen/CHNode.hP b/gnu/lib/libg++/include/gen/CHNode.hP
new file mode 100644
index 00000000000..af3acd1557c
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHNode.hP
@@ -0,0 +1,43 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1982 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>CHNode_h
+#define _<T>CHNode_h 1
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include "<T>.defs.h"
+
+struct <T>CHNode
+{
+ <T>CHNode* tl;
+ <T> hd;
+ <T>CHNode();
+ <T>CHNode(<T&> h, <T>CHNode* t = 0);
+ ~<T>CHNode();
+};
+
+inline <T>CHNode::<T>CHNode() {}
+
+inline <T>CHNode::<T>CHNode(<T&> h, <T>CHNode* t) :tl(t), hd(h) {}
+
+inline <T>CHNode::~<T>CHNode() {}
+
+typedef <T>CHNode* <T>CHNodePtr;
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/CHSet.ccP b/gnu/lib/libg++/include/gen/CHSet.ccP
new file mode 100644
index 00000000000..5a3727b7970
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHSet.ccP
@@ -0,0 +1,273 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.CHSet.h"
+
+// A CHSet is implemented as an array (tab) of buckets, each of which
+// contains a pointer to a list of <T>CHNodes. Each node contains a
+// pointer to the next node in the list, and a pointer to the <T>.
+// The end of the list is marked by a next node pointer which is odd
+// when considered as an integer (least significant bit = 1). The
+// assumption is that CHNodes will all begin on even addresses. If
+// the odd pointer is right-shifted by one bit, it becomes the index
+// within the tab array of the next bucket (that is, bucket i has
+// next bucket pointer 2*(i+1)+1).
+
+// The bucket pointers are initialized by the constructor and
+// used to support the next(Pix&) method.
+
+// This implementation is not portable to machines with different
+// pointer and integer sizes, or on which CHNodes might be aligned on
+// odd byte boundaries, but allows the same pointer to be used for
+// chaining within a bucket and to the next bucket.
+
+
+static inline int goodCHptr(<T>CHNode* t)
+{
+ return ((((unsigned)t) & 1) == 0);
+}
+
+static inline <T>CHNode* index_to_CHptr(int i)
+{
+ return (<T>CHNode*)((i << 1) + 1);
+}
+
+static inline int CHptr_to_index(<T>CHNode* t)
+{
+ return ( ((unsigned) t) >> 1);
+}
+
+<T>CHSet::<T>CHSet(unsigned int sz)
+{
+ tab = (<T>CHNode**)(new <T>CHNodePtr[size = sz]);
+ for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
+ count = 0;
+}
+
+<T>CHSet::<T>CHSet(<T>CHSet& a)
+{
+ tab = (<T>CHNode**)(new <T>CHNodePtr[size = a.size]);
+ for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
+ count = 0;
+ for (Pix p = a.first(); p; a.next(p)) add(a(p));
+}
+
+
+Pix <T>CHSet::seek(<T&> key)
+{
+ unsigned int h = <T>HASH(key) % size;
+
+ for (<T>CHNode* t = tab[h]; goodCHptr(t); t = t->tl)
+ if (<T>EQ(key, t->hd))
+ return Pix(t);
+
+ return 0;
+}
+
+
+Pix <T>CHSet::add(<T&> item)
+{
+ unsigned int h = <T>HASH(item) % size;
+ <T>CHNode* t;
+
+ for (t = tab[h]; goodCHptr(t); t = t->tl)
+ if (<T>EQ(item, t->hd))
+ return Pix(t);
+
+ ++count;
+ t = new <T>CHNode(item, tab[h]);
+ tab[h] = t;
+ return Pix(t);
+}
+
+
+void <T>CHSet::del(<T&> key)
+{
+ unsigned int h = <T>HASH(key) % size;
+
+ <T>CHNode* t = tab[h];
+ <T>CHNode* trail = t;
+ while (goodCHptr(t))
+ {
+ if (<T>EQ(key, t->hd))
+ {
+ if (trail == t)
+ tab[h] = t->tl;
+ else
+ trail->tl = t->tl;
+ delete t;
+ --count;
+ return;
+ }
+ trail = t;
+ t = t->tl;
+ }
+}
+
+
+void <T>CHSet::clear()
+{
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T>CHNode* p = tab[i];
+ tab[i] = index_to_CHptr(i+1);
+ while (goodCHptr(p))
+ {
+ <T>CHNode* nxt = p->tl;
+ delete(p);
+ p = nxt;
+ }
+ }
+ count = 0;
+}
+
+Pix <T>CHSet::first()
+{
+ for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]);
+ return 0;
+}
+
+void <T>CHSet::next(Pix& p)
+{
+ if (p == 0) return;
+ <T>CHNode* t = ((<T>CHNode*)p)->tl;
+ if (goodCHptr(t))
+ p = Pix(t);
+ else
+ {
+ for (unsigned int i = CHptr_to_index(t); i < size; ++i)
+ {
+ if (goodCHptr(tab[i]))
+ {
+ p = Pix(tab[i]);
+ return;
+ }
+ }
+ p = 0;
+ }
+}
+
+int <T>CHSet::operator == (<T>CHSet& b)
+{
+ if (count != b.count)
+ return 0;
+ else
+ {
+ <T>CHNode* p;
+ for (unsigned int i = 0; i < size; ++i)
+ for (p = tab[i]; goodCHptr(p); p = p->tl)
+ if (b.seek(p->hd) == 0)
+ return 0;
+ for (unsigned int i = 0; i < b.size; ++i)
+ for (p = b.tab[i]; goodCHptr(p); p = p->tl)
+ if (seek(p->hd) == 0)
+ return 0;
+ return 1;
+ }
+}
+
+int <T>CHSet::operator <= (<T>CHSet& b)
+{
+ if (count > b.count)
+ return 0;
+ else
+ {
+ for (unsigned int i = 0; i < size; ++i)
+ for (<T>CHNode* p = tab[i]; goodCHptr(p); p = p->tl)
+ if (b.seek(p->hd) == 0)
+ return 0;
+ return 1;
+ }
+}
+
+void <T>CHSet::operator |= (<T>CHSet& b)
+{
+ if (&b == this || b.count == 0)
+ return;
+ for (unsigned int i = 0; i < b.size; ++i)
+ for (<T>CHNode* p = b.tab[i]; goodCHptr(p); p = p->tl)
+ add(p->hd);
+}
+
+void <T>CHSet::operator &= (<T>CHSet& b)
+{
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T>CHNode* t = tab[i];
+ <T>CHNode* trail = t;
+ while (goodCHptr(t))
+ {
+ <T>CHNode* nxt = t->tl;
+ if (b.seek(t->hd) == 0)
+ {
+ if (trail == tab[i])
+ trail = tab[i] = nxt;
+ else
+ trail->tl = nxt;
+ delete t;
+ --count;
+ }
+ else
+ trail = t;
+ t = nxt;
+ }
+ }
+}
+
+void <T>CHSet::operator -= (<T>CHSet& b)
+{
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T>CHNode* t = tab[i];
+ <T>CHNode* trail = t;
+ while (goodCHptr(t))
+ {
+ <T>CHNode* nxt = t->tl;
+ if (b.seek(t->hd) != 0)
+ {
+ if (trail == tab[i])
+ trail = tab[i] = nxt;
+ else
+ trail->tl = nxt;
+ delete t;
+ --count;
+ }
+ else
+ trail = t;
+ t = nxt;
+ }
+ }
+}
+
+int <T>CHSet::OK()
+{
+ int v = tab != 0;
+ int n = 0;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ <T>CHNode* p;
+ for (p = tab[i]; goodCHptr(p); p = p->tl) ++n;
+ v &= CHptr_to_index(p) == i + 1;
+ }
+ v &= count == n;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/CHSet.hP b/gnu/lib/libg++/include/gen/CHSet.hP
new file mode 100644
index 00000000000..1fc2c8e994f
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/CHSet.hP
@@ -0,0 +1,84 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>CHSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>CHSet_h 1
+
+#include "<T>.Set.h"
+#include "<T>.CHNode.h"
+
+class <T>CHSet : public <T>Set
+{
+protected:
+ <T>CHNode** tab;
+ unsigned int size;
+
+public:
+ <T>CHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>CHSet(<T>CHSet& a);
+ inline ~<T>CHSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item);
+
+ void operator |= (<T>CHSet& b);
+ void operator -= (<T>CHSet& b);
+ void operator &= (<T>CHSet& b);
+
+ int operator == (<T>CHSet& b);
+ int operator != (<T>CHSet& b);
+ int operator <= (<T>CHSet& b);
+
+ int OK();
+};
+
+inline <T>CHSet::~<T>CHSet()
+{
+ clear();
+ delete tab;
+}
+
+inline int <T>CHSet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>& <T>CHSet::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>CHNode*)i)->hd;
+}
+
+inline int <T>CHSet::operator != (<T>CHSet& b)
+{
+ return ! ((*this) == b);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/DLDeque.ccP b/gnu/lib/libg++/include/gen/DLDeque.ccP
new file mode 100644
index 00000000000..d5a0db7f910
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/DLDeque.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.DLDeque.h"
diff --git a/gnu/lib/libg++/include/gen/DLDeque.hP b/gnu/lib/libg++/include/gen/DLDeque.hP
new file mode 100644
index 00000000000..6d8cc70fd98
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/DLDeque.hP
@@ -0,0 +1,130 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>DLDeque_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>DLDeque_h
+
+#include "<T>.DLList.h"
+#include "<T>.Deque.h"
+
+class <T>DLDeque : public <T>Deque
+{
+ <T>DLList p;
+
+public:
+ <T>DLDeque();
+ <T>DLDeque(const <T>DLDeque& d);
+ inline ~<T>DLDeque();
+
+ void operator = (const <T>DLDeque&);
+
+ inline void push(<T&> item); // insert at front
+ inline void enq(<T&> item); // insert at rear
+
+ inline <T>& front();
+ inline <T>& rear();
+
+ inline <T> deq();
+ inline void del_front();
+ inline void del_rear();
+
+ inline void clear();
+ inline int empty();
+ inline int full();
+ inline int length();
+
+ inline int OK();
+};
+
+
+inline <T>DLDeque::<T>DLDeque() : p() {}
+inline <T>DLDeque::<T>DLDeque(const <T>DLDeque& d) : p(d.p) {}
+
+inline <T>DLDeque::~<T>DLDeque() {}
+
+inline void <T>DLDeque::push(<T&>item)
+{
+ p.prepend(item);
+}
+
+inline void <T>DLDeque::enq(<T&>item)
+{
+ p.append(item);
+}
+
+inline <T> <T>DLDeque::deq()
+{
+ return p.remove_front();
+}
+
+inline <T>& <T>DLDeque::front()
+{
+ return p.front();
+}
+
+inline <T>& <T>DLDeque::rear()
+{
+ return p.rear();
+}
+
+inline void <T>DLDeque::del_front()
+{
+ p.del_front();
+}
+
+inline void <T>DLDeque::del_rear()
+{
+ p.del_rear();
+}
+
+inline void <T>DLDeque::operator =(const <T>DLDeque& s)
+{
+ p.operator = (s.p);
+}
+
+
+inline int <T>DLDeque::empty()
+{
+ return p.empty();
+}
+
+inline int <T>DLDeque::full()
+{
+ return 0;
+}
+
+inline int <T>DLDeque::length()
+{
+ return p.length();
+}
+
+inline int <T>DLDeque::OK()
+{
+ return p.OK();
+}
+
+inline void <T>DLDeque::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/DLList.ccP b/gnu/lib/libg++/include/gen/DLList.ccP
new file mode 100644
index 00000000000..c870dc18595
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/DLList.ccP
@@ -0,0 +1,339 @@
+// This may look like C code, but it is really -*- C++ -*-
+// WARNING: This file is obsolete. Use ../DLList.cc, if you can.
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <limits.h>
+#include <stream.h>
+#include <builtin.h>
+#include "<T>.DLList.h"
+
+// error handling
+
+
+
+void <T>DLList::error(const char* msg)
+{
+ (*lib_error_handler)("DLList", msg);
+}
+
+int <T>DLList::length()
+{
+ int l = 0;
+ <T>DLListNode* t = h;
+ if (t != 0) do { ++l; t = t->fd; } while (t != h);
+ return l;
+}
+
+<T>DLList::<T>DLList(const <T>DLList& a)
+{
+ if (a.h == 0)
+ h = 0;
+ else
+ {
+ <T>DLListNode* p = a.h;
+ <T>DLListNode* t = new <T>DLListNode(p->hd);
+ h = t;
+ p = p->fd;
+ while (p != a.h)
+ {
+ <T>DLListNode* n = new <T>DLListNode(p->hd);
+ t->fd = n;
+ n->bk = t;
+ t = n;
+ p = p->fd;
+ }
+ t->fd = h;
+ h->bk = t;
+ return;
+ }
+}
+
+<T>DLList& <T>DLList::operator = (const <T>DLList& a)
+{
+ if (h != a.h)
+ {
+ clear();
+ if (a.h != 0)
+ {
+ <T>DLListNode* p = a.h;
+ <T>DLListNode* t = new <T>DLListNode(p->hd);
+ h = t;
+ p = p->fd;
+ while (p != a.h)
+ {
+ <T>DLListNode* n = new <T>DLListNode(p->hd);
+ t->fd = n;
+ n->bk = t;
+ t = n;
+ p = p->fd;
+ }
+ t->fd = h;
+ h->bk = t;
+ }
+ }
+ return *this;
+}
+
+void <T>DLList::clear()
+{
+ if (h == 0)
+ return;
+
+ <T>DLListNode* p = h->fd;
+ h->fd = 0;
+ h = 0;
+
+ while (p != 0)
+ {
+ <T>DLListNode* nxt = p->fd;
+ delete(p);
+ p = nxt;
+ }
+}
+
+
+Pix <T>DLList::prepend(<T&> item)
+{
+ <T>DLListNode* t = new <T>DLListNode(item);
+ 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 <T>DLList::append(<T&> item)
+{
+ <T>DLListNode* t = new <T>DLListNode(item);
+ 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 <T>DLList::ins_after(Pix p, <T&> item)
+{
+ if (p == 0) return prepend(item);
+ <T>DLListNode* u = (<T>DLListNode*) p;
+ <T>DLListNode* t = new <T>DLListNode(item, u, u->fd);
+ u->fd->bk = t;
+ u->fd = t;
+ return Pix(t);
+}
+
+Pix <T>DLList::ins_before(Pix p, <T&> item)
+{
+ if (p == 0) error("null Pix");
+ <T>DLListNode* u = (<T>DLListNode*) p;
+ <T>DLListNode* t = new <T>DLListNode(item, u->bk, u);
+ u->bk->fd = t;
+ u->bk = t;
+ if (u == h) h = t;
+ return Pix(t);
+}
+
+void <T>DLList::join(<T>DLList& b)
+{
+ <T>DLListNode* t = b.h;
+ b.h = 0;
+ if (h == 0)
+ h = t;
+ else if (t != 0)
+ {
+ <T>DLListNode* l = t->bk;
+ h->bk->fd = t;
+ t->bk = h->bk;
+ h->bk = l;
+ l->fd = h;
+ }
+}
+
+int <T>DLList::owns(Pix p)
+{
+ <T>DLListNode* t = h;
+ if (t != 0 && p != 0)
+ {
+ do
+ {
+ if (Pix(t) == p) return 1;
+ t = t->fd;
+ } while (t != h);
+ }
+ return 0;
+}
+
+void <T>DLList::del(Pix& p, int dir)
+{
+ if (p == 0) error("null Pix");
+ <T>DLListNode* t = (<T>DLListNode*) 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 <T>DLList::del_after(Pix& p)
+{
+ if (p == 0)
+ {
+ del_front();
+ return;
+ }
+
+ <T>DLListNode* b = (<T>DLListNode*) p;
+ <T>DLListNode* 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 t;
+}
+
+<T> <T>DLList::remove_front()
+{
+ if (h == 0)
+ error("remove_front of empty list");
+ <T>DLListNode* t = h;
+ <T> res = t->hd;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ h->fd->bk = h->bk;
+ h->bk->fd = h->fd;
+ h = h->fd;
+ }
+ delete t;
+ return res;
+}
+
+
+void <T>DLList::del_front()
+{
+ if (h == 0)
+ error("del_front of empty list");
+ <T>DLListNode* t = h;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ h->fd->bk = h->bk;
+ h->bk->fd = h->fd;
+ h = h->fd;
+ }
+ delete t;
+}
+
+<T> <T>DLList::remove_rear()
+{
+ if (h == 0)
+ error("remove_rear of empty list");
+ <T>DLListNode* t = h->bk;
+ <T> res = t->hd;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ t->fd->bk = t->bk;
+ t->bk->fd = t->fd;
+ }
+ delete t;
+ return res;
+}
+
+
+void <T>DLList::del_rear()
+{
+ if (h == 0)
+ error("del_rear of empty list");
+ <T>DLListNode* t = h->bk;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ t->fd->bk = t->bk;
+ t->bk->fd = t->fd;
+ }
+ delete t;
+}
+
+
+int <T>DLList::OK()
+{
+ int v = 1;
+ if (h != 0)
+ {
+ <T>DLListNode* 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;
+}
diff --git a/gnu/lib/libg++/include/gen/DLList.hP b/gnu/lib/libg++/include/gen/DLList.hP
new file mode 100644
index 00000000000..8d1a3f45d7b
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/DLList.hP
@@ -0,0 +1,157 @@
+// This may look like C code, but it is really -*- C++ -*-
+// WARNING: This file is obsolete. Use ../DLList.h, if you can.
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>DLList_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>DLList_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+#ifndef _<T>DLListNode_h
+#define _<T>DLListNode_h 1
+
+struct <T>DLListNode
+{
+ <T>DLListNode* bk;
+ <T>DLListNode* fd;
+ <T> hd;
+ <T>DLListNode();
+ <T>DLListNode(const <T&> h,
+ <T>DLListNode* p = 0,
+ <T>DLListNode* n = 0);
+ ~<T>DLListNode();
+};
+
+inline <T>DLListNode::<T>DLListNode() {}
+
+inline <T>DLListNode::<T>DLListNode(const <T&> h, <T>DLListNode* p,
+ <T>DLListNode* n)
+ :bk(p), fd(n), hd(h) {}
+
+inline <T>DLListNode::~<T>DLListNode() {}
+
+typedef <T>DLListNode* <T>DLListNodePtr;
+
+#endif
+
+class <T>DLList
+{
+ friend class <T>DLListTrav;
+
+ <T>DLListNode* h;
+
+public:
+ <T>DLList();
+ <T>DLList(const <T>DLList& a);
+ ~<T>DLList();
+
+ <T>DLList& operator = (const <T>DLList& a);
+
+ int empty();
+ int length();
+
+ void clear();
+
+ Pix prepend(<T&> item);
+ Pix append(<T&> item);
+ void join(<T>DLList&);
+
+ <T>& front();
+ <T> remove_front();
+ void del_front();
+
+ <T>& rear();
+ <T> remove_rear();
+ void del_rear();
+
+ <T>& operator () (Pix p);
+ Pix first();
+ Pix last();
+ void next(Pix& p);
+ void prev(Pix& p);
+ int owns(Pix p);
+ Pix ins_after(Pix p, <T&> item);
+ Pix ins_before(Pix p, <T&> item);
+ void del(Pix& p, int dir = 1);
+ void del_after(Pix& p);
+
+ void error(const char* msg);
+ int OK();
+};
+
+
+inline <T>DLList::~<T>DLList()
+{
+ clear();
+}
+
+inline <T>DLList::<T>DLList()
+{
+ h = 0;
+}
+
+inline int <T>DLList::empty()
+{
+ return h == 0;
+}
+
+
+inline void <T>DLList::next(Pix& p)
+{
+ p = (p == 0 || p == h->bk)? 0 : Pix(((<T>DLListNode*)p)->fd);
+}
+
+inline void <T>DLList::prev(Pix& p)
+{
+ p = (p == 0 || p == h)? 0 : Pix(((<T>DLListNode*)p)->bk);
+}
+
+inline Pix <T>DLList::first()
+{
+ return Pix(h);
+}
+
+inline Pix <T>DLList::last()
+{
+ return (h == 0)? 0 : Pix(h->bk);
+}
+
+inline <T>& <T>DLList::operator () (Pix p)
+{
+ if (p == 0) error("null Pix");
+ return ((<T>DLListNode*)p)->hd;
+}
+
+inline <T>& <T>DLList::front()
+{
+ if (h == 0) error("front: empty list");
+ return h->hd;
+}
+
+inline <T>& <T>DLList::rear()
+{
+ if (h == 0) error("rear: empty list");
+ return h->bk->hd;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Deque.ccP b/gnu/lib/libg++/include/gen/Deque.ccP
new file mode 100644
index 00000000000..79a9b72c875
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Deque.ccP
@@ -0,0 +1,11 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.Deque.h"
+
+<T>Deque::~<T>Deque() {}
+
+void <T>Deque::error(const char* msg)
+{
+ (*lib_error_handler)("Deque", msg);
+}
diff --git a/gnu/lib/libg++/include/gen/Deque.hP b/gnu/lib/libg++/include/gen/Deque.hP
new file mode 100644
index 00000000000..35764321f35
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Deque.hP
@@ -0,0 +1,57 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>Deque_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Deque_h
+
+#include <builtin.h>
+
+#include "<T>.defs.h"
+
+class <T>Deque
+{
+public:
+ <T>Deque() { }
+ virtual ~<T>Deque();
+
+ virtual void push(<T&> item) = 0; // insert at front
+ virtual void enq(<T&> item) = 0; // insert at rear
+
+ virtual <T>& front() = 0;
+ virtual <T>& rear() = 0;
+
+ virtual <T> deq() = 0;
+ virtual void del_front() = 0;
+ virtual void del_rear() = 0;
+
+ virtual int empty() = 0;
+ virtual int full() = 0;
+ virtual int length() = 0;
+ virtual void clear() = 0;
+
+ virtual int OK() = 0;
+
+ void error(const char*);
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/FPQueue.ccP b/gnu/lib/libg++/include/gen/FPQueue.ccP
new file mode 100644
index 00000000000..a358cacb60e
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/FPQueue.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.FPQueue.h"
diff --git a/gnu/lib/libg++/include/gen/FPQueue.hP b/gnu/lib/libg++/include/gen/FPQueue.hP
new file mode 100644
index 00000000000..adf7e8d3159
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/FPQueue.hP
@@ -0,0 +1,112 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>FPQueue_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>FPQueue_h
+
+#include "<T>.FPlex.h"
+#include "<T>.Queue.h"
+
+class <T>FPQueue : public <T>Queue
+{
+ <T>FPlex p;
+
+public:
+ <T>FPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>FPQueue(const <T>FPQueue& q);
+ ~<T>FPQueue();
+
+ void operator = (const <T>FPQueue&);
+
+ void enq(<T&> item);
+ <T> deq();
+ <T>& front();
+ void del_front();
+
+ void clear();
+ int empty();
+ int full();
+ int length();
+
+ int OK();
+};
+
+inline <T>FPQueue::<T>FPQueue(int chunksize) : p(chunksize) {}
+inline <T>FPQueue::<T>FPQueue(const <T>FPQueue& q) : p(q.p) {}
+
+inline <T>FPQueue::~<T>FPQueue() {}
+
+inline void <T>FPQueue::enq(<T&>item)
+{
+ p.add_high(item);
+}
+
+inline <T> <T>FPQueue::deq()
+{
+ <T> res = p.low_element();
+ p.del_low();
+ return res;
+}
+
+inline <T>& <T>FPQueue::front()
+{
+ return p.low_element();
+}
+
+
+inline void <T>FPQueue::del_front()
+{
+ p.del_low();
+}
+
+inline void <T>FPQueue::operator =(const <T>FPQueue& s)
+{
+ p = s.p;
+}
+
+inline int <T>FPQueue::empty()
+{
+ return p.empty();
+}
+
+inline int <T>FPQueue::full()
+{
+ return p.full();
+}
+
+inline int <T>FPQueue::length()
+{
+ return p.length();
+}
+
+inline int <T>FPQueue::OK()
+{
+ return p.OK();
+}
+
+inline void <T>FPQueue::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/FPStack.ccP b/gnu/lib/libg++/include/gen/FPStack.ccP
new file mode 100644
index 00000000000..954991193b7
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/FPStack.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.FPStack.h"
diff --git a/gnu/lib/libg++/include/gen/FPStack.hP b/gnu/lib/libg++/include/gen/FPStack.hP
new file mode 100644
index 00000000000..de1310465f9
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/FPStack.hP
@@ -0,0 +1,114 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>FPStack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>FPStack_h
+
+#include "<T>.FPlex.h"
+#include "<T>.Stack.h"
+
+class <T>FPStack : public <T>Stack
+{
+ <T>FPlex p;
+
+public:
+ <T>FPStack(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>FPStack(const <T>FPStack& s);
+ ~<T>FPStack();
+
+ void operator = (const <T>FPStack&);
+
+ void push(<T&> item);
+ <T> pop();
+ <T>& top();
+ void del_top();
+
+ int empty();
+ int full();
+ int length();
+
+ void clear();
+
+ int OK();
+
+};
+
+
+inline <T>FPStack::<T>FPStack(int chunksize) : p(chunksize) {}
+inline <T>FPStack::<T>FPStack(const <T>FPStack& s) : p(s.p) {}
+
+inline <T>FPStack::~<T>FPStack() {}
+
+inline void <T>FPStack::push(<T&>item)
+{
+ p.add_high(item);
+}
+
+inline <T> <T>FPStack::pop()
+{
+ <T> res = p.high_element();
+ p.del_high();
+ return res;
+}
+
+inline <T>& <T>FPStack::top()
+{
+ return p.high_element();
+}
+
+inline void <T>FPStack::del_top()
+{
+ p.del_high();
+}
+
+inline void <T>FPStack::operator =(const <T>FPStack& s)
+{
+ p = s.p;
+}
+
+inline int <T>FPStack::empty()
+{
+ return p.empty();
+}
+
+inline int <T>FPStack::full()
+{
+ return p.full();
+}
+
+inline int <T>FPStack::length()
+{
+ return p.length();
+}
+
+inline int <T>FPStack::OK()
+{
+ return p.OK();
+}
+
+inline void <T>FPStack::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/FPlex.ccP b/gnu/lib/libg++/include/gen/FPlex.ccP
new file mode 100644
index 00000000000..980870d8675
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/FPlex.ccP
@@ -0,0 +1,167 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.FPlex.h"
+
+
+<T>FPlex:: <T>FPlex()
+{
+ lo = fnc = 0;
+ csize = DEFAULT_INITIAL_CAPACITY;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, lo, lo, fnc, csize);
+}
+
+<T>FPlex:: <T>FPlex(int maxsize)
+{
+ if (maxsize == 0) error("invalid constructor specification");
+ lo = fnc = 0;
+ if (maxsize > 0)
+ {
+ csize = maxsize;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, lo, lo, fnc, csize);
+ }
+ else
+ {
+ csize = -maxsize;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, maxsize, lo, fnc, fnc);
+ }
+}
+
+
+<T>FPlex:: <T>FPlex(int l, int maxsize)
+{
+ if (maxsize == 0) error("invalid constructor specification");
+ lo = fnc = l;
+ if (maxsize > 0)
+ {
+ csize = maxsize;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, lo, lo, fnc, csize+lo);
+ }
+ else
+ {
+ csize = -maxsize;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, maxsize+lo, lo, fnc, fnc);
+ }
+}
+
+<T>FPlex:: <T>FPlex(int l, int hi, const <T&> initval, int maxsize)
+{
+ lo = l;
+ fnc = hi + 1;
+ if (maxsize >= 0)
+ {
+ csize = maxsize;
+ if (csize < fnc - lo)
+ csize = fnc - lo;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, lo, lo, fnc, csize);
+ }
+ else
+ {
+ csize = -maxsize;
+ if (csize < fnc - lo)
+ csize = fnc - lo;
+ <T>* data = new <T>[csize];
+ hd = new <T>IChunk(data, -csize, lo, fnc, fnc);
+ }
+ fill(initval);
+}
+
+<T>FPlex::<T>FPlex(const <T>FPlex& a)
+{
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = fnc - lo;
+ if (csize < a.csize) csize = a.csize;
+ <T>* data = new <T> [csize];
+ hd = new <T>IChunk(data, lo, lo, fnc, lo+csize);
+ for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
+}
+
+void <T>FPlex::operator= (const <T>FPlex& a)
+{
+ if (&a != this)
+ {
+ del_chunk(hd);
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = fnc - lo;
+ if (csize < a.csize) csize = a.csize;
+ <T>* data = new <T> [csize];
+ hd = new <T>IChunk(data, lo, lo, fnc, lo+csize);
+ for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
+ }
+}
+
+
+void <T>FPlex::reverse()
+{
+ <T> tmp;
+ int l = lo;
+ int h = fnc - 1;
+ while (l < h)
+ {
+ tmp = (*this)[l];
+ (*this)[l] = (*this)[h];
+ (*this)[h] = tmp;
+ next(l);
+ prev(h);
+ }
+}
+
+void <T>FPlex::fill(const <T&> x)
+{
+ for (int i = lo; i < fnc; ++i) (*this)[i] = x;
+}
+
+void <T>FPlex::fill(const <T&> x, int lo, int hi)
+{
+ for (int i = lo; i <= hi; ++i) (*this)[i] = x;
+}
+
+void <T>FPlex::clear()
+{
+ if (fnc != lo)
+ {
+ hd->clear(lo);
+ fnc = lo;
+ }
+}
+
+int <T>FPlex::OK () const
+{
+ int v = hd != 0; // hd exists
+ v &= hd-><T>IChunk::OK(); // and is OK
+ v &= fnc - lo <= hd->size(); // and has enough space
+ v &= lo <= fnc; // plex indices consistent
+ v &= lo == hd->low_index(); // and match those
+ v &= fnc == hd->fence_index(); // of chunk
+ v &= one_chunk(); // and only one chunk
+ if (!v) error("invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/include/gen/FPlex.hP b/gnu/lib/libg++/include/gen/FPlex.hP
new file mode 100644
index 00000000000..03cf96d20ba
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/FPlex.hP
@@ -0,0 +1,253 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>FPlex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>FPlex_h 1
+
+#include "<T>.Plex.h"
+
+class <T>FPlex : public <T>Plex
+{
+public:
+ <T>FPlex(); // set low = 0;
+ // fence = 0;
+ // csize = default
+
+ <T>FPlex(int maxsize); // low = 0;
+ // fence = 0;
+ // csize = maxsize
+
+ <T>FPlex(int lo, // low = lo;
+ int maxsize); // fence=lo
+ // csize = maxsize
+
+ <T>FPlex(int lo, // low = lo
+ int hi, // fence = hi+1
+ const <T&> initval,// fill with initval,
+ int maxsize = 0); // csize = maxsize
+ // or fence - lo if 0
+
+ <T>FPlex(const <T>FPlex&); // X(X&)
+
+ inline ~<T>FPlex();
+
+ void operator= (const <T>FPlex&);
+
+// virtuals
+
+ inline <T>& high_element ();
+ inline <T>& low_element ();
+
+ inline const <T>& high_element () const;
+ inline const <T>& low_element () const;
+
+ inline Pix first() const;
+ inline Pix last() const;
+ inline void prev(Pix& ptr) const;
+ inline void next(Pix& ptr) const;
+ inline int owns(Pix p) const;
+ inline <T>& operator () (Pix p);
+ inline const <T>& operator () (Pix p) const;
+
+ inline int low() const;
+ inline int high() const;
+ inline int valid(int idx) const;
+ inline void prev(int& idx) const;
+ inline void next(int& x) const;
+ inline <T>& operator [] (int index);
+ inline const <T>& operator [] (int index) const;
+
+ inline int Pix_to_index(Pix p) const;
+ inline Pix index_to_Pix(int idx) const;
+
+ inline int can_add_high() const;
+ inline int can_add_low() const;
+ inline int full() const;
+
+ inline int add_high(const <T&> elem);
+ inline int del_high ();
+ inline int add_low (const <T&> elem);
+ inline int del_low ();
+
+ void fill(const <T&> x);
+ void fill(const <T&> x, int from, int to);
+ void clear();
+ void reverse();
+
+ int OK () const;
+};
+
+
+inline int <T>FPlex::valid (int idx) const
+{
+ return idx >= lo && idx < fnc;
+}
+
+inline int <T>FPlex::low() const
+{
+ return lo;
+}
+
+inline int <T>FPlex::high() const
+{
+ return fnc - 1;
+}
+
+inline Pix <T>FPlex::first() const
+{
+ return (Pix)(hd-><T>IChunk::first_pointer());
+}
+
+inline void <T>FPlex::prev(Pix& p) const
+{
+ p = Pix(hd-><T>IChunk::pred((<T>*) p));
+}
+
+inline void <T>FPlex::next(Pix& p) const
+{
+ p = Pix(hd-><T>IChunk::succ((<T>*) p));
+}
+
+inline Pix <T>FPlex::last() const
+{
+ return Pix(hd-><T>IChunk::last_pointer());
+}
+
+inline int <T>FPlex::full () const
+{
+ return fnc - lo == csize;
+}
+
+inline void <T>FPlex::prev(int& idx) const
+{
+ --idx;
+}
+
+inline void <T>FPlex::next(int& idx) const
+{
+ ++idx;
+}
+
+inline <T>& <T>FPlex:: operator [] (int idx)
+{
+ if (idx < lo || idx >= fnc) index_error();
+ return *(hd->pointer_to(idx));
+}
+
+inline <T>& <T>FPlex:: operator () (Pix p)
+{
+ return *((<T>*)p);
+}
+
+inline <T>& <T>FPlex::low_element ()
+{
+ if (empty()) index_error();
+ return *(hd->pointer_to(lo));
+}
+
+inline <T>& <T>FPlex::high_element ()
+{
+ if (empty()) index_error();
+ return *(hd->pointer_to(fnc - 1));
+}
+
+inline const <T>& <T>FPlex:: operator [] (int idx) const
+{
+ if (idx < lo || idx >= fnc) index_error();
+ return *(hd->pointer_to(idx));
+}
+
+inline const <T>& <T>FPlex:: operator () (Pix p) const
+{
+ return *((const <T>*)p);
+}
+
+inline const <T>& <T>FPlex::low_element () const
+{
+ if (empty()) index_error();
+ return *(hd->pointer_to(lo));
+}
+
+inline const <T>& <T>FPlex::high_element () const
+{
+ if (empty()) index_error();
+ return *(hd->pointer_to(fnc - 1));
+}
+
+inline int <T>FPlex::can_add_high() const
+{
+ return hd->can_grow_high();
+}
+
+inline int <T>FPlex::can_add_low() const
+{
+ return hd->can_grow_low();
+}
+
+inline int <T>FPlex::add_high(const <T&> elem)
+{
+ if (!can_add_high()) full_error();
+ *((hd-><T>IChunk::grow_high())) = elem;
+ return fnc++;
+}
+
+inline int <T>FPlex::del_high ()
+{
+ if (empty()) empty_error();
+ hd-><T>IChunk::shrink_high();
+ return --fnc - 1;
+}
+
+inline int <T>FPlex::add_low (const <T&> elem)
+{
+ if (!can_add_low()) full_error();
+ *((hd-><T>IChunk::grow_low())) = elem;
+ return --lo;
+}
+
+inline int <T>FPlex::del_low ()
+{
+ if (empty()) empty_error();
+ hd-><T>IChunk::shrink_low();
+ return ++lo;
+}
+
+inline int <T>FPlex::owns (Pix p) const
+{
+ return hd->actual_pointer((<T>*)p);
+}
+
+inline int <T>FPlex::Pix_to_index(Pix p) const
+{
+ if (!hd->actual_pointer((const <T>*)p)) index_error();
+ return hd->index_of((const <T>*)p);
+}
+
+inline Pix <T>FPlex::index_to_Pix(int idx) const
+{
+ if (idx < lo || idx >= fnc) index_error();
+ return Pix(hd->pointer_to(idx));
+}
+
+inline <T>FPlex::~<T>FPlex() {}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/List.ccP b/gnu/lib/libg++/include/gen/List.ccP
new file mode 100644
index 00000000000..f672cf2db63
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/List.ccP
@@ -0,0 +1,972 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include "<T>.List.h"
+
+<T>ListNode Nil<T>ListNode;
+
+class init_Nil<T>ListNode
+{
+public:
+ init_Nil<T>ListNode()
+ {
+ Nil<T>ListNode.tl = &Nil<T>ListNode;
+ Nil<T>ListNode.ref = -1;
+ }
+};
+
+static init_Nil<T>ListNode Nil<T>ListNode_initializer;
+
+<T>List& <T>List::operator = (const <T>List& a)
+{
+ reference(a.P);
+ dereference(P);
+ P = a.P;
+ return *this;
+}
+
+<T> <T>List::pop()
+{
+ <T> res = P->hd;
+ <T>ListNode* tail = P->tl;
+ reference(tail);
+ dereference(P);
+ P = tail;
+ return res;
+}
+
+void <T>List::set_tail(<T>List& a)
+{
+ reference(a.P);
+ dereference(P->tl);
+ P->tl = a.P;
+}
+
+<T>List <T>List::nth(int n)
+{
+ <T>ListNode* p;
+ for ( p = P; n-- > 0; p = p->tl);
+ reference(p);
+ return <T>List(p);
+}
+
+<T>List <T>List::last()
+{
+ <T>ListNode* p = P;
+ if (p != &Nil<T>ListNode) while (p->tl != &Nil<T>ListNode) p = p->tl;
+ reference(p);
+ return <T>List(p);
+}
+
+void <T>List::append(<T>List& l)
+{
+ <T>ListNode* p = P;
+ <T>ListNode* a = l.P;
+ reference(a);
+ if (p != &Nil<T>ListNode)
+ {
+ while (p->tl != &Nil<T>ListNode) p = p->tl;
+ p->tl = a;
+ }
+ else
+ P = a;
+}
+
+int <T>List::length()
+{
+ int l = 0;
+ for (<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl) ++l;
+ return l;
+}
+
+<T>& <T>List::operator [] (int n)
+{
+ <T>ListNode* p;
+ for ( p = P; n-- > 0; p = p->tl);
+ return (p->hd);
+}
+
+int operator == (const <T>List& x, const <T>List& y)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* b = y.P;
+
+ for (;;)
+ {
+ if (a == &Nil<T>ListNode)
+ return b == &Nil<T>ListNode;
+ else if (b == &Nil<T>ListNode)
+ return 0;
+ else if (<T>EQ(a->hd, b->hd))
+ {
+ a = a->tl;
+ b = b->tl;
+ }
+ else
+ return 0;
+ }
+}
+
+
+void <T>List::apply(<T>Procedure f)
+{
+ for(<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl)
+ (*f)((p->hd));
+}
+
+void <T>List::subst(<T&> old, <T&> repl)
+{
+ for(<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl)
+ if (<T>EQ(p->hd, old))
+ p->hd = repl;
+}
+
+<T> <T>List::reduce(<T>Combiner f, <T&> base)
+{
+ <T> r = base;
+ for(<T>ListNode* p = P; p != &Nil<T>ListNode; p = p->tl)
+ r = (*f)(r, (p->hd));
+ return r;
+}
+
+int <T>List::position(<T&> targ)
+{
+ int l = 0;
+ <T>ListNode* p = P;
+ for (;;)
+ {
+ if (p == &Nil<T>ListNode)
+ return -1;
+ else if (<T>EQ(p->hd, targ))
+ return l;
+ else
+ {
+ ++l;
+ p = p->tl;
+ }
+ }
+}
+
+int <T>List::contains(<T&> targ)
+{
+ <T>ListNode* p = P;
+ for (;;)
+ {
+ if (p == &Nil<T>ListNode)
+ return 0;
+ else if (<T>EQ(p->hd, targ))
+ return 1;
+ else
+ p = p->tl;
+ }
+}
+
+<T>List <T>List::find(<T&> targ)
+{
+ <T>ListNode* p = P;
+ while (p != &Nil<T>ListNode && !<T>EQ(p->hd, targ))
+ p=p->tl;
+ reference(p);
+ return <T>List(p);
+}
+
+Pix <T>List::seek(<T&> targ) const
+{
+ const <T>ListNode* p = P;
+ for (;;)
+ {
+ if (p == &Nil<T>ListNode)
+ return 0;
+ else if (<T>EQ(p->hd, targ))
+ return Pix(p);
+ else
+ p = p->tl;
+ }
+}
+
+int <T>List::owns(Pix i)
+{
+ <T>ListNode* p = P;
+ for (;;)
+ {
+ if (p == &Nil<T>ListNode)
+ return 0;
+ else if (Pix(p) == i)
+ return 1;
+ else
+ p = p->tl;
+ }
+}
+
+<T>List <T>List::find(<T>List& target)
+{
+ <T>ListNode* targ = target.P;
+ if (targ == &Nil<T>ListNode)
+ return <T>List(targ);
+
+ <T>ListNode* p = P;
+ while (p != &Nil<T>ListNode)
+ {
+ if (<T>EQ(p->hd, targ->hd))
+ {
+ <T>ListNode* a = p->tl;
+ <T>ListNode* t = targ->tl;
+ for(;;)
+ {
+ if (t == &Nil<T>ListNode)
+ {
+ reference(p);
+ return <T>List(p);
+ }
+ else if (a == &Nil<T>ListNode || !<T>EQ(a->hd, t->hd))
+ break;
+ else
+ {
+ a = a->tl;
+ t = t->tl;
+ }
+ }
+ }
+ p = p->tl;
+ }
+ return <T>List(&Nil<T>ListNode);
+}
+
+int <T>List::contains(<T>List& target)
+{
+ <T>ListNode* targ = target.P;
+ if (targ == &Nil<T>ListNode)
+ return 0;
+
+ <T>ListNode* p = P;
+ while (p != &Nil<T>ListNode)
+ {
+ if (<T>EQ(p->hd, targ->hd))
+ {
+ <T>ListNode* a = p->tl;
+ <T>ListNode* t = targ->tl;
+ for(;;)
+ {
+ if (t == &Nil<T>ListNode)
+ return 1;
+ else if (a == &Nil<T>ListNode || !<T>EQ(a->hd, t->hd))
+ break;
+ else
+ {
+ a = a->tl;
+ t = t->tl;
+ }
+ }
+ }
+ p = p->tl;
+ }
+ return 0;
+}
+
+void <T>List::del(<T&> targ)
+{
+ <T>ListNode* h = P;
+ // Former bug: targ can be a reference to a element in this list
+ // So do not dereference a element if targ is the element,
+ // until targ is no longer needed, as dereferencing it may destroy it.
+ <T>ListNode* to_be_dereferenced = 0;
+
+ for (;;)
+ {
+ if (h == &Nil<T>ListNode)
+ {
+ P = h;
+ if (to_be_dereferenced)
+ dereference(to_be_dereferenced);
+ return;
+ }
+ else if (<T>EQ(h->hd, targ))
+ {
+ <T>ListNode* nxt = h->tl;
+ reference(nxt);
+ if ((&targ == &h->hd) && (to_be_dereferenced == 0))
+ to_be_dereferenced = h;
+ else
+ dereference(h);
+ h = nxt;
+ }
+ else
+ break;
+ }
+
+ <T>ListNode* trail = h;
+ <T>ListNode* p = h->tl;
+ while (p != &Nil<T>ListNode)
+ {
+ if (<T>EQ(p->hd, targ))
+ {
+ <T>ListNode* nxt = p->tl;
+ reference(nxt);
+ if ((&targ == &p->hd) && (to_be_dereferenced == 0))
+ to_be_dereferenced = p;
+ else
+ dereference(p);
+ trail->tl = nxt;
+ p = nxt;
+ }
+ else
+ {
+ trail = p;
+ p = p->tl;
+ }
+ }
+ P = h;
+ if (to_be_dereferenced)
+ dereference(to_be_dereferenced);
+}
+
+void <T>List::del(<T>Predicate f)
+{
+ <T>ListNode* h = P;
+ for (;;)
+ {
+ if (h == &Nil<T>ListNode)
+ {
+ P = h;
+ return;
+ }
+ else if ((*f)(h->hd))
+ {
+ <T>ListNode* nxt = h->tl;
+ reference(nxt);
+ dereference(h);
+ h = nxt;
+ }
+ else
+ break;
+ }
+
+ <T>ListNode* trail = h;
+ <T>ListNode* p = h->tl;
+ while (p != &Nil<T>ListNode)
+ {
+ if ((*f)(p->hd))
+ {
+ <T>ListNode* nxt = p->tl;
+ reference(nxt);
+ dereference(p);
+ trail->tl = nxt;
+ p = nxt;
+ }
+ else
+ {
+ trail = p;
+ p = p->tl;
+ }
+ }
+ P = h;
+}
+
+void <T>List::select(<T>Predicate f)
+{
+ <T>ListNode* h = P;
+ for (;;)
+ {
+ if (h == &Nil<T>ListNode)
+ {
+ P = h;
+ return;
+ }
+ else if (!(*f)(h->hd))
+ {
+ <T>ListNode* nxt = h->tl;
+ reference(nxt);
+ dereference(h);
+ h = nxt;
+ }
+ else
+ break;
+ }
+ <T>ListNode* trail = h;
+ <T>ListNode* p = h->tl;
+ while (p != &Nil<T>ListNode)
+ {
+ if (!(*f)(p->hd))
+ {
+ <T>ListNode* nxt = p->tl;
+ reference(nxt);
+ dereference(p);
+ trail->tl = nxt;
+ p = nxt;
+ }
+ else
+ {
+ trail = p;
+ p = p->tl;
+ }
+ }
+ P = h;
+}
+
+void <T>List::reverse()
+{
+ <T>ListNode* l = &Nil<T>ListNode;
+ <T>ListNode* p = P;
+ while (p != &Nil<T>ListNode)
+ {
+ <T>ListNode* nxt = p->tl;
+ p->tl = l;
+ l = p;
+ p = nxt;
+ }
+ P = l;
+}
+
+
+<T>List copy(const <T>List& x)
+{
+ const <T>ListNode* a = x.P;
+ if (a == &Nil<T>ListNode)
+ return <T>List(&Nil<T>ListNode);
+ else
+ {
+ <T>ListNode* h = new<T>ListNode(a->hd);
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+}
+
+
+<T>List subst(<T&> old, <T&> repl, <T>List& x)
+{
+ <T>ListNode* a = x.P;
+ if (a == &Nil<T>ListNode)
+ return <T>List(a);
+ else
+ {
+ <T>ListNode* h = new <T>ListNode;
+ h->ref = 1;
+ if (<T>EQ(a->hd, old))
+ h->hd = repl;
+ else
+ h->hd = a->hd;
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ <T>ListNode* n = new <T>ListNode;
+ n->ref = 1;
+ if (<T>EQ(a->hd, old))
+ n->hd = repl;
+ else
+ n->hd = a->hd;
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+}
+
+<T>List combine(<T>Combiner f, <T>List& x, <T>List& y)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* b = y.P;
+ if (a == &Nil<T>ListNode || b == &Nil<T>ListNode)
+ return <T>List(&Nil<T>ListNode);
+ else
+ {
+ <T>ListNode* h = new<T>ListNode((*f)(a->hd, b->hd));
+ <T>ListNode* trail = h;
+ a = a->tl;
+ b = b->tl;
+ while (a != &Nil<T>ListNode && b != &Nil<T>ListNode)
+ {
+ <T>ListNode* n = new<T>ListNode((*f)(a->hd, b->hd));
+ trail->tl = n;
+ trail = n;
+ a = a->tl;
+ b = b->tl;
+ }
+ trail->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+}
+
+<T>List reverse(<T>List& x)
+{
+ <T>ListNode* a = x.P;
+ if (a == &Nil<T>ListNode)
+ return <T>List(a);
+ else
+ {
+ <T>ListNode* l = new<T>ListNode(a->hd);
+ l->tl = &Nil<T>ListNode;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ n->tl = l;
+ l = n;
+ }
+ return <T>List(l);
+ }
+}
+
+<T>List append(<T>List& x, <T>List& y)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* b = y.P;
+ reference(b);
+ if (a != &Nil<T>ListNode)
+ {
+ <T>ListNode* h = new<T>ListNode(a->hd);
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = b;
+ return <T>List(h);
+ }
+ else
+ return <T>List(b);
+}
+
+void <T>List::prepend(<T>List& y)
+{
+ <T>ListNode* b = y.P;
+ if (b != &Nil<T>ListNode)
+ {
+ <T>ListNode* h = new<T>ListNode(b->hd);
+ <T>ListNode* trail = h;
+ for(b = b->tl; b != &Nil<T>ListNode; b = b->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(b->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = P;
+ P = h;
+ }
+}
+
+<T>List concat(<T>List& x, <T>List& y)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* b = y.P;
+ if (a != &Nil<T>ListNode)
+ {
+ <T>ListNode* h = new<T>ListNode(a->hd);
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ trail->tl = n;
+ trail = n;
+ };
+ for(;b != &Nil<T>ListNode; b = b->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(b->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+ else if (b != &Nil<T>ListNode)
+ {
+ <T>ListNode* h = new<T>ListNode(b->hd);
+ <T>ListNode* trail = h;
+ for(b = b->tl; b != &Nil<T>ListNode; b = b->tl)
+ {
+ <T>ListNode* n = new<T>ListNode(b->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+ else
+ return <T>List(&Nil<T>ListNode);
+}
+
+<T>List select(<T>Predicate f, <T>List& x)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* h = &Nil<T>ListNode;
+ while (a != &Nil<T>ListNode)
+ {
+ if ((*f)(a->hd))
+ {
+ h = new<T>ListNode(a->hd);
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ if ((*f)(a->hd))
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ }
+ trail->tl = &Nil<T>ListNode;
+ break;
+ }
+ else
+ a = a->tl;
+ }
+ return <T>List(h);
+}
+
+<T>List remove(<T>Predicate f, <T>List& x)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* h = &Nil<T>ListNode;
+ while (a != &Nil<T>ListNode)
+ {
+ if (!(*f)(a->hd))
+ {
+ h = new<T>ListNode(a->hd);
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ if (!(*f)(a->hd))
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ }
+ trail->tl = &Nil<T>ListNode;
+ break;
+ }
+ else
+ a = a->tl;
+ }
+ return <T>List(h);
+}
+
+<T>List remove(<T&> targ, <T>List& x)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* h = &Nil<T>ListNode;
+ while (a != &Nil<T>ListNode)
+ {
+ if (!(<T>EQ(a->hd, targ)))
+ {
+ h = new<T>ListNode(a->hd);
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ if (!<T>EQ(a->hd, targ))
+ {
+ <T>ListNode* n = new<T>ListNode(a->hd);
+ trail->tl = n;
+ trail = n;
+ }
+ }
+ trail->tl = &Nil<T>ListNode;
+ break;
+ }
+ else
+ a = a->tl;
+ }
+ return <T>List(h);
+}
+
+<T>List map(<T>Mapper f, <T>List& x)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* h = &Nil<T>ListNode;
+ if (a != &Nil<T>ListNode)
+ {
+ h = new<T>ListNode((*f)(a->hd));
+ <T>ListNode* trail = h;
+ for(a = a->tl; a != &Nil<T>ListNode; a = a->tl)
+ {
+ <T>ListNode* n = new<T>ListNode((*f)(a->hd));
+ trail->tl = n;
+ trail = n;
+ }
+ trail->tl = &Nil<T>ListNode;
+ }
+ return <T>List(h);
+}
+
+
+<T>List merge(<T>List& x, <T>List& y, <T>Comparator f)
+{
+ <T>ListNode* a = x.P;
+ <T>ListNode* b = y.P;
+
+ if (a == &Nil<T>ListNode)
+ {
+ if (b == &Nil<T>ListNode)
+ return <T>List(&Nil<T>ListNode);
+ else
+ return copy(y);
+ }
+ else if (b == &Nil<T>ListNode)
+ return copy(x);
+
+ <T>ListNode* h = new <T>ListNode;
+ h->ref = 1;
+ if ((*f)(a->hd, b->hd) <= 0)
+ {
+ h->hd = a->hd;
+ a = a->tl;
+ }
+ else
+ {
+ h->hd = b->hd;
+ b = b->tl;
+ }
+
+ <T>ListNode* r = h;
+
+ for(;;)
+ {
+ if (a == &Nil<T>ListNode)
+ {
+ while (b != &Nil<T>ListNode)
+ {
+ <T>ListNode* n = new <T>ListNode;
+ n->ref = 1;
+ n->hd = b->hd;
+ r->tl = n;
+ r = n;
+ b = b->tl;
+ }
+ r->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+ else if (b == &Nil<T>ListNode)
+ {
+ while (a != &Nil<T>ListNode)
+ {
+ <T>ListNode* n = new <T>ListNode;
+ n->ref = 1;
+ n->hd = a->hd;
+ r->tl = n;
+ r = n;
+ a = a->tl;
+ }
+ r->tl = &Nil<T>ListNode;
+ return <T>List(h);
+ }
+ else if ((*f)(a->hd, b->hd) <= 0)
+ {
+ <T>ListNode* n = new <T>ListNode;
+ n->ref = 1;
+ n->hd = a->hd;
+ r->tl = n;
+ r = n;
+ a = a->tl;
+ }
+ else
+ {
+ <T>ListNode* n = new <T>ListNode;
+ n->ref = 1;
+ n->hd = b->hd;
+ r->tl = n;
+ r = n;
+ b = b->tl;
+ }
+ }
+}
+
+void <T>List::sort(<T>Comparator f)
+{
+ // strategy: place runs in queue, merge runs until done
+ // This is often very fast
+
+ if (P == &Nil<T>ListNode || P->tl == &Nil<T>ListNode)
+ return;
+
+ int qlen = 250; // guess a good queue size, realloc if necessary
+
+ <T>ListNode** queue = (<T>ListNode**)malloc(qlen * sizeof(<T>ListNode*));
+
+ <T>ListNode* h = P;
+ <T>ListNode* a = h;
+ <T>ListNode* b = a->tl;
+ int qin = 0;
+
+ while (b != &Nil<T>ListNode)
+ {
+ if ((*f)(a->hd, b->hd) > 0)
+ {
+ if (h == a) // minor optimization: ensure runlen >= 2
+ {
+ h = b;
+ a->tl = b->tl;
+ b->tl = a;
+ b = a->tl;
+ }
+ else
+ {
+ if (qin >= qlen)
+ {
+ qlen *= 2;
+ queue = (<T>ListNode**)realloc(queue, qlen * sizeof(<T>ListNode*));
+ }
+ queue[qin++] = h;
+ a->tl = &Nil<T>ListNode;
+ h = a = b;
+ b = b->tl;
+ }
+ }
+ else
+ {
+ a = b;
+ b = b->tl;
+ }
+ }
+
+ int count = qin;
+ queue[qin] = h;
+ if (++qin >= qlen) qin = 0;
+ int qout = 0;
+
+ while (count-- > 0)
+ {
+ a = queue[qout];
+ if (++qout >= qlen) qout = 0;
+ b = queue[qout];
+ if (++qout >= qlen) qout = 0;
+
+ if ((*f)(a->hd, b->hd) <= 0)
+ {
+ h = a;
+ a = a->tl;
+ }
+ else
+ {
+ h = b;
+ b = b->tl;
+ }
+ queue[qin] = h;
+ if (++qin >= qlen) qin = 0;
+
+ for (;;)
+ {
+ if (a == &Nil<T>ListNode)
+ {
+ h->tl = b;
+ break;
+ }
+ else if (b == &Nil<T>ListNode)
+ {
+ h->tl = a;
+ break;
+ }
+ else if ((*f)(a->hd, b->hd) <= 0)
+ {
+ h->tl = a;
+ h = a;
+ a = a->tl;
+ }
+ else
+ {
+ h->tl = b;
+ h = b;
+ b = b->tl;
+ }
+ }
+ }
+ P = queue[qout];
+ free(queue);
+}
+
+int <T>List::list_length()
+{
+ <T>ListNode* fast = P;
+ if (fast == &Nil<T>ListNode)
+ return 0;
+
+ <T>ListNode* slow = fast->tl;
+ if (slow == &Nil<T>ListNode)
+ return 1;
+
+ fast = slow->tl;
+ int n = 2;
+
+ for (;;)
+ {
+ if (fast == &Nil<T>ListNode)
+ return n;
+ else if (fast->tl == &Nil<T>ListNode)
+ return n+1;
+ else if (fast == slow)
+ return -1;
+ else
+ {
+ n += 2;
+ fast = fast->tl->tl;
+ slow = slow->tl;
+ }
+ }
+}
+
+void <T>List::error(const char* msg)
+{
+ (*lib_error_handler)("List", msg);
+}
+
+int <T>List::OK()
+{
+ int v = P != 0; // have a node
+ // check that all nodes OK, even if circular:
+
+ <T>ListNode* fast = P;
+ if (fast != &Nil<T>ListNode)
+ {
+ v &= fast->ref != 0;
+ <T>ListNode* slow = fast->tl;
+ v &= slow->ref != 0;
+ if (v && slow != &Nil<T>ListNode)
+ {
+ fast = slow->tl;
+ v &= fast->ref != 0;
+ while (v)
+ {
+ if (fast == &Nil<T>ListNode)
+ break;
+ else if (fast->tl == &Nil<T>ListNode)
+ break;
+ else if (fast == slow)
+ break;
+ else
+ {
+ v &= fast->ref != 0 && slow->ref != 0;
+ fast = fast->tl->tl;
+ slow = slow->tl;
+ }
+ }
+ }
+ }
+ if (!v) error ("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/List.hP b/gnu/lib/libg++/include/gen/List.hP
new file mode 100644
index 00000000000..4551e3e47ef
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/List.hP
@@ -0,0 +1,279 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>List_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>List_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+#ifndef _<T>_typedefs
+#define _<T>_typedefs 1
+typedef void (*<T>Procedure)(<T&>);
+typedef <T> (*<T>Mapper)(<T&>);
+typedef <T> (*<T>Combiner)(<T&>, <T&>);
+typedef int (*<T>Predicate)(<T&>);
+typedef int (*<T>Comparator)(<T&>, <T&>);
+#endif
+
+struct <T>ListNode
+{
+ <T>ListNode* tl;
+ short ref;
+ <T> hd;
+};
+
+extern <T>ListNode Nil<T>ListNode;
+
+class <T>List
+{
+protected:
+ <T>ListNode* P;
+
+ <T>List(<T>ListNode* p);
+public:
+ <T>List();
+ <T>List(<T&> head);
+ <T>List(<T&> head, const <T>List& tl);
+ <T>List(<T>List& a);
+ <T>List(Pix p);
+ ~<T>List();
+
+ <T>List& operator = (const <T>List& a);
+
+ int null();
+ int valid();
+ operator const void* ();
+ int operator ! ();
+
+ int length();
+ int list_length();
+
+ <T>& get();
+ <T>& head();
+ <T>& operator [] (int n);
+
+ <T>List nth(int n);
+ <T>List tail();
+ <T>List last();
+
+ <T>List find(<T&> targ);
+ <T>List find(<T>List& targ);
+ int contains(<T&> targ);
+ int contains(<T>List& targ);
+ int position(<T&> targ);
+
+ friend <T>List copy(const <T>List& a);
+ friend <T>List concat(<T>List& a, <T>List& b);
+ friend <T>List append(<T>List& a, <T>List& b);
+ friend <T>List map(<T>Mapper f, <T>List& a);
+ friend <T>List merge(<T>List& a, <T>List& b, <T>Comparator f);
+ friend <T>List combine(<T>Combiner f, <T>List& a, <T>List& b);
+ friend <T>List reverse(<T>List& a);
+ friend <T>List select(<T>Predicate f, <T>List& a);
+#undef remove
+ friend <T>List remove(<T&> targ, <T>List& a);
+ friend <T>List remove(<T>Predicate f, <T>List& a);
+ friend <T>List subst(<T&> old, <T&> repl, <T>List& a);
+
+ void push(<T&> x);
+ <T> pop();
+
+ void set_tail(<T>List& p);
+ void append(<T>List& p);
+ void prepend(<T>List& p);
+ void del(<T&> targ);
+ void del(<T>Predicate f);
+ void select(<T>Predicate f);
+ void subst(<T&> old, <T&> repl);
+ void reverse();
+ void sort(<T>Comparator f);
+
+ void apply(<T>Procedure f);
+ <T> reduce(<T>Combiner f, <T&> base);
+
+ friend int operator == (const <T>List& a, const <T>List& b);
+ friend inline int operator != (const <T>List& a, const <T>List& b);
+
+ Pix first();
+ void next(Pix& p);
+ Pix seek(<T&> item) const;
+ <T>& operator () (Pix p);
+ const <T>& operator () (Pix p) const;
+ int owns(Pix p);
+
+ void error(const char*);
+ int OK();
+};
+
+
+inline void reference(<T>ListNode* p)
+{
+ if (p->ref >= 0) ++p->ref;
+}
+
+inline void dereference(<T>ListNode* p)
+{
+ while (p->ref > 0 && --p->ref == 0)
+ {
+ <T>ListNode* n = p->tl;
+ delete(p);
+ p = n;
+ }
+}
+
+
+inline <T>ListNode* new<T>ListNode(const <T&> h)
+{
+ <T>ListNode* p = new <T>ListNode;
+ p->ref = 1;
+ p->hd = h;
+ return p;
+}
+
+inline <T>ListNode* new<T>ListNode(<T&> h, <T>ListNode* t)
+{
+ <T>ListNode* p = new <T>ListNode;
+ p->ref = 1;
+ p->hd = h;
+ p->tl = t;
+ return p;
+}
+
+
+inline <T>List::~<T>List()
+{
+ dereference(P);
+}
+
+inline <T>List::<T>List()
+{
+ P = &Nil<T>ListNode;
+}
+
+inline <T>List::<T>List(<T>ListNode* p)
+{
+ P = p;
+}
+
+inline <T>List::<T>List(<T&> head)
+{
+ P = new<T>ListNode(head);
+ P->tl = &Nil<T>ListNode;
+}
+
+inline <T>List::<T>List(<T&> head, const <T>List& tl)
+{
+ P = new<T>ListNode(head, tl.P);
+ reference(P->tl);
+}
+
+inline <T>List::<T>List(<T>List& a)
+{
+ reference(a.P);
+ P = a.P;
+}
+
+
+inline <T>& <T>List::get()
+{
+ return P->hd;
+}
+
+inline <T>& <T>List::head()
+{
+ return P->hd;
+}
+
+
+inline <T>List <T>List::tail()
+{
+ reference(P->tl);
+ return <T>List(P->tl);
+}
+
+
+
+inline int <T>List::null()
+{
+ return P == &Nil<T>ListNode;
+}
+
+inline int <T>List::valid()
+{
+ return P != &Nil<T>ListNode;
+}
+
+inline <T>List::operator const void* ()
+{
+ return (P == &Nil<T>ListNode)? 0 : this;
+}
+
+inline int <T>List::operator ! ()
+{
+ return (P == &Nil<T>ListNode);
+}
+
+
+inline void <T>List::push(<T&> head)
+{
+ <T>ListNode* oldp = P;
+ P = new<T>ListNode(head, oldp);
+}
+
+
+inline int operator != (const <T>List& x, const <T>List& y)
+{
+ return !(x == y);
+}
+
+inline Pix <T>List::first()
+{
+ return (P == &Nil<T>ListNode)? 0 : Pix(P);
+}
+
+inline <T>& <T>List::operator () (Pix p)
+{
+ return ((<T>ListNode*)p)->hd;
+}
+
+inline const <T>& <T>List::operator () (Pix p) const
+{
+ return ((const <T>ListNode*)p)->hd;
+}
+
+inline void <T>List::next(Pix& p)
+{
+ if (p != 0)
+ {
+ p = Pix(((<T>ListNode*)p)->tl);
+ if (p == &Nil<T>ListNode) p = 0;
+ }
+}
+
+inline <T>List::<T>List(Pix p)
+{
+ P = (<T>ListNode*)p;
+ reference(P);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/MPlex.ccP b/gnu/lib/libg++/include/gen/MPlex.ccP
new file mode 100644
index 00000000000..8c306b5e8a6
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/MPlex.ccP
@@ -0,0 +1,848 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.MPlex.h"
+
+// <T>MChunk support
+
+
+<T>MChunk::<T>MChunk(<T>* d,
+ int baseidx,
+ int lowidx,
+ int fenceidx,
+ int topidx)
+ : <T>IChunk(d, baseidx, lowidx, fenceidx, topidx)
+{
+ unused = fence - low;
+ unsigned msize = (top - base)/_MAP_BITS + 1;
+ map = (unsigned long *) (new long[msize]);
+ memset((void*)map, 0, msize * sizeof(long));
+}
+
+void <T>MChunk:: shrink_high ()
+{
+ if (fence <= low) empty_error();
+ --fence;
+ if (!valid(fence))
+ --unused;
+ else
+ free(fence);
+ reset_high();
+}
+
+void <T>MChunk:: shrink_low ()
+{
+ if (fence <= low) empty_error();
+ if (!valid(low))
+ --unused;
+ else
+ free(low);
+ ++low;
+ reset_low();
+}
+
+void <T>MChunk::clear(int lo)
+{
+ int s = top - base;
+ low = base = fence = lo;
+ top = base + s;
+ unused = 0;
+ memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long));
+}
+
+void <T>MChunk::cleardown(int hi)
+{
+ int s = top - base;
+ low = top = fence = hi;
+ base = top - s;
+ unused = 0;
+ memset((void*)map, 0, ((top - base)/_MAP_BITS + 1) * sizeof(long));
+}
+
+int <T>MChunk::del(int idx)
+{
+ if (idx < low || idx >= fence) index_error();
+ int v = valid(idx);
+ if (v)
+ {
+ free(idx);
+ ++unused;
+ }
+ return v;
+}
+
+
+int <T>MChunk::undel(int idx)
+{
+ if (idx < low || idx >= fence) index_error();
+ int v = valid(idx);
+ if (!v)
+ {
+ mark(idx);
+ --unused;
+ }
+ return v;
+}
+
+int <T>MChunk::unused_index() const
+{
+ if (unused_indices() == 0) index_error();
+ int slot;
+ if (low == base) // can traverse 32 slots at a time
+ {
+ int blk = 0;
+ while (map[blk] == ~0UL) ++blk;
+ slot = blk * _MAP_BITS + base;
+ }
+ else
+ slot = low;
+
+ while(valid(slot)) ++slot;
+ return slot;
+}
+
+int <T>MChunk::first_index() const
+{
+ if (empty()) return fence;
+ int slot;
+ if (low == base)
+ {
+ int blk = 0;
+ while (map[blk] == 0) ++blk;
+ slot = blk * _MAP_BITS + base;
+ }
+ else
+ slot = low;
+
+ while(!valid(slot)) ++slot;
+ return slot;
+}
+
+int <T>MChunk::last_index() const
+{
+ if (empty()) return low - 1;
+ int slot;
+ if (top == fence)
+ {
+ int blk = (top - base) / _MAP_BITS;
+ while (map[blk] == 0) --blk;
+ slot = blk * _MAP_BITS + base + _MAP_BITS - 1;
+ }
+ else
+ slot = fence - 1;
+
+ while(!valid(slot)) --slot;
+ return slot;
+}
+
+
+int <T>MChunk:: OK() const
+{
+ int v = data != 0; // have some data
+ v &= map != 0; // and a map
+ v &= base <= low; // ok, index-wise
+ v &= low <= fence;
+ v &= fence <= top;
+
+ v &= ((<T>MChunk*)(nxt->prev())) == this; // and links are OK
+ v &= ((<T>MChunk*)(prv->next())) == this;
+
+ int bitcount = 0; // and unused count correct
+ for (int i = low; i < fence; ++i) if (!valid(i)) ++bitcount;
+ v &= unused == bitcount;
+
+ if (!v) error("invariant failure");
+ return(v);
+}
+
+<T>* <T>MChunk::succ(<T>* p) const
+{
+ int i = ((int) p - (int) data) / sizeof(<T>) + base + 1;
+ if (p == 0 || i < low) return 0;
+ while (i < fence && !valid(i)) ++i;
+ if (i >= fence) return 0;
+ return pointer_to(i);
+}
+
+<T>* <T>MChunk::pred(<T>* p) const
+{
+ int i = ((int) p - (int) data) / sizeof(<T>) + base - 1;
+ if (p == 0 || i >= fence) return 0;
+ while (i >= low && !valid(i)) --i;
+ if (i < low) return 0;
+ return pointer_to(i);
+}
+
+<T>* <T>MChunk::first_pointer() const
+{
+ if (empty()) return 0;
+ int slot;
+ if (low == base)
+ {
+ int blk = 0;
+ while (map[blk] == 0) ++blk;
+ slot = blk * _MAP_BITS + base;
+ }
+ else
+ slot = low;
+
+ while(!valid(slot)) ++slot;
+ return pointer_to(slot);
+}
+
+<T>* <T>MChunk::last_pointer() const
+{
+ if (empty()) return 0;
+ int slot;
+ if (top == fence)
+ {
+ int blk = (top - base) / _MAP_BITS;
+ while (map[blk] == 0) --blk;
+ slot = blk * _MAP_BITS + base + _MAP_BITS - 1;
+ }
+ else
+ slot = fence - 1;
+
+ while(!valid(slot)) --slot;
+ return pointer_to(slot);
+}
+
+<T>MPlex:: <T>MPlex()
+{
+ unused = 0;
+ lo = fnc = 0;
+ csize = DEFAULT_INITIAL_CAPACITY;
+ <T>* data = new <T>[csize];
+ hd = ch = new <T>MChunk(data, lo, lo, fnc, lo+csize);
+}
+
+<T>MPlex:: <T>MPlex(int chunksize)
+{
+ if (chunksize == 0) error("invalid constructor specification");
+ unused = 0;
+ lo = fnc = 0;
+ if (chunksize > 0)
+ {
+ csize = chunksize;
+ <T>* data = new <T>[csize];
+ hd = ch = new <T>MChunk(data, lo, lo, fnc, csize);
+ }
+ else
+ {
+ csize = -chunksize;
+ <T>* data = new <T>[csize];
+ hd = ch = new <T>MChunk(data, chunksize, lo, fnc, fnc);
+ }
+}
+
+
+<T>MPlex:: <T>MPlex(int l, int chunksize)
+{
+ if (chunksize == 0) error("invalid constructor specification");
+ unused = 0;
+ lo = fnc = l;
+ if (chunksize > 0)
+ {
+ csize = chunksize;
+ <T>* data = new <T>[csize];
+ hd = ch = new <T>MChunk(data, lo, lo, fnc, csize+lo);
+ }
+ else
+ {
+ csize = -chunksize;
+ <T>* data = new <T>[csize];
+ hd = ch = new <T>MChunk(data, chunksize+lo, lo, fnc, fnc);
+ }
+}
+
+
+void <T>MPlex::make_initial_chunks(int up)
+{
+ int need = fnc - lo;
+ hd = 0;
+ if (up)
+ {
+ int l = lo;
+ do
+ {
+ int sz;
+ if (need >= csize)
+ sz = csize;
+ else
+ sz = need;
+ <T>* data = new <T> [csize];
+ <T>MChunk* h = new <T>MChunk(data, l, l, l+sz, l+csize);
+ if (hd != 0)
+ h->link_to_next(hd);
+ else
+ hd = h;
+ l += sz;
+ need -= sz;
+ } while (need > 0);
+ }
+ else
+ {
+ int hi = fnc;
+ do
+ {
+ int sz;
+ if (need >= csize)
+ sz = csize;
+ else
+ sz = need;
+ <T>* data = new <T> [csize];
+ <T>MChunk* h = new <T>MChunk(data, hi-csize, hi-sz, hi, hi);
+ if (hd != 0)
+ h->link_to_next(hd);
+ hd = h;
+ hi -= sz;
+ need -= sz;
+ } while (need > 0);
+ }
+ ch = (<T>MChunk*) hd;
+}
+
+<T>MPlex:: <T>MPlex(int l, int hi, const <T&> initval, int chunksize)
+{
+ lo = l;
+ fnc = hi + 1;
+ if (chunksize == 0)
+ {
+ csize = fnc - l;
+ make_initial_chunks(1);
+ }
+ else if (chunksize < 0)
+ {
+ csize = -chunksize;
+ make_initial_chunks(0);
+ }
+ else
+ {
+ csize = chunksize;
+ make_initial_chunks(1);
+ }
+ unused = fnc - lo;
+ for (int i=lo; i<fnc; ++i)
+ undel_index(i);
+ fill(initval);
+}
+
+<T>MPlex::<T>MPlex(const <T>MPlex& a)
+{
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = a.csize;
+ unused = fnc - lo;
+ hd = 0;
+ const <T>IChunk* p = a.hd;
+ do
+ {
+ <T>* data = new <T> [p->size()];
+ <T>MChunk* h = new <T>MChunk(data, p->base_index(),
+ p->low_index(), p->fence_index(), p->top_index());
+ if (hd != 0)
+ h->link_to_next(hd);
+ else
+ hd = h;
+ p = p->next();
+ } while (p != a.hd);
+ ch = (<T>MChunk*) hd;
+ for (int i = a.low(); i < a.fence(); a.next(i))
+ {
+ undel_index(i);
+ (*this)[i] = a[i];
+ }
+}
+
+void <T>MPlex::operator= (const <T>MPlex& a)
+{
+ if (&a != this)
+ {
+ invalidate();
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = a.csize;
+ unused = fnc - lo;
+ hd = 0;
+ const <T>IChunk* p = a.hd;
+ do
+ {
+ <T>* data = new <T> [p->size()];
+ <T>MChunk* h = new <T>MChunk(data, p->base_index(),
+ p->low_index(), p->fence_index(),
+ p->top_index());
+ if (hd != 0)
+ h->link_to_next(hd);
+ else
+ hd = h;
+ p = p->next();
+ } while (p != a.hd);
+ ch = (<T>MChunk*) hd;
+ for (int i = a.low(); i < a.fence(); a.next(i))
+ {
+ undel_index(i);
+ (*this)[i] = a[i];
+ }
+ }
+}
+
+int <T>MPlex::valid(int idx) const
+{
+ const <T>MChunk* tail = (<T>MChunk*)tl();
+ const <T>MChunk* t = ch;
+ while (idx >= t->fence_index())
+ {
+ if (t == tail) return 0;
+ t = ((<T>MChunk*)(t->next()));
+ }
+ while (idx < t->low_index())
+ {
+ if (t == (<T>MChunk*)(hd)) return 0;
+ t = ((<T>MChunk*)(t->prev()));
+ }
+ set_cache(t);
+ return t-><T>MChunk::valid_index(idx);
+}
+
+void <T>MPlex::cache(int idx) const
+{
+ const <T>MChunk* tail = (<T>MChunk*)tl();
+ const <T>MChunk* t = ch;
+ while (idx >= t->fence_index())
+ {
+ if (t == tail) index_error();
+ t = ((<T>MChunk*)(t->next()));
+ }
+ while (idx < t->low_index())
+ {
+ if (t == (<T>MChunk*)hd) index_error();
+ t = ((<T>MChunk*)(t->prev()));
+ }
+ if (!t-><T>MChunk::valid_index(idx)) index_error();
+ set_cache(t);
+}
+
+void <T>MPlex::cache(const <T>* p) const
+{
+ const <T>MChunk* old = ch;
+ const <T>MChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = ((<T>MChunk*)(t->next()));
+ if (t == old) index_error();
+ }
+ if (!t-><T>MChunk::valid_pointer(p)) index_error();
+ set_cache(t);
+}
+
+int <T>MPlex::owns(Pix px) const
+{
+ <T>* p = (<T>*)px;
+ const <T>MChunk* old = ch;
+ const <T>MChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = ((<T>MChunk*)(t->next()));
+ if (t == old) return 0;
+ }
+ set_cache(t);
+ return t-><T>MChunk::valid_pointer(p);
+}
+
+int <T>MPlex::add_high(const <T&> elem)
+{
+ <T>MChunk* t = ((<T>MChunk*) tl());
+
+ if (!t->can_grow_high())
+ {
+ <T>* data = new <T> [csize];
+ t = (new <T>MChunk(data, fnc,fnc,fnc,fnc+csize));
+ t->link_to_prev(tl());
+ }
+
+ *((t-><T>MChunk::grow_high())) = elem;
+ set_cache(t);
+ return fnc++;
+}
+
+int <T>MPlex::add_low (const <T&> elem)
+{
+ <T>MChunk* t = ((<T>MChunk*) hd);
+ if (!t->can_grow_low())
+ {
+ <T>* data = new <T> [csize];
+ hd = new <T>MChunk(data, lo-csize, lo, lo, lo);
+ hd->link_to_next(t);
+ t = ((<T>MChunk*) hd);
+ }
+
+ *((t-><T>MChunk::grow_low())) = elem;
+ set_cache(t);
+ return --lo;
+}
+
+void <T>MPlex::adjust_bounds()
+{
+ <T>MChunk* t = ((<T>MChunk*) tl());
+
+ // clean up tail
+
+ t->reset_high();
+ while (t-><T>MChunk::empty() && !one_chunk())
+ {
+ <T>MChunk* pred = (<T>MChunk*)(t->prev());
+ del_chunk(t);
+ pred->reset_high();
+ t = (pred);
+ }
+ if (one_chunk())
+ t->reset_high();
+
+ int oldfnc = fnc;
+ fnc = t->fence_index();
+ unused -= oldfnc - fnc;
+
+ // and head..
+ t = ((<T>MChunk*) hd);
+ t->reset_low();
+ while (t-><T>MChunk::empty() && !one_chunk())
+ {
+ hd = (<T>MChunk*)(t->next());
+ del_chunk(t);
+ t = ((<T>MChunk*) hd);
+ t->reset_low();
+ }
+
+ int oldlo = lo;
+ lo = t->low_index();
+ unused -= lo - oldlo;
+
+
+ set_cache(t);
+}
+
+int <T>MPlex::del_high ()
+{
+ if (empty()) empty_error();
+ <T>MChunk* t = ((<T>MChunk*) tl());
+ while (t-><T>MChunk::empty() && !one_chunk()) // possible stragglers
+ {
+ <T>MChunk* pred = (<T>MChunk*)(t->prev());
+ del_chunk(t);
+ pred->reset_high();
+ t = (pred);
+ }
+ t-><T>MChunk::shrink_high();
+ while (t-><T>MChunk::empty() && !one_chunk())
+ {
+ <T>MChunk* pred = (<T>MChunk*)(t->prev());
+ del_chunk(t);
+ pred->reset_high();
+ t = (pred);
+ }
+ int oldfnc = fnc;
+ fnc = t->fence_index();
+ unused -= oldfnc - fnc - 1;
+ set_cache(t);
+ return fnc - 1;
+}
+
+int <T>MPlex::del_low ()
+{
+ if (empty()) empty_error();
+ <T>MChunk* t = ((<T>MChunk*) hd);
+ while (t-><T>MChunk::empty() && !one_chunk())
+ {
+ hd = (<T>MChunk*)(t->next());
+ del_chunk(t);
+ t = ((<T>MChunk*) hd);
+ t->reset_low();
+ }
+ t-><T>MChunk::shrink_low();
+ while (t-><T>MChunk::empty() && !one_chunk())
+ {
+ hd = (<T>MChunk*)(t->next());
+ del_chunk(t);
+ t = ((<T>MChunk*) hd);
+ t->reset_low();
+ }
+ int oldlo = lo;
+ lo = t->low_index();
+ unused -= lo - oldlo - 1;
+ set_cache(t);
+ return lo;
+}
+
+int <T>MPlex::add(const <T&> elem)
+{
+ if (unused == 0)
+ return add_high(elem);
+
+ <T>MChunk* t;
+ for (t = ch;
+ t->unused_indices() == 0;
+ t = (<T>MChunk*)(t->prev()))
+ ;
+
+ int i = t->unused_index();
+ set_cache(t);
+ undel_index(i);
+ (*this)[i] = elem;
+ return i;
+}
+
+int <T>MPlex::unused_index() const
+{
+ if (unused == 0) index_error();
+
+ <T>MChunk* t;
+ for (t = ch;
+ t->unused_indices() == 0;
+ t = (<T>MChunk*)(t->prev()))
+ ;
+
+ set_cache(t);
+ return t->unused_index();
+}
+
+Pix <T>MPlex::unused_Pix() const
+{
+ if (unused == 0) return 0;
+
+ <T>MChunk* t;
+ for (t = ch;
+ t->unused_indices() == 0;
+ t = (<T>MChunk*)(t->prev()))
+ ;
+
+ set_cache(t);
+ return t->pointer_to(t->unused_index());
+}
+
+int <T>MPlex::del_index(int idx)
+{
+ if (idx < lo || idx >= fnc) index_error();
+ if (<T>MPlex::valid(idx))
+ {
+ ++unused;
+ ch-><T>MChunk::del(idx);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+int <T>MPlex::dopred(int idx) const
+{
+
+ if (idx >= fnc) idx = fnc;
+ if (idx <= lo) return lo - 1;
+
+ const <T>MChunk* t = ch;
+
+ while (idx > t->fence_index())
+ {
+ t = ((<T>MChunk*)(t->next()));
+ }
+ while (idx <= t->low_index())
+ {
+ t = ((<T>MChunk*)(t->prev()));
+ }
+ int i = t-><T>MChunk::pred(idx);
+ while (i < t->low_index() && i >= lo)
+ {
+ t = ((<T>MChunk*)(t->prev()));
+ i = t-><T>MChunk::last_index();
+ }
+ set_cache(t);
+ return i;
+}
+
+
+int <T>MPlex::dosucc(int idx) const
+{
+ if (idx < lo) idx = lo;
+ if (idx >= fnc - 1) return fnc;
+
+ const <T>MChunk* t = ch;
+ while (idx >= t->fence_index())
+ {
+ t = ((<T>MChunk*)(t->next()));
+ }
+ while (idx < t->low_index())
+ {
+ t = ((<T>MChunk*)(t->prev()));
+ }
+ int i = t-><T>MChunk::succ(idx);
+ while (i >= t->fence_index() && i < fnc)
+ {
+ t = (<T>MChunk*)(t->next());
+ i = t-><T>MChunk::first_index();
+ }
+ set_cache(t);
+ return i;
+}
+
+void <T>MPlex::prev(Pix& i) const
+{
+ if (i == 0) return;
+
+ <T>* p = (<T>*) i;
+ const <T>MChunk* old = ch;
+ const <T>MChunk* t = ch;
+
+ while (!t->actual_pointer(p))
+ {
+ t = ((<T>MChunk*)(t->prev()));
+ if (t == old)
+ {
+ i = 0;
+ return;
+ }
+ }
+ <T>* q = t-><T>MChunk::pred(p);
+ while (q == 0 && t != (<T>MChunk*)hd)
+ {
+ t = ((<T>MChunk*)(t->prev()));
+ q = t-><T>MChunk::last_pointer();
+ }
+
+ i = Pix(q);
+ set_cache(t);
+ return;
+}
+
+void <T>MPlex::next(Pix& i) const
+{
+ if (i == 0) return;
+
+ <T>* p = (<T>*) i;
+ const <T>MChunk* tail = (<T>MChunk*)(tl());
+ const <T>MChunk* old = ch;
+ const <T>MChunk* t = ch;
+
+ while (!t->actual_pointer(p))
+ {
+ t = ((<T>MChunk*)(t->next()));
+ if (t == old)
+ {
+ i = 0;
+ return;
+ }
+ }
+ <T>* q = t-><T>MChunk::succ(p);
+ while (q == 0 && t != tail)
+ {
+ t = ((<T>MChunk*)(t->next()));
+ q = t-><T>MChunk::first_pointer();
+ }
+
+ i = Pix(q);
+ set_cache(t);
+ return;
+}
+
+
+void <T>MPlex::undel_index(int idx)
+{
+ if (idx < lo || idx >= fnc) index_error();
+
+ <T>MChunk* t = ch;
+ while (idx >= t->fence_index())
+ {
+ t = ((<T>MChunk*)(t->next()));
+ }
+ while (idx < t->low_index())
+ {
+ t = ((<T>MChunk*)(t->prev()));
+ }
+ int was_present = t-><T>MChunk::undel(idx);
+ if (!was_present)
+ {
+ --unused;
+ }
+ set_cache(t);
+ return;
+}
+
+void <T>MPlex::clear()
+{
+ if (fnc != lo)
+ {
+ <T>MChunk* t = ((<T>MChunk*)tl());
+ while (t != hd)
+ {
+ <T>MChunk* prv = (<T>MChunk*)(t->prev());
+ del_chunk(t);
+ t = prv;
+ }
+ t-><T>MChunk::clear(lo);
+ set_cache(t);
+ fnc = lo;
+ unused = 0;
+ }
+}
+
+int <T>MPlex::OK () const
+{
+ int v = hd != 0; // at least one chunk
+
+ int found_ch = 0; // to make sure ch is in list;
+
+ int count = 0; // to count unused slots
+
+ const <T>MChunk* t = (<T>MChunk*)(hd);
+
+ int gap = t->low_index() - lo;
+ v &= gap == 0; // hd lo not less than lo.
+ count += gap;
+
+ for (;;)
+ {
+ if (t == ch) ++found_ch;
+ v &= t-><T>MChunk::OK(); // each chunk is OK
+ count += t->unused_indices();
+ if (t == (<T>MChunk*)(tl()))
+ break;
+ else // and has indices less than succ
+ {
+ gap = t->next()->base_index() - t->top_index();
+ v &= gap == 0;
+ count += gap;
+
+ if (t != (<T>MChunk*)hd) // internal chunks can't grow
+ v &= !t->can_grow_low() && !t->can_grow_high();
+
+ t = (const <T>MChunk*)(t->next());
+ }
+ }
+ gap = fnc - t->fence_index();
+ v &= gap == 0;
+ count += gap;
+
+ v &= count == unused; // chunk counts agree with plex
+
+ v &= found_ch == 1;
+ if (!v) error("invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/include/gen/MPlex.hP b/gnu/lib/libg++/include/gen/MPlex.hP
new file mode 100644
index 00000000000..c257f43de5a
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/MPlex.hP
@@ -0,0 +1,414 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>MPlex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>MPlex_h 1
+
+
+#include "<T>.Plex.h"
+
+
+// Number of bits per long, used in MChunk bit map operations
+
+#define _MAP_BITS 32
+
+
+class <T>MChunk : public <T>IChunk
+{
+protected:
+
+ unsigned long* map; // bitmap of slots
+ int unused; // number of unused internal slots
+
+ inline void mark(int); // bitmap operations
+ inline void free(int);
+ inline int valid(int) const;
+
+public:
+
+ <T>MChunk(<T>* d, // ptr to array of elements
+ int base_idx, // initial indices
+ int low_idx, // & initially clear map
+ int fence_idx,
+ int top_idx);
+
+ inline ~<T>MChunk();
+
+// virtuals
+
+ int first_index() const;
+ int last_index() const;
+ inline int succ(int idx) const;
+ inline int pred(int idx) const;
+ <T>* first_pointer() const;
+ <T>* last_pointer() const;
+ <T>* succ(<T>*) const;
+ <T>* pred(<T>*) const;
+ inline int empty() const;
+ inline int full() const;
+ inline int valid_index(int i) const;
+ inline int valid_pointer(const <T>* p) const;
+ inline <T>* grow_high ();
+ inline <T>* grow_low ();
+ void shrink_high ();
+ void shrink_low ();
+ void clear(int);
+ void cleardown(int);
+ int OK() const;
+
+// extensions
+
+ int unused_indices() const; // how many free slot in low..fence?
+
+ int unused_index() const; // return index of free slot
+
+ int del(int i); // delete data indexed by i
+ // return true if was present
+ int undel(int idx); // un-delete data indexed by i
+ // return true if already present
+
+ void reset_low(); // reset low = lowest valid index;
+ void reset_high(); // same for high
+
+};
+
+
+class <T>MPlex: public <T>Plex
+{
+ <T>MChunk* ch; // cached chunk
+ int unused; // # of free slots between low & fence
+
+ void make_initial_chunks(int up = 1);
+ void cache(int idx) const;
+ void cache(const <T>* p) const;
+ int dopred(int) const;
+ int dosucc(int) const;
+
+ void set_cache(const <T>MChunk* t) const; // logically,
+ // not physically const
+
+public:
+ <T>MPlex(); // set low = 0;
+ // fence = 0;
+ // csize = default
+
+ <T>MPlex(int ch_size); // low = 0;
+ // fence = 0;
+ // csize = ch_size
+
+ <T>MPlex(int lo, // low = lo;
+ int ch_size); // fence=lo
+ // csize = ch_size
+
+ <T>MPlex(int lo, // low = lo
+ int hi, // fence = hi+1
+ const <T&> initval,// fill with initval,
+ int ch_size = 0); // csize= ch_size
+ // or fence-lo if 0
+
+ <T>MPlex(const <T>MPlex&);
+
+ void operator= (const <T>MPlex&);
+
+// virtuals
+
+ inline <T>& high_element ();
+ inline <T>& low_element ();
+ inline const <T>& high_element () const;
+ inline const <T>& low_element () const;
+
+ inline Pix first() const;
+ inline Pix last() const ;
+ void prev(Pix& ptr) const;
+ void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ inline <T>& operator () (Pix p);
+ inline const <T>& operator () (Pix p) const;
+
+ inline int low() const;
+ inline int high() const;
+ int valid(int idx) const;
+ inline void prev(int& idx) const;
+ inline void next(int& x) const;
+ inline <T>& operator [] (int index);
+ inline const <T>& operator [] (int index) const;
+
+ inline int Pix_to_index(Pix p) const;
+ inline Pix index_to_Pix(int idx) const;
+
+ inline int can_add_high() const;
+ inline int can_add_low() const;
+ inline int full() const;
+
+ int add_high(const <T&> elem);
+ int del_high ();
+ int add_low (const <T&> elem);
+ int del_low ();
+ void clear();
+
+ int OK () const;
+
+// extensions
+
+ int count() const; // # valid elements
+ int available() const; // # deleted elements
+
+ int unused_index()const; // return index of a deleted elem
+ Pix unused_Pix() const; // return Pix of a deleted elem
+
+ int del_index(int idx); // logically delete at idx;
+ // return true if was present
+ int del_Pix(Pix p); // delete at p
+
+ void undel_index(int idx); // undelete at idx;
+ void undel_Pix(Pix p); // undelete at p;
+
+ void adjust_bounds(); // reset lo, hi to lowest &
+ // highest valid indices
+
+ int add(const <T&> elem); // add anywhere
+};
+
+
+inline <T>MChunk:: ~<T>MChunk()
+{
+ delete map;
+}
+
+inline void <T>MChunk::mark(int idx)
+{
+ unsigned int i = idx - base;
+ map[i / _MAP_BITS] |= 1 << (i & (_MAP_BITS - 1));
+}
+
+inline void <T>MChunk::free(int idx)
+{
+ unsigned int i = idx - base;
+ map[i / _MAP_BITS] &= ~(1 << (i & (_MAP_BITS - 1)));
+}
+
+inline int <T>MChunk::valid(int idx) const
+{
+ unsigned int i = idx - base;
+ return map[i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1)));
+}
+
+inline int <T>MChunk:: valid_index(int i) const
+{
+ return i >= low && i < fence && valid(i);
+}
+
+inline int <T>MChunk:: valid_pointer(const <T>* p) const
+{
+ int i = ((int)p - (int)data) / sizeof(<T>);
+ return i >= 0 && i < (fence - base) &&
+ (map[(unsigned)i / _MAP_BITS] & (1 << (i & (_MAP_BITS - 1))));
+}
+
+inline int <T>MChunk::empty() const
+{
+ return fence - low - unused == 0;
+}
+
+inline int <T>MChunk::full() const
+{
+ return unused + (top - fence) + (low - base) == 0;
+}
+
+inline int <T>MChunk::succ(int idx) const
+{
+ int i = (idx < low)? low : idx + 1;
+ while (i < fence && !valid(i)) ++i;
+ return i;
+}
+
+inline int <T>MChunk::pred(int idx) const
+{
+ int i = (idx > fence)? (fence - 1) : idx - 1;
+ while (i >= low && !valid(i)) --i;
+ return i;
+}
+
+inline int <T>MChunk::unused_indices() const
+{
+ return unused;
+}
+
+inline <T>* <T>MChunk:: grow_high ()
+{
+ if (!can_grow_high()) full_error();
+ mark(fence);
+ return &(data[fence++ - base]);
+}
+
+inline <T>* <T>MChunk:: grow_low ()
+{
+ if (!can_grow_low()) full_error();
+ mark(--low);
+ return &(data[low - base]);
+}
+
+inline void <T>MChunk::reset_low()
+{
+ while (low < fence && !valid(low))
+ {
+ --unused;
+ ++low;
+ }
+}
+
+inline void <T>MChunk::reset_high()
+{
+ while (fence > low && !valid(fence - 1))
+ {
+ --unused;
+ --fence;
+ }
+}
+
+inline int <T>MPlex::full () const
+{
+ return 0;
+}
+
+inline int <T>MPlex::can_add_high() const
+{
+ return 1;
+}
+
+inline int <T>MPlex::can_add_low() const
+{
+ return 1;
+}
+
+inline int <T>MPlex::available() const
+{
+ return unused;
+}
+
+inline int <T>MPlex::count() const
+{
+ return fnc - lo - unused;
+}
+
+inline void <T>MPlex::set_cache(const <T>MChunk* t) const
+{
+ ((<T>MPlex*)(this))->ch = (<T>MChunk*)t;
+}
+
+inline <T>& <T>MPlex:: operator [] (int idx)
+{
+ if (!ch-><T>MChunk::valid_index(idx)) cache(idx);
+ return * (ch->pointer_to(idx));
+}
+
+inline const <T>& <T>MPlex:: operator [] (int idx) const
+{
+ if (!ch-><T>MChunk::valid_index(idx)) cache(idx);
+ return * ((const <T>*)(ch->pointer_to(idx)));
+}
+
+inline int <T>MPlex::Pix_to_index(Pix p) const
+{
+ if (!ch-><T>MChunk::valid_pointer((<T>*)p)) cache((<T>*)p);
+ return ch->index_of((<T>*)p);
+}
+
+inline int <T>MPlex::high() const
+{
+ return (((const <T>MChunk*)tl())-><T>MChunk::valid_index(fnc-1)) ?
+ fnc-1 : dopred(fnc-1);
+}
+
+inline int <T>MPlex::low() const
+{
+ return (((const <T>MChunk*)hd)-><T>MChunk::valid_index(lo))? lo : dosucc(lo);
+}
+
+inline <T>& <T>MPlex::low_element ()
+{
+ return (*this)[low()];
+}
+
+inline const <T>& <T>MPlex::low_element () const
+{
+ return (*this)[low()];
+}
+
+inline <T>& <T>MPlex::high_element ()
+{
+ return (*this)[high()];
+}
+
+inline const <T>& <T>MPlex::high_element () const
+{
+ return (*this)[high()];
+}
+
+inline Pix <T>MPlex::index_to_Pix(int idx) const
+{
+ if (!ch-><T>MChunk::valid_index(idx)) cache(idx);
+ return Pix(ch->pointer_to(idx));
+}
+
+inline void <T>MPlex::next(int& idx) const
+{
+ idx = (ch-><T>MChunk::valid_index(idx+1))? idx+1 : dosucc(idx);
+}
+
+inline void <T>MPlex::prev(int& idx) const
+{
+ idx = (ch-><T>MChunk::valid_index(idx-1))? idx-1 : dopred(idx);
+}
+
+inline Pix <T>MPlex::first() const
+{
+ return index_to_Pix(low());
+}
+
+inline Pix <T>MPlex::last() const
+{
+ return index_to_Pix(high());
+}
+
+
+inline void <T>MPlex::undel_Pix(Pix p)
+{
+ undel_index(Pix_to_index(p));
+}
+
+inline int <T>MPlex::del_Pix(Pix p)
+{
+ return del_index(Pix_to_index(p));
+}
+
+inline <T>& <T>MPlex:: operator () (Pix p)
+{
+ return *((<T>*)p);
+}
+
+inline const <T>& <T>MPlex:: operator () (Pix p) const
+{
+ return *((const <T>*)p);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Map.ccP b/gnu/lib/libg++/include/gen/Map.ccP
new file mode 100644
index 00000000000..146a2d2b2a9
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Map.ccP
@@ -0,0 +1,59 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include "<T>.<C>.Map.h"
+
+
+Pix <T><C>Map::seek(<T&> item)
+{
+ Pix i;
+ for (i = first(); i != 0 && !(<T>EQ(key(i), item)); next(i));
+ return i;
+}
+
+int <T><C>Map::owns(Pix idx)
+{
+ if (idx == 0) return 0;
+ for (Pix i = first(); i; next(i)) if (i == idx) return 1;
+ return 0;
+}
+
+void <T><C>Map::clear()
+{
+ Pix i = first();
+ while (i != 0)
+ {
+ del(key(i));
+ i = first();
+ }
+}
+
+int <T><C>Map::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+
+void <T><C>Map::error(const char* msg)
+{
+ (*lib_error_handler)("Map", msg);
+}
diff --git a/gnu/lib/libg++/include/gen/Map.hP b/gnu/lib/libg++/include/gen/Map.hP
new file mode 100644
index 00000000000..13a3fb14518
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Map.hP
@@ -0,0 +1,87 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T><C>Map_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>Map_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T><C>Map
+{
+protected:
+ int count;
+ <C> def;
+
+public:
+ <T><C>Map(<C&> dflt);
+ inline virtual ~<T><C>Map();
+
+ int length() const; // current number of items
+ int empty() const;
+
+ virtual int contains(<T&> key); // is key mapped?
+
+ virtual void clear(); // delete all items
+
+ virtual <C>& operator [] (<T&> key) = 0; // access contents by key
+
+ virtual void del(<T&> key) = 0; // delete entry
+
+ virtual Pix first() = 0; // Pix of first item or 0
+ virtual void next(Pix& i) = 0; // advance to next or 0
+ virtual <T>& key(Pix i) = 0; // access key at i
+ virtual <C>& contents(Pix i) = 0; // access contents at i
+
+ virtual int owns(Pix i); // is i a valid Pix ?
+ virtual Pix seek(<T&> key); // Pix of key
+
+ <C>& dflt(); // access default val
+
+ void error(const char* msg);
+ virtual int OK() = 0; // rep invariant
+};
+
+
+inline <T><C>Map::~<T><C>Map() {}
+
+inline int <T><C>Map::length() const
+{
+ return count;
+}
+
+inline int <T><C>Map::empty() const
+{
+ return count == 0;
+}
+
+inline <C>& <T><C>Map::dflt()
+{
+ return def;
+}
+
+inline <T><C>Map::<T><C>Map(<C&> dflt) :def(dflt)
+{
+ count = 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/OSLBag.ccP b/gnu/lib/libg++/include/gen/OSLBag.ccP
new file mode 100644
index 00000000000..285c2cfd000
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OSLBag.ccP
@@ -0,0 +1,196 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.OSLBag.h"
+
+
+Pix <T>OSLBag::seek(<T&> item, Pix i)
+{
+ if (i == 0) i = p.first(); else next(i);
+ for (; i != 0; p.next(i))
+ {
+ int cmp = <T>CMP(item, p(i));
+ if (cmp == 0)
+ return i;
+ else if (cmp < 0)
+ return 0;
+ }
+ return 0;
+}
+
+int <T>OSLBag::nof(<T&> item)
+{
+ int n = 0;
+ for (Pix i = p.first(); i != 0; p.next(i))
+ {
+ int cmp = <T>CMP(item, p(i));
+ if (cmp == 0)
+ ++n;
+ else if (cmp < 0)
+ break;
+ }
+ return n;
+}
+
+Pix <T>OSLBag::add(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ {
+ ++count;
+ return p.prepend(item);
+ }
+ int cmp = <T>CMP(item, p(i));
+ if (cmp <= 0)
+ {
+ ++count;
+ return p.prepend(item);
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ for (;;)
+ {
+ if (i == 0)
+ {
+ ++count;
+ return p.append(item);
+ }
+ cmp = <T>CMP(item, p(i));
+ if (cmp <= 0)
+ {
+ ++count;
+ return p.ins_after(trail, item);
+ }
+ else
+ {
+ trail = i;
+ p.next(i);
+ }
+ }
+ }
+}
+
+void <T>OSLBag::del(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ return;
+ int cmp = <T>CMP(item, p(i));
+ if (cmp < 0)
+ return;
+ else if (cmp == 0)
+ {
+ --count;
+ p.del_front();
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ while (i != 0)
+ {
+ cmp = <T>CMP(item, p(i));
+ if (cmp < 0)
+ return;
+ else if (cmp == 0)
+ {
+ --count;
+ p.del_after(trail);
+ return;
+ }
+ else
+ {
+ trail = i;
+ p.next(i);
+ }
+ }
+ }
+}
+
+void <T>OSLBag::remove(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ return;
+ int cmp = <T>CMP(item, p(i));
+ if (cmp < 0)
+ return;
+ else if (cmp == 0)
+ {
+ do
+ {
+ --count;
+ p.del_front();
+ i = p.first();
+ } while (i != 0 && <T>EQ(item, p(i)));
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ while (i != 0)
+ {
+ cmp = <T>CMP(item, p(i));
+ if (cmp < 0)
+ return;
+ else if (cmp == 0)
+ {
+ do
+ {
+ --count;
+ p.del_after(trail);
+ i = trail;
+ next(i);
+ } while (i != 0 && <T>EQ(item, p(i)));
+ return;
+ }
+ else
+ {
+ trail = i;
+ p.next(i);
+ }
+ }
+ }
+}
+
+int <T>OSLBag::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ Pix trail = p.first();
+ if (trail == 0)
+ v &= count == 0;
+ else
+ {
+ Pix i = trail; next(i);
+ while (i != 0)
+ {
+ v &= <T>CMP(p(trail), p(i)) <= 0;
+ trail = i;
+ next(i);
+ }
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/include/gen/OSLBag.hP b/gnu/lib/libg++/include/gen/OSLBag.hP
new file mode 100644
index 00000000000..5a657f0f3a1
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OSLBag.hP
@@ -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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>OSLBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>OSLBag_h 1
+
+#include "<T>.Bag.h"
+#include "<T>.SLList.h"
+
+class <T>OSLBag : public <T>Bag
+{
+protected:
+ <T>SLList p;
+
+public:
+ <T>OSLBag();
+ <T>OSLBag(const <T>OSLBag&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+
+ inline int contains(<T&> item);
+ int nof(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+
+inline <T>OSLBag::<T>OSLBag() : p() { count = 0; }
+
+inline <T>OSLBag::<T>OSLBag(const <T>OSLBag& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>OSLBag::first()
+{
+ return p.first();
+}
+
+inline void <T>OSLBag::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>OSLBag::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>OSLBag::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>OSLBag::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+inline int <T>OSLBag::contains(<T&> item)
+{
+ return seek(item) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/OSLSet.ccP b/gnu/lib/libg++/include/gen/OSLSet.ccP
new file mode 100644
index 00000000000..937d915a96b
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OSLSet.ccP
@@ -0,0 +1,321 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.OSLSet.h"
+
+
+Pix <T>OSLSet::seek(<T&> item)
+{
+ for (Pix i = p.first(); i != 0; p.next(i))
+ {
+ int cmp = <T>CMP(item, p(i));
+ if (cmp == 0)
+ return i;
+ else if (cmp < 0)
+ return 0;
+ }
+ return 0;
+}
+
+Pix <T>OSLSet::add(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ {
+ ++count;
+ return p.prepend(item);
+ }
+ int cmp = <T>CMP(item, p(i));
+ if (cmp == 0)
+ return i;
+ else if (cmp < 0)
+ {
+ ++count;
+ return p.prepend(item);
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ for (;;)
+ {
+ if (i == 0)
+ {
+ ++count;
+ return p.append(item);
+ }
+ cmp = <T>CMP(item, p(i));
+ if (cmp == 0)
+ return i;
+ else if (cmp < 0)
+ {
+ ++count;
+ return p.ins_after(trail, item);
+ }
+ else
+ {
+ trail = i;
+ p.next(i);
+ }
+ }
+ }
+}
+
+void <T>OSLSet::del(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ return;
+ int cmp = <T>CMP(item, p(i));
+ if (cmp < 0)
+ return;
+ else if (cmp == 0)
+ {
+ --count;
+ p.del_front();
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ while (i != 0)
+ {
+ cmp = <T>CMP(item, p(i));
+ if (cmp < 0)
+ return;
+ else if (cmp == 0)
+ {
+ --count;
+ p.del_after(trail);
+ return;
+ }
+ else
+ {
+ trail = i;
+ p.next(i);
+ }
+ }
+ }
+}
+
+
+int <T>OSLSet::operator <= (<T>OSLSet& b)
+{
+ if (count > b.count) return 0;
+ Pix i = first();
+ Pix j = b.first();
+ for (;;)
+ {
+ if (i == 0)
+ return 1;
+ else if (j == 0)
+ return 0;
+ int cmp = <T>CMP(p(i), b.p(j));
+ if (cmp == 0)
+ {
+ next(i); b.next(j);
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ b.next(j);
+ }
+}
+
+int <T>OSLSet::operator == (<T>OSLSet& b)
+{
+ if (count != b.count) return 0;
+ if (count == 0) return 1;
+ Pix i = p.first();
+ Pix j = b.p.first();
+ while (i != 0)
+ {
+ if (!<T>EQ(p(i),b.p(j))) return 0;
+ next(i);
+ b.next(j);
+ }
+ return 1;
+}
+
+
+void <T>OSLSet::operator |= (<T>OSLSet& b)
+{
+ if (&b == this || b.count == 0)
+ return;
+ else
+ {
+ Pix j = b.p.first();
+ Pix i = p.first();
+ Pix trail = 0;
+ for (;;)
+ {
+ if (j == 0)
+ return;
+ else if (i == 0)
+ {
+ for (; j != 0; b.next(j))
+ {
+ ++count;
+ p.append(b.p(j));
+ }
+ return;
+ }
+ int cmp = <T>CMP(p(i), b.p(j));
+ if (cmp <= 0)
+ {
+ if (cmp == 0) b.next(j);
+ trail = i;
+ next(i);
+ }
+ else
+ {
+ ++count;
+ if (trail == 0)
+ trail = p.prepend(b.p(j));
+ else
+ trail = p.ins_after(trail, b.p(j));
+ b.next(j);
+ }
+ }
+ }
+}
+
+
+void <T>OSLSet::operator -= (<T>OSLSet& b)
+{
+ if (&b == this)
+ clear();
+ else if (count != 0 && b.count != 0)
+ {
+ Pix i = p.first();
+ Pix j = b.p.first();
+ Pix trail = 0;
+ for (;;)
+ {
+ if (j == 0 || i == 0)
+ return;
+ int cmp = <T>CMP(p(i), b.p(j));
+ if (cmp == 0)
+ {
+ --count;
+ b.next(j);
+ if (trail == 0)
+ {
+ p.del_front();
+ i = p.first();
+ }
+ else
+ {
+ next(i);
+ p.del_after(trail);
+ }
+ }
+ else if (cmp < 0)
+ {
+ trail = i;
+ next(i);
+ }
+ else
+ b.next(j);
+ }
+ }
+}
+
+void <T>OSLSet::operator &= (<T>OSLSet& b)
+{
+ if (b.count == 0)
+ clear();
+ else if (&b != this && count != 0)
+ {
+ Pix i = p.first();
+ Pix j = b.p.first();
+ Pix trail = 0;
+ for (;;)
+ {
+ if (i == 0)
+ return;
+ else if (j == 0)
+ {
+ if (trail == 0)
+ {
+ p.clear();
+ count = 0;
+ }
+ else
+ {
+ while (i != 0)
+ {
+ --count;
+ next(i);
+ p.del_after(trail);
+ }
+ }
+ return;
+ }
+ int cmp = <T>CMP(p(i), b.p(j));
+
+ if (cmp == 0)
+ {
+ trail = i;
+ next(i);
+ b.next(j);
+ }
+ else if (cmp < 0)
+ {
+ --count;
+ if (trail == 0)
+ {
+ p.del_front();
+ i = p.first();
+ }
+ else
+ {
+ next(i);
+ p.del_after(trail);
+ }
+ }
+ else
+ b.next(j);
+ }
+ }
+}
+
+
+int <T>OSLSet::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ Pix trail = p.first();
+ if (trail == 0)
+ v &= count == 0;
+ else
+ {
+ Pix i = trail; next(i);
+ while (i != 0)
+ {
+ v &= <T>CMP(p(trail), p(i)) < 0;
+ trail = i;
+ next(i);
+ }
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/OSLSet.hP b/gnu/lib/libg++/include/gen/OSLSet.hP
new file mode 100644
index 00000000000..02ace589cba
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OSLSet.hP
@@ -0,0 +1,101 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>OSLSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>OSLSet_h 1
+
+#include "<T>.Set.h"
+#include "<T>.SLList.h"
+
+class <T>OSLSet : public <T>Set
+{
+protected:
+ <T>SLList p;
+
+public:
+ <T>OSLSet();
+ <T>OSLSet(const <T>OSLSet&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item);
+
+ void operator |= (<T>OSLSet& b);
+ void operator -= (<T>OSLSet& b);
+ void operator &= (<T>OSLSet& b);
+
+ int operator == (<T>OSLSet& b);
+ int operator != (<T>OSLSet& b);
+ int operator <= (<T>OSLSet& b);
+
+ int OK();
+};
+
+
+inline <T>OSLSet::<T>OSLSet() : p() { count = 0; }
+
+inline <T>OSLSet::<T>OSLSet(const <T>OSLSet& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>OSLSet::first()
+{
+ return p.first();
+}
+
+inline void <T>OSLSet::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>OSLSet::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>OSLSet::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>OSLSet::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+inline int <T>OSLSet::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+inline int <T>OSLSet::operator != (<T>OSLSet& b)
+{
+ return !(*this == b);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/OXPBag.ccP b/gnu/lib/libg++/include/gen/OXPBag.ccP
new file mode 100644
index 00000000000..b81c3a0a373
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OXPBag.ccP
@@ -0,0 +1,221 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.OXPBag.h"
+
+
+Pix <T>OXPBag::seek(<T&> item, Pix i)
+{
+ if (i == 0)
+ {
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ while (mid > p.low() && <T>EQ(item, p[mid - 1])) --mid;
+ return p.index_to_Pix(mid);
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+ return 0;
+ }
+ int cmp = <T>CMP(item, p(i));
+ if (cmp == 0)
+ {
+ next(i);
+ return (<T>EQ(item, p(i)))? i : 0;
+ }
+ else if (cmp < 0)
+ {
+ int ind = p.Pix_to_index(i);
+ int l = ind;
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ while (mid > ind && <T>EQ(item, p[mid - 1])) --mid;
+ return p.index_to_Pix(mid);
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+ return 0;
+ }
+ else
+ return 0;
+}
+
+int <T>OXPBag::nof(<T&> item)
+{
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ l = h = mid;
+ while (l > p.low() && <T>EQ(item, p[l - 1])) --l;
+ while (h < p.high() && <T>EQ(item, p[h + 1])) ++h;
+ return h - l + 1;
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+ return 0;
+}
+
+Pix <T>OXPBag::add(<T&> item)
+{
+ if (count == 0)
+ {
+ ++count;
+ return p.index_to_Pix(p.add_high(item));
+ }
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ l = mid;
+ break;
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+ // add on whichever side is shortest
+ ++count;
+ if (l == p.fence())
+ return p.index_to_Pix(p.add_high(item));
+ else if (l == p.low())
+ return p.index_to_Pix(p.add_low(item));
+ else
+ {
+ if (p.high() - l < l - p.low())
+ {
+ h = p.add_high(p.high_element());
+ for (int i = h - 1; i > l; --i) p[i] = p[i-1];
+ }
+ else
+ {
+ --l;
+ h = p.add_low(p.low_element());
+ for (int i = h + 1; i < l; ++i) p[i] = p[i+1];
+ }
+ p[l] = item;
+ return p.index_to_Pix(l);
+ }
+}
+
+void <T>OXPBag::del(<T&> item)
+{
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ --count;
+ if (p.high() - mid < mid - p.low())
+ {
+ for (int i = mid; i < p.high(); ++i) p[i] = p[i+1];
+ p.del_high();
+ }
+ else
+ {
+ for (int i = mid; i > p.low(); --i) p[i] = p[i-1];
+ p.del_low();
+ }
+ return;
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+}
+
+void <T>OXPBag::remove(<T&> item)
+{
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ l = h = mid;
+ while (l > p.low() && <T>EQ(item, p[l - 1])) --l;
+ while (h < p.high() && <T>EQ(item, p[h + 1])) ++h;
+ int n = h - l + 1;
+ count -= n;
+ if (p.high() - h < l - p.low())
+ {
+ h = p.high() - n;
+ for (int i = l; i <= h; ++i) p[i] = p[i+n];
+ while (n-- > 0) p.del_high();
+ }
+ else
+ {
+ l = p.low() + n;
+ for (int i = h; i >= l; --i) p[i] = p[i-n];
+ while (n-- > 0) p.del_low();
+ }
+ return;
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+}
+
+int <T>OXPBag::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ for (int i = p.low(); i < p.high(); ++i) v &= <T>CMP(p[i], p[i+1]) <= 0;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/OXPBag.hP b/gnu/lib/libg++/include/gen/OXPBag.hP
new file mode 100644
index 00000000000..c7a25141415
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OXPBag.hP
@@ -0,0 +1,73 @@
+#ifndef _<T>OXPBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>OXPBag_h 1
+
+#include "<T>.Bag.h"
+#include "<T>.XPlex.h"
+
+class <T>OXPBag : public <T>Bag
+{
+protected:
+ <T>XPlex p;
+
+public:
+ <T>OXPBag(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>OXPBag(const <T>OXPBag&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+#undef remove
+ void remove(<T&>item);
+ int nof(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+
+inline <T>OXPBag::<T>OXPBag(int chunksize)
+ : p(chunksize) { count = 0; }
+
+inline <T>OXPBag::<T>OXPBag(const <T>OXPBag& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>OXPBag::first()
+{
+ return p.first();
+}
+
+inline void <T>OXPBag::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>OXPBag::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>OXPBag::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>OXPBag::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+inline int <T>OXPBag::contains(<T&> item)
+{
+ return seek(item) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/OXPSet.ccP b/gnu/lib/libg++/include/gen/OXPSet.ccP
new file mode 100644
index 00000000000..397c2c986a2
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OXPSet.ccP
@@ -0,0 +1,280 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.OXPSet.h"
+
+
+Pix <T>OXPSet::seek(<T&> item)
+{
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ return p.index_to_Pix(mid);
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+ return 0;
+}
+
+Pix <T>OXPSet::add(<T&> item)
+{
+ if (count == 0)
+ {
+ ++count;
+ return p.index_to_Pix(p.add_high(item));
+ }
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ return p.index_to_Pix(mid);
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+ // add on whichever side is shortest
+ ++count;
+ if (l == p.fence())
+ return p.index_to_Pix(p.add_high(item));
+ else if (l == p.low())
+ return p.index_to_Pix(p.add_low(item));
+ else
+ {
+ if (p.fence() - l < l - p.low())
+ {
+ h = p.add_high(p.high_element());
+ for (int i = h - 1; i > l; --i) p[i] = p[i-1];
+ }
+ else
+ {
+ --l;
+ h = p.add_low(p.low_element());
+ for (int i = h + 1; i < l; ++i) p[i] = p[i+1];
+ }
+ p[l] = item;
+ return p.index_to_Pix(l);
+ }
+}
+
+void <T>OXPSet::del(<T&> item)
+{
+ int l = p.low();
+ int h = p.high();
+ while (l <= h)
+ {
+ int mid = (l + h) / 2;
+ int cmp = <T>CMP(item, p[mid]);
+ if (cmp == 0)
+ {
+ --count;
+ if (p.high() - mid < mid - p.low())
+ {
+ for (int i = mid; i < p.high(); ++i) p[i] = p[i+1];
+ p.del_high();
+ }
+ else
+ {
+ for (int i = mid; i > p.low(); --i) p[i] = p[i-1];
+ p.del_low();
+ }
+ return;
+ }
+ else if (cmp < 0)
+ h = mid - 1;
+ else
+ l = mid + 1;
+ }
+}
+
+int <T>OXPSet::operator <= (<T>OXPSet& b)
+{
+ if (count > b.count) return 0;
+ int i = p.low();
+ int j = b.p.low();
+ for (;;)
+ {
+ if (i >= p.fence())
+ return 1;
+ else if (j >= b.p.fence())
+ return 0;
+ int cmp = <T>CMP(p[i], b.p[j]);
+ if (cmp == 0)
+ {
+ ++i; ++j;
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ ++j;
+ }
+}
+
+int <T>OXPSet::operator == (<T>OXPSet& b)
+{
+ int n = count;
+ if (n != b.count) return 0;
+ if (n == 0) return 1;
+ int i = p.low();
+ int j = b.p.low();
+ while (n-- > 0) if (!<T>EQ(p[i++], b.p[j++])) return 0;
+ return 1;
+}
+
+
+void <T>OXPSet::operator |= (<T>OXPSet& b)
+{
+ if (&b == this || b.count == 0)
+ return;
+ else if (b.count <= 2) // small b -- just add
+ for (Pix i = b.first(); i; b.next(i)) add(b(i));
+ else
+ {
+ // strategy: merge into top of p, simultaneously killing old bottom
+ int oldfence = p.fence();
+ int i = p.low();
+ int j = b.p.low();
+ for (;;)
+ {
+ if (i == oldfence)
+ {
+ while (j < b.p.fence()) p.add_high(b.p[j++]);
+ break;
+ }
+ else if (j == b.p.fence())
+ {
+ while (i++ < oldfence)
+ {
+ p.add_high(p.low_element());
+ p.del_low();
+ }
+ break;
+ }
+ int cmp = <T>CMP(p[i], b.p[j]);
+ if (cmp <= 0)
+ {
+ ++i;
+ if (cmp == 0) ++j;
+ p.add_high(p.low_element());
+ p.del_low();
+ }
+ else
+ p.add_high(b.p[j++]);
+ }
+ count = p.length();
+ }
+}
+
+
+
+void <T>OXPSet::operator -= (<T>OXPSet& b)
+{
+ if (&b == this)
+ clear();
+ else if (count != 0 && b.count != 0)
+ {
+ int i = p.low();
+ int k = i;
+ int j = b.p.low();
+ int oldfence = p.fence();
+ for (;;)
+ {
+ if (i >= oldfence)
+ break;
+ else if (j >= b.p.fence())
+ {
+ if (k != i)
+ while (i < oldfence) p[k++] = p[i++];
+ else
+ k = oldfence;
+ break;
+ }
+ int cmp = <T>CMP(p[i], b.p[j]);
+ if (cmp == 0)
+ {
+ ++i; ++j;
+ }
+ else if (cmp < 0)
+ {
+ if (k != i) p[k] = p[i];
+ ++i; ++k;
+ }
+ else
+ j++;
+ }
+ while (k++ < oldfence)
+ {
+ --count;
+ p.del_high();
+ }
+ }
+}
+
+void <T>OXPSet::operator &= (<T>OXPSet& b)
+{
+ if (b.count == 0)
+ clear();
+ else if (&b != this && count != 0)
+ {
+ int i = p.low();
+ int k = i;
+ int j = b.p.low();
+ int oldfence = p.fence();
+ for (;;)
+ {
+ if (i >= oldfence || j >= b.p.fence())
+ break;
+ int cmp = <T>CMP(p[i], b.p[j]);
+ if (cmp == 0)
+ {
+ if (k != i) p[k] = p[i];
+ ++i; ++k; ++j;
+ }
+ else if (cmp < 0)
+ ++i;
+ else
+ ++j;
+ }
+ while (k++ < oldfence)
+ {
+ --count;
+ p.del_high();
+ }
+ }
+}
+
+int <T>OXPSet::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ for (int i = p.low(); i < p.high(); ++i) v &= <T>CMP(p[i], p[i+1]) < 0;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/OXPSet.hP b/gnu/lib/libg++/include/gen/OXPSet.hP
new file mode 100644
index 00000000000..cfa0f156fb9
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/OXPSet.hP
@@ -0,0 +1,102 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>OXPSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>OXPSet_h 1
+
+#include "<T>.Set.h"
+#include "<T>.XPlex.h"
+
+class <T>OXPSet : public <T>Set
+{
+protected:
+ <T>XPlex p;
+
+public:
+ <T>OXPSet(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>OXPSet(const <T>OXPSet&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item);
+
+ void operator |= (<T>OXPSet& b);
+ void operator -= (<T>OXPSet& b);
+ void operator &= (<T>OXPSet& b);
+
+ int operator == (<T>OXPSet& b);
+ int operator != (<T>OXPSet& b);
+ int operator <= (<T>OXPSet& b);
+
+ int OK();
+};
+
+
+inline <T>OXPSet::<T>OXPSet(int chunksize)
+ : p(chunksize) { count = 0; }
+
+inline <T>OXPSet::<T>OXPSet(const <T>OXPSet& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>OXPSet::first()
+{
+ return p.first();
+}
+
+inline void <T>OXPSet::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>OXPSet::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>OXPSet::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>OXPSet::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+inline int <T>OXPSet::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+inline int <T>OXPSet::operator != (<T>OXPSet& b)
+{
+ return !(*this == b);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/PHPQ.ccP b/gnu/lib/libg++/include/gen/PHPQ.ccP
new file mode 100644
index 00000000000..ae8cde6cd07
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/PHPQ.ccP
@@ -0,0 +1,339 @@
+// 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)
+ 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <limits.h>
+#include "<T>.PHPQ.h"
+
+//
+// This defines a Pairing Heap structure
+//
+// See ``The Pairing Heap: A New Form of Self-Adjusting Heap''
+// Fredman, Segdewick et al,
+// Algorithmica (1986) 1:111-129
+//
+// In particular, this implements the pairing heap using the circular
+// list.
+//
+//
+
+<T>PHPQ::<T>PHPQ(int sz)
+{
+ storage = 0;
+ root = 0;
+ count = 0;
+ size = 0;
+ prealloc(sz);
+}
+
+<T>PHPQ::<T>PHPQ(<T>PHPQ& a)
+{
+ storage = 0;
+ root = 0;
+ count = 0;
+ size = 0;
+ prealloc(a.size);
+ for (Pix i = a.first(); i != 0; a.next(i)) enq(a(i));
+}
+
+
+void <T>PHPQ::prealloc(int newsize)
+{
+ ++newsize; // leave a spot for freelist
+ if (size != 0)
+ {
+ int news = size;
+ while (news <= newsize) news = (news * 3) / 2;
+ newsize = news;
+ }
+ // see if indices are OK
+ <T>PHPQNode test;
+ test.sibling = 0;
+ test.sibling = ~test.sibling;
+ if ((unsigned long)newsize > (unsigned long)(test.sibling))
+ error("storage size exceeds index range");
+
+ if (storage == 0)
+ {
+ storage = new <T>PHPQNode[size = newsize];
+ for (int i = 0; i < size; ++i)
+ {
+ storage[i].sibling = i + 1;
+ storage[i].valid = 0;
+ }
+ storage[size-1].sibling = 0;
+ }
+ else
+ {
+ <T>PHPQNode* newstor = new <T>PHPQNode[newsize];
+ for (int i = 1; i < size; ++i)
+ newstor[i] = storage[i];
+ delete [] storage;
+ storage = newstor;
+ for (int i = size; i < newsize; ++i)
+ {
+ storage[i].sibling = i + 1;
+ storage[i].valid = 0;
+ }
+ storage[newsize-1].sibling = 0;
+ storage[0].sibling = size;
+ size = newsize;
+ }
+}
+
+
+void <T>PHPQ::clear()
+{
+ for (int i = 0; i < size; ++i)
+ {
+ storage[i].sibling = i + 1;
+ storage[i].valid = 0;
+ }
+ storage[size-1].sibling = 0;
+ root = 0;
+ count = 0;
+}
+
+Pix <T>PHPQ::enq(<T&> item)
+{
+ ++count;
+ if (storage[0].sibling == 0)
+ prealloc(count);
+
+ int cell = storage[0].sibling;
+ storage[0].sibling = storage[cell].sibling;
+ storage[cell].sibling = 0;
+ storage[cell].children = 0;
+ storage[cell].item = item;
+ storage[cell].valid = 1;
+
+ if (root == 0)
+ {
+ root = cell;
+ return Pix(root);
+ }
+ else
+ {
+ int parent;
+ int child;
+
+ if (<T>LE(storage[root].item, storage[cell].item))
+ {
+ parent = root; child = cell;
+ }
+ else
+ {
+ parent = cell; child = root;
+ }
+ int popsKid = storage[parent].children;
+
+ if (popsKid == 0)
+ {
+ storage[parent].children = child;
+ storage[child].sibling = child;
+ }
+ else
+ {
+ int temp = storage[popsKid].sibling;
+ storage[popsKid].sibling = child;
+ storage[child].sibling = temp;
+ storage[parent].children = child;
+ }
+ root = parent;
+ return Pix(cell);
+ }
+}
+
+//
+// Item removal is the most complicated routine.
+//
+// We remove the root (should there be one) and then select a new
+// root. The siblings of the root are in a circular list. We continue
+// to pair elements in this list until there is a single element.
+// This element will be the new root.
+
+void <T>PHPQ::del_front()
+{
+ int valid = 0;
+ do
+ {
+ if (root == 0) return;
+ if ((valid = storage[root].valid))
+ --count;
+ storage[root].valid = 0;
+ int child = storage[root].children;
+ storage[root].sibling = storage[0].sibling;
+ storage[0].sibling = root;
+
+ if (child == 0)
+ {
+ root = 0;
+ return;
+ }
+ else
+ {
+ while(storage[child].sibling != child)
+ {
+ // We have at least two kids, but we may only have
+ // two kids. So, oneChild != child, but it is possible
+ // that twoChild == child.
+
+ int oneChild = storage[child].sibling;
+ int twoChild = storage[oneChild].sibling;
+
+ // Remove the two from the sibling list
+
+ storage[child].sibling = storage[twoChild].sibling;
+ storage[oneChild].sibling = 0;
+ storage[twoChild].sibling = 0;
+
+ int bestChild;
+ int worstChild;
+
+ if (<T>LE(storage[oneChild].item, storage[twoChild].item))
+ {
+ bestChild = oneChild; worstChild = twoChild;
+ }
+ else
+ {
+ bestChild = twoChild; worstChild = oneChild;
+ }
+ int popsKid = storage[bestChild].children;
+
+ if (popsKid == 0)
+ {
+ storage[bestChild].children = worstChild;
+ storage[worstChild].sibling = worstChild;
+ }
+ else
+ {
+ int temp = storage[popsKid].sibling;
+ storage[popsKid].sibling = worstChild;
+ storage[worstChild].sibling = temp;
+ storage[bestChild].children = worstChild;
+ }
+ if (twoChild == child)
+ {
+ // We have reduced the two to one, so we'll be exiting.
+ child = bestChild;
+ storage[child].sibling = child;
+ }
+ else
+ {
+ // We've removed two siblings, now we need to insert
+ // the better of the two
+ storage[bestChild].sibling = storage[child].sibling;
+ storage[child].sibling = bestChild;
+ child = storage[bestChild].sibling;
+ }
+ }
+ root = child;
+ }
+ } while ( !valid );
+}
+
+void <T>PHPQ::del(Pix p)
+{
+ if (p == 0) error("null Pix");
+ int i = int(p);
+ if (storage[i].valid)
+ {
+ if (i == root)
+ del_front();
+ else
+ {
+ storage[i].valid = 0;
+ --count;
+ }
+ }
+}
+
+
+Pix <T>PHPQ::seek(<T&> key)
+{
+ for (int i = 1; i < size; ++i)
+ if (storage[i].valid && <T>EQ(storage[i].item, key))
+ return Pix(i);
+ return 0;
+}
+
+Pix <T>PHPQ::first()
+{
+ for (int i = 1; i < size; ++i)
+ if (storage[i].valid)
+ return Pix(i);
+ return 0;
+}
+
+
+void <T>PHPQ::next(Pix& p)
+{
+ if (p == 0) return;
+ for (int i = int(p)+1; i < size; ++i)
+ if (storage[i].valid)
+ {
+ p = Pix(i);
+ return;
+ }
+ p = 0;
+}
+
+int <T>PHPQ::OK()
+{
+ int v = storage != 0;
+ int n = 0;
+ for (int i = 0; i < size; ++i) if (storage[i].valid) ++n;
+ v &= n == count;
+ v &= check_sibling_list(root);
+ int ct = INT_MAX;
+ n = 0;
+ int f = storage[0].sibling;
+ while (f != 0 && ct-- > 0)
+ {
+ f = storage[f].sibling;
+ ++n;
+ }
+ v &= ct > 0;
+ v &= n <= size - count;
+ if (!v) error("invariant failure");
+ return v;
+}
+
+
+int <T>PHPQ::check_sibling_list(int t)
+{
+ if (t != 0)
+ {
+ int s = t;
+ long ct = LONG_MAX; // Lots of chances to find self!
+ do
+ {
+ if (storage[s].valid && !check_sibling_list(storage[s].children))
+ return 0;
+ s = storage[s].sibling;
+ } while (ct-- > 0 && s != t && s != 0);
+ if (ct <= 0) return 0;
+ }
+ return 1;
+}
+
+
diff --git a/gnu/lib/libg++/include/gen/PHPQ.hP b/gnu/lib/libg++/include/gen/PHPQ.hP
new file mode 100644
index 00000000000..1964ba40dc3
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/PHPQ.hP
@@ -0,0 +1,108 @@
+// 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)
+ 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef <T>PHPQ_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define <T>PHPQ_h 1
+
+#include "<T>.PQ.h"
+
+#ifndef <T>PHPQIndex
+#define <T>PHPQIndex unsigned short
+#endif
+
+struct <T>PHPQNode
+{
+ <T>PHPQIndex sibling;
+ <T>PHPQIndex children;
+ <T> item;
+ char valid;
+};
+
+
+class <T>PHPQ : public <T>PQ
+{
+ <T>PHPQNode* storage; // table -- freelist in storage[0].sibling
+ int root;
+ int size;
+
+ void prealloc(int);
+ int check_sibling_list(int);
+
+public:
+
+ <T>PHPQ(int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>PHPQ(<T>PHPQ&);
+ inline ~<T>PHPQ();
+
+ Pix enq(<T&> item);
+ inline <T> deq();
+
+ inline <T>& front();
+ void del_front();
+
+ inline int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ void del(Pix i);
+ Pix seek(<T&> item);
+
+ int OK(); // rep invariant
+};
+
+
+inline <T>PHPQ::~<T>PHPQ()
+{
+ delete [] storage;
+}
+
+
+inline <T> <T>PHPQ::deq()
+{
+ if (count == 0) error("deq of empty PQ");
+ <T> x = storage[root].item;
+ del_front();
+ return x;
+}
+
+
+inline <T>& <T>PHPQ::front()
+{
+ if (count == 0) error("front of empty PQ");
+ return storage[root].item;
+}
+
+inline int <T>PHPQ::contains(<T&> item)
+{
+ return seek(item) != 0;
+}
+
+inline <T>& <T>PHPQ::operator() (Pix p)
+{
+ if (p == 0) error("null Pix");
+ return storage[int(p)].item;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/PQ.ccP b/gnu/lib/libg++/include/gen/PQ.ccP
new file mode 100644
index 00000000000..ec3bd06210c
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/PQ.ccP
@@ -0,0 +1,63 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include "<T>.PQ.h"
+
+
+
+<T> <T>PQ::deq()
+{
+ <T> x = front();
+ del_front();
+ return x;
+}
+
+Pix <T>PQ::seek(<T&> item)
+{
+ Pix i;
+ for (i = first(); i != 0 && !(<T>EQ((*this)(i), item)); next(i));
+ return i;
+}
+
+int <T>PQ::owns(Pix idx)
+{
+ if (idx == 0) return 0;
+ for (Pix i = first(); i; next(i)) if (i == idx) return 1;
+ return 0;
+}
+
+void <T>PQ::clear()
+{
+ while (count != 0) del_front();
+}
+
+int <T>PQ::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+
+void <T>PQ::error(const char* msg)
+{
+ (*lib_error_handler)("PQ", msg);
+}
+
diff --git a/gnu/lib/libg++/include/gen/PQ.hP b/gnu/lib/libg++/include/gen/PQ.hP
new file mode 100644
index 00000000000..efe18f87e7f
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/PQ.hP
@@ -0,0 +1,78 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>PQ_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>PQ_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T>PQ
+{
+protected:
+
+ int count;
+
+public:
+ <T>PQ();
+ inline virtual ~<T>PQ();
+
+ int length(); // current number of items
+ int empty();
+
+ virtual Pix enq(<T&> item) = 0; // add item; return Pix
+ virtual <T> deq(); // return & remove min
+
+ virtual <T>& front() = 0; // access min item
+ virtual void del_front() = 0; // delete min item
+
+ virtual int contains(<T&> item); // is item in PQ?
+
+ virtual void clear(); // delete all items
+
+ virtual Pix first() = 0; // Pix of first item or 0
+ virtual void next(Pix& i) = 0; // advance to next or 0
+ virtual <T>& operator () (Pix i) = 0; // access item at i
+ virtual void del(Pix i) = 0; // delete item at i
+ virtual int owns(Pix i); // is i a valid Pix ?
+ virtual Pix seek(<T&> item); // Pix of item
+
+ void error(const char* msg);
+ virtual int OK() = 0; // rep invariant
+};
+
+
+inline <T>PQ::<T>PQ() :count(0) {}
+
+inline <T>PQ::~<T>PQ() {}
+
+inline int <T>PQ::length()
+{
+ return count;
+}
+
+inline int <T>PQ::empty()
+{
+ return count == 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/PSList.hP b/gnu/lib/libg++/include/gen/PSList.hP
new file mode 100644
index 00000000000..eacb34dbe35
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/PSList.hP
@@ -0,0 +1,32 @@
+/* : Light weight list: This will simply reuse code from a VoidP List, which
+was genclassed from the SLList libg++ class. The classes generated from this file
+will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not
+offer all the functionality of List classes, such as sharing of sub-lists.
+However, no additional code is needed at all and no .cc file is generated. So it costs nothing
+to use these type-safe lists. Only member functions needing type casting are re-defined */
+
+
+#ifndef _<T>SList_h
+#define _<T>SList_h 1
+
+#include "VoidP.SLList.h"
+#include "<T>.defs.h"
+
+class <T>SList : public VoidPSLList
+{
+public:
+ <T>SList() {}
+ <T>SList(<T>SList& a) : (a) {}
+ ~<T>SList() {}
+
+ <T>SList& operator = (<T>SList& a) {
+ return (<T>SList&) VoidPSLList::operator= (a); }
+
+ <T>& operator () (Pix p) { return (<T>&) (VoidPSLList::operator() (p)); }
+ <T>& front() { return (<T>&) VoidPSLList::front(); }
+ <T>& rear() { return (<T>&) VoidPSLList::rear(); }
+ <T> remove_front() { return (<T>) VoidPSLList::remove_front(); }
+
+};
+
+#endif /* conditional include */
diff --git a/gnu/lib/libg++/include/gen/PVec.hP b/gnu/lib/libg++/include/gen/PVec.hP
new file mode 100644
index 00000000000..de32482610b
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/PVec.hP
@@ -0,0 +1,79 @@
+/* : light weight Vector: This will simply reuse code from */
+/* a VoidP Vec, which was genclassed from the Vec libg++ class. */
+/* The classes generated from this file will all be derived classes */
+/* from class VoidVec or intVec. No .cc file is generated. So */
+/* it costs nothing to use these type-safe Vectors. Only member */
+/* functions needing type casting are re-defined. */
+/* */
+
+#ifndef _<T>Vec_h
+#define _<T>Vec_h 1
+
+#include "VoidP.Vec.h"
+#include "<T>.defs.h"
+
+
+#ifndef _<T>_typedefs
+#define _<T>_typedefs 1
+typedef void (*<T>Procedure)(<T> );
+typedef <T> (*<T>Mapper)(<T> );
+typedef <T> (*<T>Combiner)(<T> , <T> );
+typedef int (*<T>Predicate)(<T> );
+typedef int (*<T>Comparator)(<T> , <T> );
+#endif
+
+class <T>Vec : public VoidPVec
+{
+protected:
+ <T>Vec(int l, <T>* d) : (l, (VoidP*) d) {};
+public:
+ <T>Vec() {};
+ <T>Vec(int l) : (l) {};
+ <T>Vec(int l, <T&> fill_value) : (l, fill_value) {};
+ <T>Vec(<T>Vec& v) : (v) {};
+ <T>Vec(VoidPVec& v) {fake_copy(v, s, len);}
+ ~<T>Vec() {};
+
+ <T>Vec& operator = (<T>Vec& a)
+ {return (<T>Vec&) VoidPVec::operator= (a);}
+ <T>Vec at(int from, int n) {return (<T>Vec) VoidPVec::at(from, n);}
+
+ <T>& operator [] (int n) {return (<T>&)VoidPVec::operator[] (n);}
+ <T>& elem(int n) {return (<T>&)VoidPVec::elem(n);}
+
+ friend <T>Vec concat(<T>Vec& a, <T>Vec& b);
+ friend <T>Vec map(<T>Mapper f, <T>Vec & a);
+ friend <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f);
+ friend <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b);
+ friend <T>Vec reverse(<T>Vec& a);
+
+ void sort(<T>Comparator f);
+ void apply(<T>Procedure f);
+ <T> reduce(<T>Combiner f, <T> base);
+};
+
+inline <T>Vec concat(<T>Vec& a, <T>Vec& b)
+{return (<T>Vec)concat((VoidPVec&)a, (VoidPVec&)b);}
+
+inline <T>Vec map(<T>Mapper f, <T>Vec & a) {
+ return (<T>Vec)map((VoidPMapper)f, (VoidPVec&)a); }
+
+inline <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f) {
+ return (<T>Vec)merge((VoidPVec&)a, (VoidPVec&)b, (VoidPComparator)f); }
+
+inline <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b) {
+ return (<T>Vec)combine((VoidPCombiner)f, (VoidPVec&)a, (VoidPVec&)b); }
+
+inline <T>Vec reverse(<T>Vec& a) {
+ return (<T>Vec)reverse((VoidPVec&)a);}
+
+inline void <T>Vec::sort(<T>Comparator f) {
+ VoidPVec::sort((VoidPComparator) f); }
+
+inline void <T>Vec::apply(<T>Procedure f) {
+ VoidPVec::apply((VoidPProcedure) f); }
+
+inline <T> <T>Vec::reduce(<T>Combiner f, <T> base) {
+ return (<T>)VoidPVec::reduce((VoidPCombiner)f, base);}
+
+#endif /* conditional include */
diff --git a/gnu/lib/libg++/include/gen/Plex.ccP b/gnu/lib/libg++/include/gen/Plex.ccP
new file mode 100644
index 00000000000..9a62571aca0
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Plex.ccP
@@ -0,0 +1,222 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <builtin.h>
+#include "<T>.Plex.h"
+
+// IChunk support
+
+void <T>IChunk::error(const char* msg) const
+{
+ (*lib_error_handler)("<T>IChunk", msg);
+}
+
+void <T>IChunk::index_error() const
+{
+ error("attempt to use invalid index");
+}
+
+void <T>IChunk::empty_error() const
+{
+ error("invalid use of empty chunk");
+}
+
+void <T>IChunk::full_error() const
+{
+ error("attempt to extend chunk beyond bounds");
+}
+
+<T>IChunk:: ~<T>IChunk() {}
+
+<T>IChunk::<T>IChunk(<T>* d,
+ int baseidx,
+ int lowidx,
+ int fenceidx,
+ int topidx)
+{
+ if (d == 0 || baseidx > lowidx || lowidx > fenceidx || fenceidx > topidx)
+ error("inconsistent specification");
+ data = d;
+ base = baseidx;
+ low = lowidx;
+ fence = fenceidx;
+ top = topidx;
+ nxt = prv = this;
+}
+
+void <T>IChunk:: re_index(int lo)
+{
+ int delta = lo - low;
+ base += delta;
+ low += delta;
+ fence += delta;
+ top += delta;
+}
+
+
+void <T>IChunk::clear(int lo)
+{
+ int s = top - base;
+ low = base = fence = lo;
+ top = base + s;
+}
+
+void <T>IChunk::cleardown(int hi)
+{
+ int s = top - base;
+ low = top = fence = hi;
+ base = top - s;
+}
+
+int <T>IChunk:: OK() const
+{
+ int v = data != 0; // have some data
+ v &= base <= low; // ok, index-wise
+ v &= low <= fence;
+ v &= fence <= top;
+
+ v &= nxt->prv == this; // and links are OK
+ v &= prv->nxt == this;
+ if (!v) error("invariant failure");
+ return(v);
+}
+
+
+// error handling
+
+
+void <T>Plex::error(const char* msg) const
+{
+ (*lib_error_handler)("Plex", msg);
+}
+
+void <T>Plex::index_error() const
+{
+ error("attempt to access invalid index");
+}
+
+void <T>Plex::empty_error() const
+{
+ error("attempted operation on empty plex");
+}
+
+void <T>Plex::full_error() const
+{
+ error("attempt to increase size of plex past limit");
+}
+
+// generic plex ops
+
+<T>Plex:: ~<T>Plex()
+{
+ invalidate();
+}
+
+
+void <T>Plex::append (const <T>Plex& a)
+{
+ for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
+}
+
+void <T>Plex::prepend (const <T>Plex& a)
+{
+ for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]);
+}
+
+void <T>Plex::reverse()
+{
+ <T> tmp;
+ int l = low();
+ int h = high();
+ while (l < h)
+ {
+ tmp = (*this)[l];
+ (*this)[l] = (*this)[h];
+ (*this)[h] = tmp;
+ next(l);
+ prev(h);
+ }
+}
+
+
+void <T>Plex::fill(const <T&> x)
+{
+ for (int i = lo; i < fnc; ++i) (*this)[i] = x;
+}
+
+void <T>Plex::fill(const <T&> x, int lo, int hi)
+{
+ for (int i = lo; i <= hi; ++i) (*this)[i] = x;
+}
+
+
+void <T>Plex::del_chunk(<T>IChunk* x)
+{
+ if (x != 0)
+ {
+ x->unlink();
+ <T>* data = (<T>*)(x->invalidate());
+ delete [] data;
+ delete x;
+ }
+}
+
+
+void <T>Plex::invalidate()
+{
+ <T>IChunk* t = hd;
+ if (t != 0)
+ {
+ <T>IChunk* tail = tl();
+ while (t != tail)
+ {
+ <T>IChunk* nxt = t->next();
+ del_chunk(t);
+ t = nxt;
+ }
+ del_chunk(t);
+ hd = 0;
+ }
+}
+
+int <T>Plex::reset_low(int l)
+{
+ int old = lo;
+ int diff = l - lo;
+ if (diff != 0)
+ {
+ lo += diff;
+ fnc += diff;
+ <T>IChunk* t = hd;
+ do
+ {
+ t->re_index(t->low_index() + diff);
+ t = t->next();
+ } while (t != hd);
+ }
+ return old;
+}
+
+
+
+
diff --git a/gnu/lib/libg++/include/gen/Plex.hP b/gnu/lib/libg++/include/gen/Plex.hP
new file mode 100644
index 00000000000..d756167b15a
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Plex.hP
@@ -0,0 +1,494 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>Plex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Plex_h 1
+
+#include <std.h>
+#include <Pix.h>
+#include "<T>.defs.h"
+
+// Plexes are made out of <T>IChunks
+
+#include <stddef.h>
+
+class <T>IChunk
+{
+//public: // kludge until C++ `protected' policies settled
+protected:
+
+ <T>* data; // data, from client
+
+ int base; // lowest possible index
+ int low; // lowest valid index
+ int fence; // highest valid index + 1
+ int top; // highest possible index + 1
+
+ <T>IChunk* nxt; // circular links
+ <T>IChunk* prv;
+
+public:
+
+// constructors
+
+ <T>IChunk(<T>* d, // ptr to array of elements
+ int base_idx, // initial indices
+ int low_idx,
+ int fence_idx,
+ int top_idx);
+
+ virtual ~<T>IChunk();
+
+// status reports
+
+ int size() const; // number of slots
+
+ inline virtual int empty() const ;
+ inline virtual int full() const ;
+
+ int can_grow_high () const ; // there is space to add data
+ int can_grow_low () const;
+
+ int base_index() const; // lowest possible index;
+ int low_index() const; // lowest actual index;
+ inline virtual int first_index() const; // lowest valid index or fence if none
+ inline virtual int last_index() const; // highest valid index or low-1 if none
+ int fence_index() const; // highest actual index + 1
+ int top_index() const; // highest possible index + 1
+
+// indexing conversion
+
+ int possible_index(int i) const; // i between base and top
+ int actual_index(int i) const; // i between low and fence
+ inline virtual int valid_index(int i) const; // i not deleted (mainly for mchunks)
+
+ int possible_pointer(const <T>* p) const; // same for ptr
+ int actual_pointer(const <T>* p) const;
+ inline virtual int valid_pointer(const <T>* p) const;
+
+ <T>* pointer_to(int i) const ; // pointer to data indexed by i
+ // caution: i is not checked for validity
+ int index_of(const <T>* p) const; // index of data pointed to by p
+ // caution: p is not checked for validity
+
+ inline virtual int succ(int idx) const; // next valid index or fence if none
+ inline virtual int pred(int idx) const; // previous index or low - 1 if none
+
+ inline virtual <T>* first_pointer() const; // pointer to first valid pos or 0
+ inline virtual <T>* last_pointer() const; // pointer to first valid pos or 0
+ inline virtual <T>* succ(<T>* p) const; // next pointer or 0
+ inline virtual <T>* pred(<T>* p) const; // previous pointer or 0
+
+// modification
+
+ inline virtual <T>* grow_high (); // return spot to add an element
+ inline virtual <T>* grow_low ();
+
+ inline virtual void shrink_high (); // logically delete top index
+ inline virtual void shrink_low ();
+
+ virtual void clear(int lo); // reset to empty ch with base = lo
+ virtual void cleardown(int hi); // reset to empty ch with top = hi
+ void re_index(int lo); // re-index so lo is new low
+
+// chunk traversal
+
+ <T>IChunk* next() const;
+ <T>IChunk* prev() const;
+
+ void link_to_prev(<T>IChunk* prev);
+ void link_to_next(<T>IChunk* next);
+ void unlink();
+
+// state checks
+
+ <T>* invalidate(); // mark self as invalid; return data
+ // for possible deletion
+
+ virtual int OK() const; // representation invariant
+
+ void error(const char*) const;
+ void empty_error() const;
+ void full_error() const;
+ void index_error() const;
+};
+
+// <T>Plex is a partly `abstract' class: few of the virtuals
+// are implemented at the Plex level, only in the subclasses
+
+class <T>Plex
+{
+protected:
+
+ <T>IChunk* hd; // a chunk holding the data
+ int lo; // lowest index
+ int fnc; // highest index + 1
+ int csize; // size of the chunk
+
+ void invalidate(); // mark so OK() is false
+ void del_chunk(<T>IChunk*); // delete a chunk
+
+ <T>IChunk* tl() const; // last chunk;
+ int one_chunk() const; // true if hd == tl()
+
+public:
+
+// constructors, etc.
+
+ <T>Plex(); // no-op
+
+ virtual ~<T>Plex();
+
+
+// Access functions
+
+ virtual <T>& operator [] (int idx) = 0; // access by index;
+ virtual <T>& operator () (Pix p) = 0; // access by Pix;
+
+ virtual <T>& high_element () = 0; // access high element
+ virtual <T>& low_element () = 0; // access low element
+
+// read-only versions for const Plexes
+
+ virtual const <T>& operator [] (int idx) const = 0; // access by index;
+ virtual const <T>& operator () (Pix p) const = 0; // access by Pix;
+
+ virtual const <T>& high_element () const = 0; // access high element
+ virtual const <T>& low_element () const = 0; // access low element
+
+
+// Index functions
+
+ virtual int valid (int idx) const = 0; // idx is an OK index
+
+ virtual int low() const = 0; // lowest index or fence if none
+ virtual int high() const = 0; // highest index or low-1 if none
+
+ int ecnef() const; // low limit index (low-1)
+ int fence() const; // high limit index (high+1)
+
+ virtual void prev(int& idx) const= 0; // set idx to preceding index
+ // caution: pred may be out of bounds
+
+ virtual void next(int& idx) const = 0; // set to next index
+ // caution: succ may be out of bounds
+
+ virtual Pix first() const = 0; // Pix to low element or 0
+ virtual Pix last() const = 0; // Pix to high element or 0
+ virtual void prev(Pix& pix) const = 0; // preceding pix or 0
+ virtual void next(Pix& pix) const = 0; // next pix or 0
+ virtual int owns(Pix p) const = 0; // p is an OK Pix
+
+// index<->Pix
+
+ virtual int Pix_to_index(Pix p) const = 0; // get index via Pix
+ virtual Pix index_to_Pix(int idx) const = 0; // Pix via index
+
+// Growth
+
+ virtual int add_high(const <T&> elem) =0;// add new element at high end
+ // return new high
+
+ virtual int add_low(const <T&> elem) = 0; // add new low element,
+ // return new low
+
+// Shrinkage
+
+ virtual int del_high() = 0; // remove the element at high end
+ // return new high
+ virtual int del_low() = 0; // delete low element, return new lo
+
+ // caution: del_low/high
+ // does not necessarily
+ // immediately call <T>::~<T>
+
+
+// operations on multiple elements
+
+ virtual void fill(const <T&> x); // set all elements = x
+ virtual void fill(const <T&> x, int from, int to); // fill from to to
+ virtual void clear() = 0; // reset to zero-sized Plex
+ virtual int reset_low(int newlow); // change low index,return old
+ virtual void reverse(); // reverse in-place
+ virtual void append(const <T>Plex& a); // concatenate a copy
+ virtual void prepend(const <T>Plex& a); // prepend a copy
+
+// status
+
+ virtual int can_add_high() const = 0;
+ virtual int can_add_low() const = 0;
+
+ int length () const; // number of slots
+
+ int empty () const; // is the plex empty?
+ virtual int full() const = 0; // it it full?
+
+ int chunk_size() const; // report chunk size;
+
+ virtual int OK() const = 0; // representation invariant
+
+ void error(const char* msg) const;
+ void index_error() const;
+ void empty_error() const;
+ void full_error() const;
+};
+
+
+// <T>IChunk ops
+
+inline int <T>IChunk:: size() const
+{
+ return top - base;
+}
+
+
+inline int <T>IChunk:: base_index() const
+{
+ return base;
+}
+
+inline int <T>IChunk:: low_index() const
+{
+ return low;
+}
+
+inline int <T>IChunk:: fence_index() const
+{
+ return fence;
+}
+
+inline int <T>IChunk:: top_index() const
+{
+ return top;
+}
+
+inline <T>* <T>IChunk:: pointer_to(int i) const
+{
+ return &(data[i-base]);
+}
+
+inline int <T>IChunk:: index_of(const <T>* p) const
+{
+ return ((int)p - (int)data) / sizeof(<T>) + base;
+}
+
+inline int <T>IChunk:: possible_index(int i) const
+{
+ return i >= base && i < top;
+}
+
+inline int <T>IChunk:: possible_pointer(const <T>* p) const
+{
+ return p >= data && p < &(data[top-base]);
+}
+
+inline int <T>IChunk:: actual_index(int i) const
+{
+ return i >= low && i < fence;
+}
+
+inline int <T>IChunk:: actual_pointer(const <T>* p) const
+{
+ return p >= data && p < &(data[fence-base]);
+}
+
+inline int <T>IChunk:: can_grow_high () const
+{
+ return fence < top;
+}
+
+inline int <T>IChunk:: can_grow_low () const
+{
+ return base < low;
+}
+
+inline <T>* <T>IChunk:: invalidate()
+{
+ <T>* p = data;
+ data = 0;
+ return p;
+}
+
+
+inline <T>IChunk* <T>IChunk::prev() const
+{
+ return prv;
+}
+
+inline <T>IChunk* <T>IChunk::next() const
+{
+ return nxt;
+}
+
+inline void <T>IChunk::link_to_prev(<T>IChunk* prev)
+{
+ nxt = prev->nxt;
+ prv = prev;
+ nxt->prv = this;
+ prv->nxt = this;
+}
+
+inline void <T>IChunk::link_to_next(<T>IChunk* next)
+{
+ prv = next->prv;
+ nxt = next;
+ nxt->prv = this;
+ prv->nxt = this;
+}
+
+inline void <T>IChunk::unlink()
+{
+ <T>IChunk* n = nxt;
+ <T>IChunk* p = prv;
+ n->prv = p;
+ p->nxt = n;
+ prv = nxt = this;
+}
+
+inline int <T>IChunk:: empty() const
+{
+ return low == fence;
+}
+
+inline int <T>IChunk:: full() const
+{
+ return top - base == fence - low;
+}
+
+inline int <T>IChunk:: first_index() const
+{
+ return (low == fence)? fence : low;
+}
+
+inline int <T>IChunk:: last_index() const
+{
+ return (low == fence)? low - 1 : fence - 1;
+}
+
+inline int <T>IChunk:: succ(int i) const
+{
+ return (i < low) ? low : i + 1;
+}
+
+inline int <T>IChunk:: pred(int i) const
+{
+ return (i > fence) ? (fence - 1) : i - 1;
+}
+
+inline int <T>IChunk:: valid_index(int i) const
+{
+ return i >= low && i < fence;
+}
+
+inline int <T>IChunk:: valid_pointer(const <T>* p) const
+{
+ return p >= &(data[low - base]) && p < &(data[fence - base]);
+}
+
+inline <T>* <T>IChunk:: grow_high ()
+{
+ if (!can_grow_high()) full_error();
+ return &(data[fence++ - base]);
+}
+
+inline <T>* <T>IChunk:: grow_low ()
+{
+ if (!can_grow_low()) full_error();
+ return &(data[--low - base]);
+}
+
+inline void <T>IChunk:: shrink_high ()
+{
+ if (empty()) empty_error();
+ --fence;
+}
+
+inline void <T>IChunk:: shrink_low ()
+{
+ if (empty()) empty_error();
+ ++low;
+}
+
+inline <T>* <T>IChunk::first_pointer() const
+{
+ return (low == fence)? 0 : &(data[low - base]);
+}
+
+inline <T>* <T>IChunk::last_pointer() const
+{
+ return (low == fence)? 0 : &(data[fence - base - 1]);
+}
+
+inline <T>* <T>IChunk::succ(<T>* p) const
+{
+ return ((p+1) < &(data[low - base]) || (p+1) >= &(data[fence - base])) ?
+ 0 : (p+1);
+}
+
+inline <T>* <T>IChunk::pred(<T>* p) const
+{
+ return ((p-1) < &(data[low - base]) || (p-1) >= &(data[fence - base])) ?
+ 0 : (p-1);
+}
+
+
+// generic Plex operations
+
+inline <T>Plex::<T>Plex() {}
+
+inline int <T>Plex::chunk_size() const
+{
+ return csize;
+}
+
+inline int <T>Plex::ecnef () const
+{
+ return lo - 1;
+}
+
+
+inline int <T>Plex::fence () const
+{
+ return fnc;
+}
+
+inline int <T>Plex::length () const
+{
+ return fnc - lo;
+}
+
+inline int <T>Plex::empty () const
+{
+ return fnc == lo;
+}
+
+inline <T>IChunk* <T>Plex::tl() const
+{
+ return hd->prev();
+}
+
+inline int <T>Plex::one_chunk() const
+{
+ return hd == hd->prev();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Queue.ccP b/gnu/lib/libg++/include/gen/Queue.ccP
new file mode 100644
index 00000000000..fb48d952ff7
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Queue.ccP
@@ -0,0 +1,14 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.Queue.h"
+
+<T>Queue::~<T>Queue() {}
+
+
+// error handling
+
+void <T>Queue::error(const char* msg)
+{
+ (*lib_error_handler)("Queue", msg);
+}
diff --git a/gnu/lib/libg++/include/gen/Queue.hP b/gnu/lib/libg++/include/gen/Queue.hP
new file mode 100644
index 00000000000..c7e05ac6124
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Queue.hP
@@ -0,0 +1,51 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>Queue_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Queue_h
+
+#include <builtin.h>
+
+#include "<T>.defs.h"
+
+class <T>Queue
+{
+public:
+ <T>Queue() { }
+ virtual ~<T>Queue();
+
+ virtual void enq(<T&> item) = 0;
+ virtual <T> deq() = 0;
+ virtual <T>& front() = 0;
+ virtual void del_front() = 0;
+
+ virtual void clear() = 0;
+ virtual int empty() = 0;
+ virtual int full() = 0;
+ virtual int length() = 0;
+
+ void error(const char*);
+
+ virtual int OK() = 0;
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/RAVLMap.ccP b/gnu/lib/libg++/include/gen/RAVLMap.ccP
new file mode 100644
index 00000000000..9477250a6e6
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/RAVLMap.ccP
@@ -0,0 +1,690 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.<C>.RAVLMap.h"
+
+
+/*
+ constants & inlines for maintaining balance & thread status in tree nodes
+*/
+
+#define AVLBALANCEMASK 3
+#define AVLBALANCED 0
+#define AVLLEFTHEAVY 1
+#define AVLRIGHTHEAVY 2
+
+#define LTHREADBIT 4
+#define RTHREADBIT 8
+
+
+static inline int bf(<T><C>RAVLNode* t)
+{
+ return t->stat & AVLBALANCEMASK;
+}
+
+static inline void set_bf(<T><C>RAVLNode* t, int b)
+{
+ t->stat = (t->stat & ~AVLBALANCEMASK) | (b & AVLBALANCEMASK);
+}
+
+
+static inline int rthread(<T><C>RAVLNode* t)
+{
+ return t->stat & RTHREADBIT;
+}
+
+static inline void set_rthread(<T><C>RAVLNode* t, int b)
+{
+ if (b)
+ t->stat |= RTHREADBIT;
+ else
+ t->stat &= ~RTHREADBIT;
+}
+
+static inline int lthread(<T><C>RAVLNode* t)
+{
+ return t->stat & LTHREADBIT;
+}
+
+static inline void set_lthread(<T><C>RAVLNode* t, int b)
+{
+ if (b)
+ t->stat |= LTHREADBIT;
+ else
+ t->stat &= ~LTHREADBIT;
+}
+
+/*
+ traversal primitives
+*/
+
+
+<T><C>RAVLNode* <T><C>RAVLMap::leftmost()
+{
+ <T><C>RAVLNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T><C>RAVLNode* <T><C>RAVLMap::rightmost()
+{
+ <T><C>RAVLNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T><C>RAVLNode* <T><C>RAVLMap::succ(<T><C>RAVLNode* t)
+{
+ <T><C>RAVLNode* r = t->rt;
+ if (!rthread(t)) while (!lthread(r)) r = r->lt;
+ return r;
+}
+
+<T><C>RAVLNode* <T><C>RAVLMap::pred(<T><C>RAVLNode* t)
+{
+ <T><C>RAVLNode* l = t->lt;
+ if (!lthread(t)) while (!rthread(l)) l = l->rt;
+ return l;
+}
+
+
+Pix <T><C>RAVLMap::seek(<T&> key)
+{
+ <T><C>RAVLNode* t = root;
+ if (t == 0)
+ return 0;
+ for (;;)
+ {
+ int cmp = <T>CMP(key, t->item);
+ if (cmp == 0)
+ return Pix(t);
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ return 0;
+ else
+ t = t->lt;
+ }
+ else if (rthread(t))
+ return 0;
+ else
+ t = t->rt;
+ }
+}
+
+
+int <T><C>RAVLMap::rankof(<T&> key)
+{
+ int r;
+ <T><C>RAVLNode* t = root;
+ if (t == 0)
+ return 0;
+ for (r=t->rank; t != 0; r+=t->rank)
+ {
+ int cmp = <T>CMP(key, t->item);
+ if (cmp == 0)
+ return r;
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ return 0;
+ else
+ {
+ r -= t->rank;
+ t = t->lt;
+ }
+ }
+ else if (rthread(t))
+ return 0;
+ else
+ {
+ t = t->rt;
+ }
+ }
+ return 0;
+}
+
+Pix <T><C>RAVLMap::ranktoPix(int i)
+{
+ int r;
+ <T><C>RAVLNode* t = root;
+
+ if ((i<1)||(i>count))
+ return 0;
+ for (r=t->rank; r!=i; r+=t->rank)
+ {
+ if (r>i)
+ {
+ r -= t->rank;
+ t = t->lt;
+ }
+ else
+ t = t->rt;
+ }
+ return Pix(t);
+}
+
+/*
+ The combination of threads and AVL bits make adding & deleting
+ interesting, but very awkward.
+
+ We use the following statics to avoid passing them around recursively
+*/
+
+static int _need_rebalancing; // to send back balance info from rec. calls
+static <T>* _target_item; // add/del_item target
+static <T><C>RAVLNode* _found_node; // returned added/deleted node
+static int _already_found; // for deletion subcases
+static int _rank_changed; // for rank computation
+
+
+void <T><C>RAVLMap:: _add(<T><C>RAVLNode*& t)
+{
+ int cmp = <T>CMP(*_target_item, t->item);
+ if (cmp == 0)
+ {
+ _found_node = t;
+ return;
+ }
+ else if (cmp < 0)
+ {
+ if (lthread(t))
+ {
+ ++count;
+ _found_node = new <T><C>RAVLNode(*_target_item, def);
+ set_lthread(_found_node, 1);
+ set_rthread(_found_node, 1);
+ _found_node->lt = t->lt;
+ _found_node->rt = t;
+ t->lt = _found_node;
+ set_lthread(t, 0);
+ _need_rebalancing = 1;
+ _rank_changed = 1;
+ }
+ else
+ _add(t->lt);
+ if (_rank_changed) ++t->rank;
+ if (_need_rebalancing)
+ {
+ switch(bf(t))
+ {
+ case AVLRIGHTHEAVY:
+ set_bf(t, AVLBALANCED);
+ _need_rebalancing = 0;
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLLEFTHEAVY);
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T><C>RAVLNode* l = t->lt;
+ if (bf(l) == AVLLEFTHEAVY)
+ {
+ t->rank -= l->rank;
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ _need_rebalancing = 0;
+ }
+ else
+ {
+ <T><C>RAVLNode* r = l->rt;
+ r->rank += l->rank;
+ t->rank -= r->rank;
+ set_rthread(l, lthread(r));
+ if (lthread(r))
+ l->rt = r;
+ else
+ l->rt = r->lt;
+ r->lt = l;
+ set_lthread(r, 0);
+ set_lthread(t, rthread(r));
+ if (rthread(r))
+ t->lt = r;
+ else
+ t->lt = r->rt;
+ r->rt = t;
+ set_rthread(r, 0);
+ if (bf(r) == AVLLEFTHEAVY)
+ set_bf(t, AVLRIGHTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(r) == AVLRIGHTHEAVY)
+ set_bf(l, AVLLEFTHEAVY);
+ else
+ set_bf(l, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ _need_rebalancing = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (rthread(t))
+ {
+ ++count;
+ _found_node = new <T><C>RAVLNode(*_target_item, def);
+ set_rthread(t, 0);
+ set_lthread(_found_node, 1);
+ set_rthread(_found_node, 1);
+ _found_node->lt = t;
+ _found_node->rt = t->rt;
+ t->rt = _found_node;
+ _need_rebalancing = 1;
+ _rank_changed = 1;
+ }
+ else
+ _add(t->rt);
+ if (_need_rebalancing)
+ {
+ switch(bf(t))
+ {
+ case AVLLEFTHEAVY:
+ set_bf(t, AVLBALANCED);
+ _need_rebalancing = 0;
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLRIGHTHEAVY);
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T><C>RAVLNode* r = t->rt;
+ if (bf(r) == AVLRIGHTHEAVY)
+ {
+ r->rank += t->rank;
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ _need_rebalancing = 0;
+ }
+ else
+ {
+ <T><C>RAVLNode* l = r->lt;
+ r->rank -= l->rank;
+ l->rank += t->rank;
+ set_lthread(r, rthread(l));
+ if (rthread(l))
+ r->lt = l;
+ else
+ r->lt = l->rt;
+ l->rt = r;
+ set_rthread(l, 0);
+ set_rthread(t, lthread(l));
+ if (lthread(l))
+ t->rt = l;
+ else
+ t->rt = l->lt;
+ l->lt = t;
+ set_lthread(l, 0);
+ if (bf(l) == AVLRIGHTHEAVY)
+ set_bf(t, AVLLEFTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(l) == AVLLEFTHEAVY)
+ set_bf(r, AVLRIGHTHEAVY);
+ else
+ set_bf(r, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ _need_rebalancing = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+<C>& <T><C>RAVLMap::operator [] (<T&> item)
+{
+ if (root == 0)
+ {
+ ++count;
+ root = new <T><C>RAVLNode(item, def);
+ set_rthread(root, 1);
+ set_lthread(root, 1);
+ return root->cont;
+ }
+ else
+ {
+ _target_item = &item;
+ _need_rebalancing = 0;
+ _rank_changed = 0;
+ _add(root);
+ return _found_node->cont;
+ }
+}
+
+
+void <T><C>RAVLMap::_del(<T><C>RAVLNode* par, <T><C>RAVLNode*& t)
+{
+ int comp;
+ if (_already_found)
+ {
+ if (rthread(t))
+ comp = 0;
+ else
+ comp = 1;
+ }
+ else
+ comp = <T>CMP(*_target_item, t->item);
+ if (comp == 0)
+ {
+ if (lthread(t) && rthread(t))
+ {
+ _found_node = t;
+ if (t == par->lt)
+ {
+ set_lthread(par, 1);
+ par->lt = t->lt;
+ }
+ else
+ {
+ set_rthread(par, 1);
+ par->rt = t->rt;
+ }
+ _need_rebalancing = 1;
+ _rank_changed = 1;
+ return;
+ }
+ else if (lthread(t))
+ {
+ _found_node = t;
+ <T><C>RAVLNode* s = succ(t);
+ if (s != 0 && lthread(s))
+ s->lt = t->lt;
+ t = t->rt;
+ _need_rebalancing = 1;
+ _rank_changed = 1;
+ return;
+ }
+ else if (rthread(t))
+ {
+ _found_node = t;
+ <T><C>RAVLNode* p = pred(t);
+ if (p != 0 && rthread(p))
+ p->rt = t->rt;
+ t = t->lt;
+ _need_rebalancing = 1;
+ _rank_changed = 1;
+ return;
+ }
+ else // replace item & find someone deletable
+ {
+ <T><C>RAVLNode* p = pred(t);
+ t->item = p->item;
+ t->cont = p->cont;
+ _already_found = 1;
+ comp = -1; // fall through below to left
+ }
+ }
+
+ if (comp < 0)
+ {
+ if (lthread(t))
+ return;
+ _del(t, t->lt);
+ if (_rank_changed) --t->rank;
+ if (!_need_rebalancing)
+ return;
+ switch (bf(t))
+ {
+ case AVLLEFTHEAVY:
+ set_bf(t, AVLBALANCED);
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLRIGHTHEAVY);
+ _need_rebalancing = 0;
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T><C>RAVLNode* r = t->rt;
+ switch (bf(r))
+ {
+ case AVLBALANCED:
+ r->rank += t->rank;
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLRIGHTHEAVY);
+ set_bf(r, AVLLEFTHEAVY);
+ _need_rebalancing = 0;
+ t = r;
+ return;
+ case AVLRIGHTHEAVY:
+ r->rank += t->rank;
+ if (lthread(r))
+ t->rt = r;
+ else
+ t->rt = r->lt;
+ set_rthread(t, lthread(r));
+ r->lt = t;
+ set_lthread(r, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T><C>RAVLNode* l = r->lt;
+ r->rank -= l->rank;
+ l->rank += t->rank;
+ set_lthread(r, rthread(l));
+ if (rthread(l))
+ r->lt = l;
+ else
+ r->lt = l->rt;
+ l->rt = r;
+ set_rthread(l, 0);
+ set_rthread(t, lthread(l));
+ if (lthread(l))
+ t->rt = l;
+ else
+ t->rt = l->lt;
+ l->lt = t;
+ set_lthread(l, 0);
+ if (bf(l) == AVLRIGHTHEAVY)
+ set_bf(t, AVLLEFTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(l) == AVLLEFTHEAVY)
+ set_bf(r, AVLRIGHTHEAVY);
+ else
+ set_bf(r, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ return;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (rthread(t))
+ return;
+ _del(t, t->rt);
+ if (!_need_rebalancing)
+ return;
+ switch (bf(t))
+ {
+ case AVLRIGHTHEAVY:
+ set_bf(t, AVLBALANCED);
+ return;
+ case AVLBALANCED:
+ set_bf(t, AVLLEFTHEAVY);
+ _need_rebalancing = 0;
+ return;
+ case AVLLEFTHEAVY:
+ {
+ <T><C>RAVLNode* l = t->lt;
+ switch (bf(l))
+ {
+ case AVLBALANCED:
+ t->rank -= l->rank;
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLLEFTHEAVY);
+ set_bf(l, AVLRIGHTHEAVY);
+ _need_rebalancing = 0;
+ t = l;
+ return;
+ case AVLLEFTHEAVY:
+ t->rank -= l->rank;
+ if (rthread(l))
+ t->lt = l;
+ else
+ t->lt = l->rt;
+ set_lthread(t, rthread(l));
+ l->rt = t;
+ set_rthread(l, 0);
+ set_bf(t, AVLBALANCED);
+ set_bf(l, AVLBALANCED);
+ t = l;
+ return;
+ case AVLRIGHTHEAVY:
+ {
+ <T><C>RAVLNode* r = l->rt;
+ r->rank += l->rank;
+ t->rank -= r->rank;
+ set_rthread(l, lthread(r));
+ if (lthread(r))
+ l->rt = r;
+ else
+ l->rt = r->lt;
+ r->lt = l;
+ set_lthread(r, 0);
+ set_lthread(t, rthread(r));
+ if (rthread(r))
+ t->lt = r;
+ else
+ t->lt = r->rt;
+ r->rt = t;
+ set_rthread(r, 0);
+ if (bf(r) == AVLLEFTHEAVY)
+ set_bf(t, AVLRIGHTHEAVY);
+ else
+ set_bf(t, AVLBALANCED);
+ if (bf(r) == AVLRIGHTHEAVY)
+ set_bf(l, AVLLEFTHEAVY);
+ else
+ set_bf(l, AVLBALANCED);
+ set_bf(r, AVLBALANCED);
+ t = r;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void <T><C>RAVLMap::del(<T&> item)
+{
+ if (root == 0) return;
+ _need_rebalancing = 0;
+ _already_found = 0;
+ _found_node = 0;
+ _rank_changed = 0;
+ _target_item = &item;
+ _del(root, root);
+ if (_found_node)
+ {
+ delete(_found_node);
+ if (--count == 0)
+ root = 0;
+ }
+}
+
+void <T><C>RAVLMap::_kill(<T><C>RAVLNode* t)
+{
+ if (t != 0)
+ {
+ if (!lthread(t)) _kill(t->lt);
+ if (!rthread(t)) _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T><C>RAVLMap::<T><C>RAVLMap(<T><C>RAVLMap& b) :<T><C>Map(b.def)
+{
+ root = 0;
+ count = 0;
+ for (Pix i = b.first(); i != 0; b.next(i))
+ (*this)[b.key(i)] = b.contents(i);
+}
+
+
+int <T><C>RAVLMap::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T><C>RAVLNode* trail = leftmost();
+ v &= rankof(trail->item) == n;
+ <T><C>RAVLNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ v &= rankof(t->item) == n;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/RAVLMap.hP b/gnu/lib/libg++/include/gen/RAVLMap.hP
new file mode 100644
index 00000000000..1009ef1a9a5
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/RAVLMap.hP
@@ -0,0 +1,147 @@
+// 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)
+ ranking code from Paul Anderson (paul%lfcs.ed.ac.uk)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T><C>RAVLMap_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>RAVLMap_h 1
+
+#include "<T>.<C>.Map.h"
+
+struct <T><C>RAVLNode
+{
+ <T><C>RAVLNode* lt;
+ <T><C>RAVLNode* rt;
+ <T> item;
+ <C> cont;
+ int rank;
+ char stat;
+ <T><C>RAVLNode(<T&> h, <C&> c,
+ <T><C>RAVLNode* l=0, <T><C>RAVLNode* r=0, int k=1);
+ ~<T><C>RAVLNode();
+};
+
+inline <T><C>RAVLNode::<T><C>RAVLNode(<T&> h, <C&> c,
+ <T><C>RAVLNode* l, <T><C>RAVLNode* r, int k)
+ :lt(l), rt(r), item(h), cont(c), rank(k), stat(0) {}
+
+inline <T><C>RAVLNode::~<T><C>RAVLNode() {}
+
+typedef <T><C>RAVLNode* <T><C>RAVLNodePtr;
+
+
+class <T><C>RAVLMap : public <T><C>Map
+{
+protected:
+ <T><C>RAVLNode* root;
+
+ <T><C>RAVLNode* leftmost();
+ <T><C>RAVLNode* rightmost();
+ <T><C>RAVLNode* pred(<T><C>RAVLNode* t);
+ <T><C>RAVLNode* succ(<T><C>RAVLNode* t);
+ void _kill(<T><C>RAVLNode* t);
+ void _add(<T><C>RAVLNode*& t);
+ void _del(<T><C>RAVLNode* p, <T><C>RAVLNode*& t);
+
+public:
+ <T><C>RAVLMap(<C&> dflt);
+ <T><C>RAVLMap(<T><C>RAVLMap& a);
+ inline ~<T><C>RAVLMap();
+
+ <C>& operator [] (<T&> key);
+
+ void del(<T&> key);
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& key(Pix i);
+ inline <C>& contents(Pix i);
+
+ Pix seek(<T&> key);
+ inline int contains(<T&> key);
+
+ Pix ranktoPix(int i);
+ int rankof(<T&> key);
+
+ inline void clear();
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+inline <T><C>RAVLMap::~<T><C>RAVLMap()
+{
+ _kill(root);
+}
+
+inline <T><C>RAVLMap::<T><C>RAVLMap(<C&> dflt) :<T><C>Map(dflt)
+{
+ root = 0;
+}
+
+
+inline Pix <T><C>RAVLMap::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T><C>RAVLMap::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T><C>RAVLMap::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T><C>RAVLNode*)i));
+}
+
+inline void <T><C>RAVLMap::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T><C>RAVLNode*)i));
+}
+
+inline <T>& <T><C>RAVLMap::key(Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>RAVLNode*)i)->item;
+}
+
+inline <C>& <T><C>RAVLMap::contents(Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>RAVLNode*)i)->cont;
+}
+
+inline void <T><C>RAVLMap::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T><C>RAVLMap::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/RPlex.ccP b/gnu/lib/libg++/include/gen/RPlex.ccP
new file mode 100644
index 00000000000..1707b5d0ab2
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/RPlex.ccP
@@ -0,0 +1,477 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.RPlex.h"
+
+typedef <T>IChunk* _<T>IChunk_ptr;
+
+<T>RPlex:: <T>RPlex()
+{
+ lo = fnc = 0;
+ csize = DEFAULT_INITIAL_CAPACITY;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, lo, lo, fnc, lo+csize));
+ hd = ch;
+ maxch = MIN_NCHUNKS;
+ lch = maxch / 2;
+ fch = lch + 1;
+ base = ch->base_index() - lch * csize;
+ chunks = new _<T>IChunk_ptr[maxch];
+ chunks[lch] = ch;
+}
+
+<T>RPlex:: <T>RPlex(int chunksize)
+{
+ if (chunksize == 0) error("invalid constructor specification");
+ lo = fnc = 0;
+ if (chunksize > 0)
+ {
+ csize = chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, lo, lo, fnc, csize+lo));
+ hd = ch;
+ }
+ else
+ {
+ csize = -chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, chunksize+lo, lo, fnc, fnc));
+ hd = ch;
+ }
+ maxch = MIN_NCHUNKS;
+ lch = maxch / 2;
+ fch = lch + 1;
+ base = ch->base_index() - lch * csize;
+ chunks = new _<T>IChunk_ptr[maxch];
+ chunks[lch] = ch;
+}
+
+
+<T>RPlex:: <T>RPlex(int l, int chunksize)
+{
+ if (chunksize == 0) error("invalid constructor specification");
+ lo = fnc = l;
+ if (chunksize > 0)
+ {
+ csize = chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, lo, lo, fnc, lo+csize));
+ hd = ch;
+ }
+ else
+ {
+ csize = -chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, chunksize+lo, lo, fnc, fnc));
+ hd = ch;
+ }
+ maxch = MIN_NCHUNKS;
+ lch = maxch / 2;
+ fch = lch + 1;
+ base = ch->base_index() - lch * csize;
+ chunks = new _<T>IChunk_ptr[maxch];
+ chunks[lch] = ch;
+}
+
+void <T>RPlex::make_initial_chunks(int up)
+{
+ int count = 0;
+ int need = fnc - lo;
+ hd = 0;
+ if (up)
+ {
+ int l = lo;
+ do
+ {
+ ++count;
+ int sz;
+ if (need >= csize)
+ sz = csize;
+ else
+ sz = need;
+ <T>* data = new <T> [csize];
+ <T>IChunk* h = new <T>IChunk(data, l, l, l+sz, l+csize);
+ if (hd != 0)
+ h->link_to_next(hd);
+ else
+ hd = h;
+ l += sz;
+ need -= sz;
+ } while (need > 0);
+ }
+ else
+ {
+ int hi = fnc;
+ do
+ {
+ ++count;
+ int sz;
+ if (need >= csize)
+ sz = csize;
+ else
+ sz = need;
+ <T>* data = new <T> [csize];
+ <T>IChunk* h = new <T>IChunk(data, hi-csize, hi-sz, hi, hi);
+ if (hd != 0)
+ h->link_to_next(hd);
+ hd = h;
+ hi -= sz;
+ need -= sz;
+ } while (need > 0);
+ }
+ set_cache((<T>IChunk*)hd);
+
+ maxch = MIN_NCHUNKS;
+ if (maxch < count * 2)
+ maxch = count * 2;
+ chunks = new _<T>IChunk_ptr[maxch];
+ lch = maxch / 3;
+ fch = lch + count;
+ base = ch->base_index() - csize * lch;
+ int k = lch;
+ do
+ {
+ chunks[k++] = ch;
+ set_cache(ch->next());
+ } while (ch != hd);
+}
+
+<T>RPlex:: <T>RPlex(int l, int hi, const <T&> initval, int chunksize)
+{
+ lo = l;
+ fnc = hi + 1;
+ if (chunksize == 0)
+ {
+ csize = fnc - l;
+ make_initial_chunks(1);
+ }
+ else if (chunksize < 0)
+ {
+ csize = -chunksize;
+ make_initial_chunks(0);
+ }
+ else
+ {
+ csize = chunksize;
+ make_initial_chunks(1);
+ }
+ fill(initval);
+}
+
+<T>RPlex::<T>RPlex(const <T>RPlex& a)
+{
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = a.csize;
+ make_initial_chunks();
+ for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
+}
+
+void <T>RPlex::operator= (const <T>RPlex& a)
+{
+ if (&a != this)
+ {
+ invalidate();
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = a.csize;
+ make_initial_chunks();
+ for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
+ }
+}
+
+
+void <T>RPlex::cache(const <T>* p) const
+{
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->next());
+ if (t == old) index_error();
+ }
+ set_cache(t);
+}
+
+int <T>RPlex::owns(Pix px) const
+{
+ <T>* p = (<T>*)px;
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->next());
+ if (t == old) return 0;
+ }
+ set_cache(t);
+ return 1;
+}
+
+
+<T>* <T>RPlex::dosucc(const <T>* p) const
+{
+ if (p == 0) return 0;
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->next());
+ if (t == old) return 0;
+ }
+ int i = t->index_of(p) + 1;
+ if (i >= fnc) return 0;
+ if (i >= t->fence_index()) t = (t->next());
+ set_cache(t);
+ return t->pointer_to(i);
+}
+
+<T>* <T>RPlex::dopred(const <T>* p) const
+{
+ if (p == 0) return 0;
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->prev());
+ if (t == old) return 0;
+ }
+ int i = t->index_of(p) - 1;
+ if (i < lo) return 0;
+ if (i < t->low_index()) t = (t->prev());
+ set_cache(t);
+ return (t->pointer_to(i));
+}
+
+int <T>RPlex::add_high(const <T&> elem)
+{
+ <T>IChunk* t = tl();
+ if (!t->can_grow_high())
+ {
+ if (t-><T>IChunk::empty() && one_chunk())
+ {
+ t->clear(fnc);
+ base = t->base_index() - lch * csize;
+ }
+ else
+ {
+ <T>* data = new <T> [csize];
+ t = (new <T>IChunk(data, fnc, fnc, fnc,fnc+csize));
+ t->link_to_prev(tl());
+ if (fch == maxch)
+ {
+ maxch *= 2;
+ <T>IChunk** newch = new _<T>IChunk_ptr [maxch];
+ memcpy(newch, chunks, fch * sizeof(_<T>IChunk_ptr));
+ delete chunks;
+ chunks = newch;
+ }
+ chunks[fch++] = t;
+ }
+ }
+ *((t-><T>IChunk::grow_high())) = elem;
+ set_cache(t);
+ return fnc++;
+}
+
+int <T>RPlex::del_high ()
+{
+ if (empty()) empty_error();
+ <T>IChunk* t = tl();
+ if (t-><T>IChunk::empty()) // kill straggler first
+ {
+ <T>IChunk* pred = t->prev();
+ del_chunk(t);
+ t = (pred);
+ --fch;
+ }
+ t-><T>IChunk::shrink_high();
+ if (t-><T>IChunk::empty() && !one_chunk())
+ {
+ <T>IChunk* pred = t->prev();
+ del_chunk(t);
+ t = (pred);
+ --fch;
+ }
+ set_cache(t);
+ return --fnc - 1;
+}
+
+int <T>RPlex::add_low (const <T&> elem)
+{
+ <T>IChunk* t = hd;
+ if (!t->can_grow_low())
+ {
+ if (t-><T>IChunk::empty() && one_chunk())
+ {
+ t->cleardown(lo);
+ base = t->base_index() - lch * csize;
+ }
+ else
+ {
+ <T>* data = new <T> [csize];
+ hd = new <T>IChunk(data, lo-csize, lo, lo, lo);
+ hd->link_to_next(t);
+ t = ( hd);
+ if (lch == 0)
+ {
+ lch = maxch;
+ fch += maxch;
+ maxch *= 2;
+ <T>IChunk** newch = new _<T>IChunk_ptr [maxch];
+ memcpy(&(newch[lch]), chunks, lch * sizeof(_<T>IChunk_ptr));
+ delete chunks;
+ chunks = newch;
+ base = t->base_index() - (lch - 1) * csize;
+ }
+ chunks[--lch] = t;
+ }
+ }
+ *((t-><T>IChunk::grow_low())) = elem;
+ set_cache(t);
+ return --lo;
+}
+
+
+int <T>RPlex::del_low ()
+{
+ if (empty()) empty_error();
+ <T>IChunk* t = hd;
+ if (t-><T>IChunk::empty())
+ {
+ hd = t->next();
+ del_chunk(t);
+ t = hd;
+ ++lch;
+ }
+ t-><T>IChunk::shrink_low();
+ if (t-><T>IChunk::empty() && !one_chunk())
+ {
+ hd = t->next();
+ del_chunk(t);
+ t = hd;
+ ++lch;
+ }
+ set_cache(t);
+ return ++lo;
+}
+
+void <T>RPlex::reverse()
+{
+ <T> tmp;
+ int l = lo;
+ int h = fnc - 1;
+ <T>IChunk* loch = hd;
+ <T>IChunk* hich = tl();
+ while (l < h)
+ {
+ <T>* lptr = loch->pointer_to(l);
+ <T>* hptr = hich->pointer_to(h);
+ tmp = *lptr;
+ *lptr = *hptr;
+ *hptr = tmp;
+ if (++l >= loch->fence_index()) loch = loch->next();
+ if (--h < hich->low_index()) hich = hich->prev();
+ }
+}
+
+void <T>RPlex::fill(const <T&> x)
+{
+ for (int i = lo; i < fnc; ++i) (*this)[i] = x;
+}
+
+void <T>RPlex::fill(const <T&> x, int lo, int hi)
+{
+ for (int i = lo; i <= hi; ++i) (*this)[i] = x;
+}
+
+
+void <T>RPlex::clear()
+{
+ for (int i = lch + 1; i < fch; ++i)
+ del_chunk(chunks[i]);
+ fch = lch + 1;
+ set_cache(chunks[lch]);
+ ch-><T>IChunk::clear(lo);
+ fnc = lo;
+}
+
+int <T>RPlex::reset_low(int l)
+{
+ int old = lo;
+ int diff = l - lo;
+ if (diff != 0)
+ {
+ lo += diff;
+ fnc += diff;
+ <T>IChunk* t = hd;
+ do
+ {
+ t->re_index(t->low_index() + diff);
+ t = t->next();
+ } while (t != hd);
+ }
+ base = hd->base_index() - lch * csize;
+ return old;
+}
+
+
+int <T>RPlex::OK () const
+{
+ int v = hd != 0 && ch != 0; // at least one chunk
+
+ v &= fnc == tl()->fence_index(); // last chunk fnc == plex fnc
+ v &= lo == hd-><T>IChunk::low_index(); // first lo == plex lo
+
+ v &= base == hd->base_index() - lch * csize; // base is correct;
+ v &= lch < fch;
+ v &= fch <= maxch; // within allocation;
+
+// loop for others:
+
+ int k = lch; // to cross-check nch
+
+ int found_ch = 0; // to make sure ch is in list;
+ const <T>IChunk* t = (hd);
+ for (;;)
+ {
+ v &= chunks[k++] == t; // each chunk is at proper index
+ if (t == ch) ++found_ch;
+ v &= t-><T>IChunk::OK(); // each chunk is OK
+ if (t == tl())
+ break;
+ else // and has indices contiguous to succ
+ {
+ v &= t->top_index() == t->next()->base_index();
+ if (t != hd) // internal chunks full
+ {
+ v &= !t->empty();
+ v &= !t->can_grow_low();
+ v &= !t->can_grow_high();
+ }
+ t = t->next();
+ }
+ }
+ v &= found_ch == 1;
+ v &= fch == k;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/RPlex.hP b/gnu/lib/libg++/include/gen/RPlex.hP
new file mode 100644
index 00000000000..546adaa3c5d
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/RPlex.hP
@@ -0,0 +1,257 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>RPlex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>RPlex_h 1
+
+#include "<T>.Plex.h"
+
+// minimum number of chunks to index
+
+#ifndef MIN_NCHUNKS
+#define MIN_NCHUNKS 16
+#endif
+
+class <T>RPlex: public <T>Plex
+{
+ int base; // base index of lowest chunk
+ int lch; // index of lowest used chunk
+ int fch; // 1 + index of highest used chunk
+ int maxch; // max chunks in array
+ <T>IChunk** chunks; // array of chunks
+ <T>IChunk* ch; // cached chunk
+
+ void make_initial_chunks(int up = 1);
+
+ void cache(int idx) const;
+ void cache(const <T>* p) const;
+ <T>* dopred(const <T>* p) const;
+ <T>* dosucc(const <T>* p) const;
+
+ inline void set_cache(const <T>IChunk* t) const; // logically,
+ // not physically const
+
+public:
+ <T>RPlex(); // set low = 0;
+ // fence = 0;
+ // csize = default
+
+ <T>RPlex(int ch_size); // low = 0;
+ // fence = 0;
+ // csize = ch_size
+
+ <T>RPlex(int lo, // low = lo;
+ int ch_size); // fence=lo
+ // csize = ch_size
+
+ <T>RPlex(int lo, // low = lo
+ int hi, // fence = hi+1
+ const <T&> initval,// fill with initval,
+ int ch_size = 0); // csize= ch_size
+ // or fence-lo if 0
+
+ <T>RPlex(const <T>RPlex&);
+
+ inline ~<T>RPlex();
+
+ void operator= (const <T>RPlex&);
+
+// virtuals
+
+ inline <T>& high_element ();
+ inline <T>& low_element ();
+
+ inline const <T>& high_element () const;
+ inline const <T>& low_element () const;
+
+ inline Pix first() const;
+ inline Pix last() const;
+ inline void prev(Pix& ptr) const;
+ inline void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ inline <T>& operator () (Pix p);
+ inline const <T>& operator () (Pix p) const;
+
+ inline int low() const;
+ inline int high() const;
+ inline int valid(int idx) const;
+ inline void prev(int& idx) const;
+ inline void next(int& x) const;
+ inline <T>& operator [] (int index);
+ inline const <T>& operator [] (int index) const;
+
+ inline int Pix_to_index(Pix p) const;
+ inline Pix index_to_Pix(int idx) const;
+
+ inline int can_add_high() const;
+ inline int can_add_low() const;
+ inline int full() const;
+
+ int add_high(const <T&> elem);
+ int del_high ();
+ int add_low (const <T&> elem);
+ int del_low ();
+
+ void fill(const <T&> x);
+ void fill(const <T&> x, int from, int to);
+ void clear();
+ void reverse();
+
+ int reset_low(int newlow);
+
+ int OK () const;
+};
+
+
+inline void <T>RPlex::prev(int& idx) const
+{
+ --idx;
+}
+
+inline void <T>RPlex::next(int& idx) const
+{
+ ++idx;
+}
+
+inline int <T>RPlex::full () const
+{
+ return 0;
+}
+
+inline int <T>RPlex::can_add_high() const
+{
+ return 1;
+}
+
+inline int <T>RPlex::can_add_low() const
+{
+ return 1;
+}
+
+inline int <T>RPlex::valid (int idx) const
+{
+ return idx >= lo && idx < fnc;
+}
+
+inline int <T>RPlex::low() const
+{
+ return lo;
+}
+
+inline int <T>RPlex::high() const
+{
+ return fnc - 1;
+}
+
+inline void <T>RPlex::set_cache(const <T>IChunk* t) const
+{
+ ((<T>RPlex*)(this))->ch = (<T>IChunk*)t;
+}
+
+inline void <T>RPlex::cache(int idx) const
+{
+ if (idx < lo || idx >= fnc) index_error();
+ set_cache(chunks[(idx - base) / csize]);
+}
+
+inline <T>& <T>RPlex::low_element ()
+{
+ cache(lo); return *(ch->pointer_to(lo));
+}
+
+inline <T>& <T>RPlex::high_element ()
+{
+ cache(fnc-1); return *(ch->pointer_to(fnc - 1));
+}
+
+inline const <T>& <T>RPlex::low_element () const
+{
+ cache(lo); return *((const <T>*)(ch->pointer_to(lo)));
+}
+
+inline const <T>& <T>RPlex::high_element () const
+{
+ cache(fnc-1); return *((const <T>*)(ch->pointer_to(fnc - 1)));
+}
+
+inline int <T>RPlex::Pix_to_index(Pix px) const
+{
+ <T>* p = (<T>*)px;
+ if (!ch->actual_pointer(p)) cache(p);
+ return ch->index_of(p);
+}
+
+inline Pix <T>RPlex::index_to_Pix(int idx) const
+{
+ if (!ch->actual_index(idx)) cache(idx);
+ return (Pix)(ch->pointer_to(idx));
+}
+
+inline Pix <T>RPlex::first() const
+{
+ return Pix(hd-><T>IChunk::first_pointer());
+}
+
+inline Pix <T>RPlex::last() const
+{
+ return Pix(tl()-><T>IChunk::last_pointer());
+}
+
+inline void <T>RPlex::prev(Pix& p) const
+{
+ Pix q = Pix(ch-><T>IChunk::pred((<T>*)p));
+ p = (q == 0)? Pix(dopred((<T>*)p)) : q;
+}
+
+inline void <T>RPlex::next(Pix& p) const
+{
+ Pix q = Pix(ch-><T>IChunk::succ((<T>*)p));
+ p = (q == 0)? Pix(dosucc((<T>*)p)) : q;
+}
+
+inline <T>& <T>RPlex:: operator () (Pix p)
+{
+ return *((<T>*)p);
+}
+
+
+inline <T>& <T>RPlex:: operator [] (int idx)
+{
+ cache(idx); return *(ch->pointer_to(idx));
+}
+
+inline const <T>& <T>RPlex:: operator () (Pix p) const
+{
+ return *((const <T>*)p);
+}
+
+inline const <T>& <T>RPlex:: operator [] (int idx) const
+{
+ cache(idx); return *((const <T>*)(ch->pointer_to(idx)));
+}
+
+inline <T>RPlex::~<T>RPlex()
+{
+ delete chunks;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SLBag.ccP b/gnu/lib/libg++/include/gen/SLBag.ccP
new file mode 100644
index 00000000000..6b7c0faca5c
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLBag.ccP
@@ -0,0 +1,105 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SLBag.h"
+
+int <T>SLBag::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ if (!v) error("invariant failure");
+ return v;
+}
+
+Pix <T>SLBag::seek(<T&> item, Pix i)
+{
+ if (i == 0) i = first(); else next(i);
+ for (; i != 0 && (!(<T>EQ(p(i), item))); p.next(i));
+ return i;
+}
+
+int <T>SLBag::nof(<T&> item)
+{
+ int n = 0;
+ for (Pix p = first(); p; next(p)) if (<T>EQ((*this)(p), item)) ++n;
+ return n;
+}
+
+
+void <T>SLBag::del(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ return;
+ else if (<T>EQ(p(i), item))
+ {
+ --count;
+ p.del_front();
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ while (i != 0)
+ {
+ if (<T>EQ(p(i), item))
+ {
+ --count;
+ p.del_after(trail);
+ return;
+ }
+ trail = i;
+ p.next(i);
+ }
+ }
+}
+
+void <T>SLBag::remove(<T&> item)
+{
+ Pix i = p.first();
+ while (i != 0 && <T>EQ(p(i), item))
+ {
+ --count;
+ p.del_front();
+ i = p.first();
+ }
+ if (i != 0)
+ {
+ Pix trail = i;
+ p.next(i);
+ while (i != 0)
+ {
+ if (<T>EQ(p(i), item))
+ {
+ --count;
+ p.del_after(trail);
+ i = trail;
+ p.next(i);
+ }
+ else
+ {
+ trail = i;
+ p.next(i);
+ }
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/include/gen/SLBag.hP b/gnu/lib/libg++/include/gen/SLBag.hP
new file mode 100644
index 00000000000..2bab7db64a9
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLBag.hP
@@ -0,0 +1,96 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>SLBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SLBag_h 1
+
+#include "<T>.Bag.h"
+#include "<T>.SLList.h"
+
+class <T>SLBag : public <T>Bag
+{
+protected:
+ <T>SLList p;
+
+public:
+ <T>SLBag();
+ <T>SLBag(const <T>SLBag&);
+
+ inline Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ inline int contains(<T&> item);
+ int nof(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+
+inline <T>SLBag::<T>SLBag() : p() { count = 0; }
+
+inline <T>SLBag::<T>SLBag(const <T>SLBag& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>SLBag::first()
+{
+ return p.first();
+}
+
+inline void <T>SLBag::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>SLBag::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>SLBag::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>SLBag::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+inline Pix <T>SLBag::add(<T&> item)
+{
+ ++count;
+ return p.append(item);
+}
+
+inline int <T>SLBag::contains(<T&> item)
+{
+ return seek(item) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SLList.ccP b/gnu/lib/libg++/include/gen/SLList.ccP
new file mode 100644
index 00000000000..3dbe22f3d38
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLList.ccP
@@ -0,0 +1,292 @@
+// This may look like C code, but it is really -*- C++ -*-
+// WARNING: This file is obsolete. Use ../SLList.cc, if you can.
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <limits.h>
+#include <stream.h>
+#include <builtin.h>
+#include "<T>.SLList.h"
+
+void <T>SLList::error(const char* msg)
+{
+ (*lib_error_handler)("SLList", msg);
+}
+
+int <T>SLList::length()
+{
+ int l = 0;
+ <T>SLListNode* t = last;
+ if (t != 0) do { ++l; t = t->tl; } while (t != last);
+ return l;
+}
+
+<T>SLList::<T>SLList(const <T>SLList& a)
+{
+ if (a.last == 0)
+ last = 0;
+ else
+ {
+ <T>SLListNode* p = a.last->tl;
+ <T>SLListNode* h = new <T>SLListNode(p->hd);
+ last = h;
+ for (;;)
+ {
+ if (p == a.last)
+ {
+ last->tl = h;
+ return;
+ }
+ p = p->tl;
+ <T>SLListNode* n = new <T>SLListNode(p->hd);
+ last->tl = n;
+ last = n;
+ }
+ }
+}
+
+<T>SLList& <T>SLList::operator = (const <T>SLList& a)
+{
+ if (last != a.last)
+ {
+ clear();
+ if (a.last != 0)
+ {
+ <T>SLListNode* p = a.last->tl;
+ <T>SLListNode* h = new <T>SLListNode(p->hd);
+ last = h;
+ for (;;)
+ {
+ if (p == a.last)
+ {
+ last->tl = h;
+ break;
+ }
+ p = p->tl;
+ <T>SLListNode* n = new <T>SLListNode(p->hd);
+ last->tl = n;
+ last = n;
+ }
+ }
+ }
+ return *this;
+}
+
+void <T>SLList::clear()
+{
+ if (last == 0)
+ return;
+
+ <T>SLListNode* p = last->tl;
+ last->tl = 0;
+ last = 0;
+
+ while (p != 0)
+ {
+ <T>SLListNode* nxt = p->tl;
+ delete(p);
+ p = nxt;
+ }
+}
+
+
+Pix <T>SLList::prepend(<T&> item)
+{
+ <T>SLListNode* t = new <T>SLListNode(item);
+ if (last == 0)
+ t->tl = last = t;
+ else
+ {
+ t->tl = last->tl;
+ last->tl = t;
+ }
+ return Pix(t);
+}
+
+
+Pix <T>SLList::prepend(<T>SLListNode* 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 <T>SLList::append(<T&> item)
+{
+ <T>SLListNode* t = new <T>SLListNode(item);
+ if (last == 0)
+ t->tl = last = t;
+ else
+ {
+ t->tl = last->tl;
+ last->tl = t;
+ last = t;
+ }
+ return Pix(t);
+}
+
+Pix <T>SLList::append(<T>SLListNode* 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 <T>SLList::join(<T>SLList& b)
+{
+ <T>SLListNode* t = b.last;
+ b.last = 0;
+ if (last == 0)
+ last = t;
+ else if (t != 0)
+ {
+ <T>SLListNode* f = last->tl;
+ last->tl = t->tl;
+ t->tl = f;
+ last = t;
+ }
+}
+
+Pix <T>SLList::ins_after(Pix p, <T&> item)
+{
+ <T>SLListNode* u = (<T>SLListNode*)p;
+ <T>SLListNode* t = new <T>SLListNode(item);
+ 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 <T>SLList::del_after(Pix p)
+{
+ <T>SLListNode* u = (<T>SLListNode*)p;
+ if (last == 0 || u == last) error("cannot del_after last");
+ if (u == 0) u = last; // del_after 0 means delete first
+ <T>SLListNode* t = u->tl;
+ if (u == t)
+ last = 0;
+ else
+ {
+ u->tl = t->tl;
+ if (last == t)
+ last = u;
+ }
+ delete t;
+}
+
+int <T>SLList::owns(Pix p)
+{
+ <T>SLListNode* t = last;
+ if (t != 0 && p != 0)
+ {
+ do
+ {
+ if (Pix(t) == p) return 1;
+ t = t->tl;
+ } while (t != last);
+ }
+ return 0;
+}
+
+<T> <T>SLList::remove_front()
+{
+ if (last == 0) error("remove_front of empty list");
+ <T>SLListNode* t = last->tl;
+ <T> res = t->hd;
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete t;
+ return res;
+}
+
+int <T>SLList::remove_front(<T>& x)
+{
+ if (last == 0)
+ return 0;
+ else
+ {
+ <T>SLListNode* t = last->tl;
+ x = t->hd;
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete t;
+ return 1;
+ }
+}
+
+
+void <T>SLList::del_front()
+{
+ if (last == 0) error("del_front of empty list");
+ <T>SLListNode* t = last->tl;
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete t;
+}
+
+int <T>SLList::OK()
+{
+ int v = 1;
+ if (last != 0)
+ {
+ <T>SLListNode* 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;
+}
diff --git a/gnu/lib/libg++/include/gen/SLList.hP b/gnu/lib/libg++/include/gen/SLList.hP
new file mode 100644
index 00000000000..cd89dee3309
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLList.hP
@@ -0,0 +1,137 @@
+// This may look like C code, but it is really -*- C++ -*-
+// WARNING: This file is obsolete. Use ../SLList.h, if you can.
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>SLList_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SLList_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+#ifndef _<T>SLListNode_h
+#define _<T>SLListNode_h 1
+
+struct <T>SLListNode
+{
+ <T>SLListNode* tl;
+ <T> hd;
+ <T>SLListNode() { }
+ <T>SLListNode(const <T&> h, <T>SLListNode* t = 0);
+ ~<T>SLListNode() { }
+};
+
+
+inline <T>SLListNode::<T>SLListNode(const <T&> h, <T>SLListNode* t)
+:tl(t), hd(h) {}
+
+typedef <T>SLListNode* <T>SLListNodePtr;
+
+#endif
+
+
+class <T>SLList
+{
+protected:
+ <T>SLListNode* last;
+
+public:
+ <T>SLList();
+ <T>SLList(const <T>SLList& a);
+ ~<T>SLList();
+
+ <T>SLList& operator = (const <T>SLList& a);
+
+ int empty();
+ int length();
+
+ void clear();
+
+ Pix prepend(<T&> item);
+ Pix append(<T&> item);
+
+ void join(<T>SLList&);
+
+ Pix prepend(<T>SLListNode*);
+ Pix append(<T>SLListNode*);
+
+ <T>& operator () (Pix p);
+ Pix first();
+ void next(Pix& p);
+ int owns(Pix p);
+ Pix ins_after(Pix p, <T&> item);
+ void del_after(Pix p);
+
+ <T>& front();
+ <T>& rear();
+ <T> remove_front();
+ int remove_front(<T>& x);
+ void del_front();
+
+ void error(const char* msg);
+ int OK();
+};
+
+inline <T>SLList::~<T>SLList()
+{
+ clear();
+}
+
+inline <T>SLList::<T>SLList()
+{
+ last = 0;
+}
+
+inline int <T>SLList::empty()
+{
+ return last == 0;
+}
+
+
+inline Pix <T>SLList::first()
+{
+ return (last == 0)? 0 : Pix(last->tl);
+}
+
+inline void <T>SLList::next(Pix& p)
+{
+ p = (p == 0 || p == last)? 0 : Pix(((<T>SLListNode*)(p))->tl);
+}
+
+inline <T>& <T>SLList::operator () (Pix p)
+{
+ if (p == 0) error("null Pix");
+ return ((<T>SLListNode*)(p))->hd;
+}
+
+inline <T>& <T>SLList::front()
+{
+ if (last == 0) error("front: empty list");
+ return last->tl->hd;
+}
+
+inline <T>& <T>SLList::rear()
+{
+ if (last == 0) error("rear: empty list");
+ return last->hd;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SLQueue.ccP b/gnu/lib/libg++/include/gen/SLQueue.ccP
new file mode 100644
index 00000000000..8a5935b7757
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLQueue.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SLQueue.h"
diff --git a/gnu/lib/libg++/include/gen/SLQueue.hP b/gnu/lib/libg++/include/gen/SLQueue.hP
new file mode 100644
index 00000000000..84683b85a2c
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLQueue.hP
@@ -0,0 +1,108 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>SLQueue_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SLQueue_h
+
+#include "<T>.SLList.h"
+#include "<T>.Queue.h"
+
+class <T>SLQueue : public <T>Queue
+{
+ <T>SLList p;
+
+public:
+ <T>SLQueue();
+ <T>SLQueue(const <T>SLQueue& q);
+ inline ~<T>SLQueue();
+
+ void operator = (const <T>SLQueue&);
+
+ inline void enq(<T&> item);
+ inline <T> deq();
+ inline <T>& front();
+ inline void del_front();
+
+ inline void clear();
+ inline int empty();
+ inline int full();
+ inline int length();
+
+ inline int OK();
+};
+
+inline <T>SLQueue::<T>SLQueue() :p() {}
+inline <T>SLQueue::<T>SLQueue(const <T>SLQueue& q) : p(q.p) {}
+
+inline <T>SLQueue::~<T>SLQueue() {}
+
+inline void <T>SLQueue::enq(<T&>item)
+{
+ p.append(item);
+}
+
+inline <T> <T>SLQueue::deq()
+{
+ return p.remove_front();
+}
+
+inline <T>& <T>SLQueue::front()
+{
+ return p.front();
+}
+
+
+inline void <T>SLQueue::del_front()
+{
+ p.del_front();
+}
+
+inline void <T>SLQueue::operator =(const <T>SLQueue& s)
+{
+ p = s.p;
+}
+
+inline int <T>SLQueue::empty()
+{
+ return p.empty();
+}
+
+inline int <T>SLQueue::full()
+{
+ return 0;
+}
+
+inline int <T>SLQueue::length()
+{
+ return p.length();
+}
+
+inline int <T>SLQueue::OK()
+{
+ return p.OK();
+}
+
+inline void <T>SLQueue::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SLSet.ccP b/gnu/lib/libg++/include/gen/SLSet.ccP
new file mode 100644
index 00000000000..7d2ac58d087
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLSet.ccP
@@ -0,0 +1,77 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SLSet.h"
+
+int <T>SLSet::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ if (!v) error("invariant failure");
+ return v;
+}
+
+Pix <T>SLSet::seek(<T&> item)
+{
+ Pix i;
+ for (i = p.first(); i != 0 && !<T>EQ(p(i),item); p.next(i));
+ return i;
+}
+
+Pix <T>SLSet::add(<T&> item)
+{
+ Pix i = seek(item);
+ if (i == 0)
+ {
+ ++count;
+ i = p.append(item);
+ }
+ return i;
+}
+
+void <T>SLSet::del(<T&> item)
+{
+ Pix i = p.first();
+ if (i == 0)
+ return;
+ else if (<T>EQ(p(i), item))
+ {
+ --count;
+ p.del_front();
+ }
+ else
+ {
+ Pix trail = i;
+ p.next(i);
+ while (i != 0)
+ {
+ if (<T>EQ(p(i), item))
+ {
+ --count;
+ p.del_after(trail);
+ return;
+ }
+ trail = i;
+ p.next(i);
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/include/gen/SLSet.hP b/gnu/lib/libg++/include/gen/SLSet.hP
new file mode 100644
index 00000000000..fa94bb891ba
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLSet.hP
@@ -0,0 +1,87 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>SLSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SLSet_h 1
+
+#include "<T>.Set.h"
+#include "<T>.SLList.h"
+
+class <T>SLSet : public <T>Set
+{
+protected:
+ <T>SLList p;
+
+public:
+ <T>SLSet();
+ <T>SLSet(const <T>SLSet&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item);
+
+ int OK();
+};
+
+inline <T>SLSet::<T>SLSet() : p() { count = 0; }
+
+inline <T>SLSet::<T>SLSet(const <T>SLSet& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>SLSet::first()
+{
+ return p.first();
+}
+
+inline void <T>SLSet::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>SLSet::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>SLSet::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>SLSet::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+inline int <T>SLSet::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SLStack.ccP b/gnu/lib/libg++/include/gen/SLStack.ccP
new file mode 100644
index 00000000000..3996b41fac5
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLStack.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SLStack.h"
diff --git a/gnu/lib/libg++/include/gen/SLStack.hP b/gnu/lib/libg++/include/gen/SLStack.hP
new file mode 100644
index 00000000000..466cfee53b4
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SLStack.hP
@@ -0,0 +1,109 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>SLStack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SLStack_h 1
+
+#include "<T>.SLList.h"
+#include "<T>.Stack.h"
+
+class <T>SLStack : public <T>Stack
+{
+ <T>SLList p;
+
+public:
+ <T>SLStack();
+ <T>SLStack(const <T>SLStack& s);
+ inline ~<T>SLStack();
+
+ void operator = (const <T>SLStack&);
+
+ inline void push(<T&> item);
+ inline <T> pop();
+ inline <T>& top();
+ inline void del_top();
+
+ inline int empty();
+ inline int full();
+ inline int length();
+
+ inline void clear();
+
+ inline int OK();
+
+};
+
+inline <T>SLStack::<T>SLStack() :p() {}
+inline <T>SLStack::<T>SLStack(const <T>SLStack& a) : p(a.p) {}
+inline <T>SLStack::~<T>SLStack() {}
+
+inline void <T>SLStack::push(<T&> item)
+{
+ p.prepend(item);
+}
+
+inline <T> <T>SLStack::pop()
+{
+ return p.remove_front();
+}
+
+inline <T>& <T>SLStack::top()
+{
+ return p.front();
+}
+
+inline void <T>SLStack::del_top()
+{
+ p.del_front();
+}
+
+inline void <T>SLStack::operator =(const <T>SLStack& s)
+{
+ p = s.p;
+}
+
+inline int <T>SLStack::empty()
+{
+ return p.empty();
+}
+
+inline int <T>SLStack::full()
+{
+ return 0;
+}
+
+inline int <T>SLStack::length()
+{
+ return p.length();
+}
+
+inline int <T>SLStack::OK()
+{
+ return p.OK();
+}
+
+inline void <T>SLStack::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Set.ccP b/gnu/lib/libg++/include/gen/Set.ccP
new file mode 100644
index 00000000000..b072339158d
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Set.ccP
@@ -0,0 +1,117 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include "<T>.Set.h"
+
+
+Pix <T>Set::seek(<T&> item)
+{
+ Pix i;
+ for (i = first(); i != 0 && !(<T>EQ((*this)(i), item)); next(i));
+ return i;
+}
+
+int <T>Set::owns(Pix idx)
+{
+ if (idx == 0) return 0;
+ for (Pix i = first(); i; next(i)) if (i == idx) return 1;
+ return 0;
+}
+
+void <T>Set::clear()
+{
+ Pix i = first();
+ while (i != 0)
+ {
+ del((*this)(i));
+ i = first();
+ }
+}
+
+int <T>Set::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+int <T>Set::operator <= (<T>Set& b)
+{
+ if (count > b.count) return 0;
+ if (count == 0) return 1;
+ for (Pix i = first(); i; next(i)) if (b.seek((*this)(i)) == 0) return 0;
+ return 1;
+}
+
+int <T>Set::operator == (<T>Set& b)
+{
+ int n = count;
+ if (n != b.count) return 0;
+ if (n == 0) return 1;
+ Pix i = first();
+ Pix j = b.first();
+ while (n-- > 0)
+ {
+ if ((b.seek((*this)(i)) == 0) || (seek(b(j)) == 0)) return 0;
+ next(i);
+ b.next(j);
+ }
+ return 1;
+}
+
+int <T>Set::operator != (<T>Set& b)
+{
+ return !(*this == b);
+}
+
+void <T>Set::operator |= (<T>Set& b)
+{
+ if (&b != this)
+ for (Pix i = b.first(); i; b.next(i)) add(b(i));
+}
+
+void <T>Set::operator -= (<T>Set& b)
+{
+ if (&b == this)
+ clear();
+ else
+ for (Pix i = b.first(); i; b.next(i)) del(b(i));
+}
+
+
+void <T>Set::operator &= (<T>Set& b)
+{
+ if (&b != this)
+ {
+ Pix i = first();
+ Pix n = i;
+ while (i != 0)
+ {
+ next(n);
+ if (b.seek((*this)(i)) == 0) del((*this)(i));
+ i = n;
+ }
+ }
+}
+
+void <T>Set::error(const char* msg)
+{
+ (*lib_error_handler)("Set", msg);
+}
diff --git a/gnu/lib/libg++/include/gen/Set.hP b/gnu/lib/libg++/include/gen/Set.hP
new file mode 100644
index 00000000000..8dd99e574ca
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Set.hP
@@ -0,0 +1,78 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>Set_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Set_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T>Set
+{
+protected:
+
+ int count;
+
+public:
+ inline virtual ~<T>Set();
+
+ int length(); // current number of items
+ int empty();
+
+ virtual Pix add(<T&> item) = 0; // add item; return Pix
+ virtual void del(<T&> item) = 0; // delete item
+ virtual int contains(<T&> item); // is item in set?
+
+ virtual void clear(); // delete all items
+
+ virtual Pix first() = 0; // Pix of first item or 0
+ virtual void next(Pix& i) = 0; // advance to next or 0
+ virtual <T>& operator () (Pix i) = 0; // access item at i
+
+ virtual int owns(Pix i); // is i a valid Pix ?
+ virtual Pix seek(<T&> item); // Pix of item
+
+ void operator |= (<T>Set& b); // add all items in b
+ void operator -= (<T>Set& b); // delete items also in b
+ void operator &= (<T>Set& b); // delete items not in b
+
+ int operator == (<T>Set& b);
+ int operator != (<T>Set& b);
+ int operator <= (<T>Set& b);
+
+ void error(const char* msg);
+ virtual int OK() = 0; // rep invariant
+};
+
+inline <T>Set::~<T>Set() {}
+
+inline int <T>Set::length()
+{
+ return count;
+}
+
+inline int <T>Set::empty()
+{
+ return count == 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SkipBag.ccP b/gnu/lib/libg++/include/gen/SkipBag.ccP
new file mode 100644
index 00000000000..9711d85c095
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SkipBag.ccP
@@ -0,0 +1,322 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+Copyright (C) 1991 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Bags implemented via William Pugh SkipList algorithms.
+ * CACM, June 1990, p 668-676.
+ *
+ */
+
+#include <stream.h>
+#include <time.h>
+#include "<T>.SkipBag.h"
+
+MLCG* <T>SkipBag::gen = 0;
+int <T>SkipBaginit::count = 0;
+
+static int countbits(long bits)
+{
+ int n = 0;
+ while(bits>>=1L) n++;
+ return n;
+}
+
+<T>SkipBag::<T>SkipBag(long size)
+: level(0),
+ header(new <T>SkipBagNode (countbits(size)+1)),
+ max_levels (countbits(size)+1),
+ random_bits(gen->asLong()),
+ randoms_left(BITS_IN_RANDOM / 2)
+{
+ <T>SkipBagNodePtr *buffer_start = header->forward;
+ <T>SkipBagNodePtr *trav = &header->forward[max_levels];
+
+ count = 0;
+ while (trav > buffer_start)
+ *--trav = (<T>SkipBagNodePtr) header;
+}
+
+<T>SkipBag::<T>SkipBag(<T>SkipBag& b)
+: level (0),
+ header (new <T>SkipBagNode (b.max_levels)),
+ max_levels (b.max_levels),
+ random_bits (gen->asLong()),
+ randoms_left (BITS_IN_RANDOM / 2)
+{
+ <T>SkipBagNodePtr *buffer_start = header->forward;
+ <T>SkipBagNodePtr *trav = &header->forward[max_levels];
+
+ count = 0;
+
+ while (trav > buffer_start)
+ *--trav = (<T>SkipBagNodePtr)header;
+
+ for (<T>SkipBagNodePtr t = b.leftmost(); t; t = b.succ(t))
+ add(t->item);
+}
+
+Pix <T>SkipBag::add (<T&> item)
+{
+ <T>SkipBagNodePtr *update = new <T>SkipBagNodePtr[max_levels+1];
+ <T>SkipBagNodePtr curr = (<T>SkipBagNodePtr) this->header;
+ int l = level;
+ <T>SkipBagNodePtr temp;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header &&
+ <T>CMP(temp->item, item) < 0)
+ curr = temp;
+ update[l] = curr;
+ }
+ while (--l >= 0);
+
+ if ((l = random_level ()) > level)
+ {
+ l = ++level;
+ update[l] = (<T>SkipBagNodePtr)header;
+ };
+
+ temp = new <T>RealSkipBagNode (item, l);
+ <T>SkipBagNodePtr *temp_forward = temp->forward;
+
+ do
+ {
+ <T>SkipBagNodePtr *curr_forward = update[l]->forward;
+
+ temp_forward[l] = curr_forward[l];
+ curr_forward[l] = temp;
+ }
+ while (--l >= 0);
+
+ count++;
+ delete update;
+ return Pix(temp);
+}
+
+void <T>SkipBag::del(<T&> key)
+{
+
+ int l = level;
+ int curr_level = level;
+ <T>SkipBagNodePtr *update = new <T>SkipBagNodePtr[max_levels+1];
+ <T>SkipBagNodePtr curr = (<T>SkipBagNodePtr)header;
+ <T>SkipBagNodePtr temp;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header
+ && <T>CMP(temp->item,key) < 0)
+ curr = temp;
+ update[l] = curr;
+ }
+ while (--l >= 0);
+
+ if (<T>CMP(temp->item,key)==0)
+ {
+ <T>SkipBagNodePtr *temp_forward = temp->forward;
+
+ for (l = 0;
+ l <= curr_level && (curr = update[l])->forward[l] == temp;
+ l++)
+ curr->forward[l] = temp_forward[l];
+
+ delete temp;
+
+ <T>SkipBagNodePtr *forward = header->forward;
+
+ while (forward[curr_level]==header && curr_level > 0)
+ curr_level--;
+
+ level = curr_level;
+ count--;
+ delete update;
+ return;
+ }
+}
+
+<T>SkipBagNodePtr <T>SkipBag::rightmost()
+{
+ <T>SkipBagNodePtr temp;
+ <T>SkipBagNode* curr = header;
+ int l = level;
+
+ do
+ while ((temp = curr->forward[l])!=header)
+ curr = temp;
+ while (--l >= 0);
+
+ return temp==header ? 0 : temp;
+}
+
+<T>SkipBagNodePtr <T>SkipBag::pred(<T>SkipBagNodePtr t)
+{
+ <T>SkipBagNodePtr temp, curr = (<T>SkipBagNodePtr) header;
+ int l = level;
+
+ do
+ while ((temp = curr->forward[l])!=t)
+ curr = temp;
+ while (--l >= 0);
+
+ return curr == header ? 0 : curr;
+}
+
+void <T>SkipBag::_kill()
+{
+ <T>SkipBagNode *p = this->header->forward[0];
+
+ while (p != header)
+ {
+ <T>SkipBagNodePtr q = p->forward[0];
+ delete p;
+ p = q;
+ }
+}
+
+void <T>SkipBag::clear()
+{
+ <T>SkipBagNodePtr *buffer_start = header->forward;
+ <T>SkipBagNodePtr *trav = &header->forward[level+1];
+ _kill();
+ count = 0;
+
+ while (trav > buffer_start)
+ *--trav = (<T>SkipBagNodePtr)header;
+}
+
+Pix <T>SkipBag::seek(<T&> key, Pix i)
+{
+ <T>SkipBagNodePtr temp;
+ <T>SkipBagNode *curr = header;
+ int l = level;
+ if (i)
+ curr = (<T>SkipBagNode *)i;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header &&
+ <T>CMP(temp->item, key) < 0)
+ curr = temp;
+ }
+ while (--l >= 0);
+
+ if (<T>CMP(temp->item, key) != 0)
+ return 0;
+ else
+ {
+ return Pix(temp);
+ }
+}
+
+
+int <T>SkipBag::nof(<T&> item)
+{
+ int n = 0;
+ <T>SkipBagNodePtr t = (<T>SkipBagNodePtr)(seek(item));
+ if (t != 0)
+ {
+ do
+ {
+ ++n;
+ t = succ(t);
+ } while (t != 0 && <T>EQ(item, t->item));
+ }
+ return n;
+}
+
+void <T>SkipBag::remove(<T&> key)
+{
+ Pix t = seek(key);
+ while (t != 0)
+ {
+ del(key);
+ t = seek(key);
+ }
+}
+
+
+/*
+ * random function for probabilistic balancing
+ *
+ * Hardwired for p = .25. Not too flexible,
+ * but fast. Changing this would require a constructor
+ * that would accept a different value for p, etc.
+ * Perhaps someone else would like to implement this?
+ *
+ */
+int <T>SkipBag::random_level (void)
+{
+ int rlevel = 0;
+ int b;
+
+ do
+ {
+ b = random_bits & 3L;
+ if (!b)
+ rlevel++;
+ random_bits >>= 2;
+ if (--randoms_left == 0)
+ {
+ random_bits = gen->asLong();
+ randoms_left = BITS_IN_RANDOM / 2;
+ };
+ }
+ while (!b);
+
+ return rlevel > max_levels ? max_levels : rlevel;
+}
+
+int <T>SkipBag::OK()
+{
+ int v = 1;
+ if (header == 0)
+ v = 0;
+ else
+ {
+ int n = 0;
+ <T>SkipBagNodePtr trail = leftmost();
+ <T>SkipBagNodePtr t = 0;
+ if (trail) t = succ(trail);
+ if (t) n++;
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+
+<T>SkipBaginit::<T>SkipBaginit()
+{
+ if (!count)
+ <T>SkipBag::gen = new MLCG(time(0));
+ count++;
+}
+
+<T>SkipBaginit::~<T>SkipBaginit()
+{
+ count--;
+ if (!count)
+ delete <T>SkipBag::gen;
+}
diff --git a/gnu/lib/libg++/include/gen/SkipBag.hP b/gnu/lib/libg++/include/gen/SkipBag.hP
new file mode 100644
index 00000000000..647711de373
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SkipBag.hP
@@ -0,0 +1,171 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1991 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Bags implemented via William Pugh SkipList algorithms.
+ * CACM, June 1990, p 668-676.
+ *
+ */
+
+#ifndef _<T>SkipBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SkipBag_h 1
+
+#include "<T>.Bag.h"
+
+#include <limits.h>
+#include <MLCG.h>
+
+class <T>SkipBag;
+class <T>RealSkipBagNode;
+
+class <T>SkipBagNode
+{
+friend class <T>SkipBag;
+ private:
+ <T>RealSkipBagNode * * forward;
+ <T>SkipBagNode(int size);
+};
+
+class <T>RealSkipBagNode : public <T>SkipBagNode
+{
+friend class <T>SkipBag;
+ private:
+ <T> item;
+ <T>RealSkipBagNode(<T&> h, int size);
+};
+
+typedef <T>RealSkipBagNode* <T>SkipBagNodePtr;
+
+inline <T>SkipBagNode::<T>SkipBagNode(int size)
+: forward(new <T>SkipBagNodePtr[size+1])
+{
+}
+
+inline <T>RealSkipBagNode::<T>RealSkipBagNode(<T&> h, int size)
+: item(h),
+ <T>SkipBagNode(size)
+{
+}
+
+class <T>SkipBag : public <T>Bag
+{
+friend class <T>SkipBaginit;
+ protected:
+ <T>SkipBagNode* header;
+ int level;
+ int max_levels;
+ int randoms_left;
+ long random_bits;
+
+ static MLCG* gen;
+ int random_level(void);
+
+ <T>SkipBagNodePtr leftmost(void);
+ <T>SkipBagNodePtr rightmost(void);
+ <T>SkipBagNodePtr pred(<T>SkipBagNodePtr t);
+ <T>SkipBagNodePtr succ(<T>SkipBagNodePtr t);
+ void _kill(void);
+
+ private:
+ enum { BITS_IN_RANDOM = LONGBITS-1 };
+
+ public:
+ <T>SkipBag(long size=DEFAULT_INITIAL_CAPACITY);
+ <T>SkipBag(<T>SkipBag& a);
+ ~<T>SkipBag(void);
+
+ Pix add(<T&> i);
+ void del(<T&> i);
+ void remove(<T&>i);
+ int nof(<T&> i);
+ int contains(<T&> i);
+
+ void clear(void);
+
+ Pix first(void);
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ Pix seek(<T&> i, Pix from = 0);
+
+ Pix last(void);
+ void prev(Pix& i);
+
+ int OK(void);
+};
+
+inline <T>SkipBagNodePtr <T>SkipBag::leftmost(void)
+{
+ return header->forward[0];
+}
+
+inline <T>SkipBagNodePtr <T>SkipBag::succ(<T>SkipBagNodePtr t)
+{
+ <T>SkipBagNodePtr result = 0;
+ if (t->forward[0]!=header) result = t->forward[0];
+ return result;
+}
+
+inline Pix <T>SkipBag::first(void)
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>SkipBag::last(void)
+{
+ return Pix(rightmost());
+}
+
+inline void <T>SkipBag::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>SkipBagNodePtr)i));
+}
+
+inline <T>& <T>SkipBag::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>SkipBagNodePtr)i)->item;
+}
+
+inline void <T>SkipBag::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>SkipBagNodePtr)i));
+}
+
+inline int <T>SkipBag::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>SkipBag::~<T>SkipBag()
+{
+ _kill();
+ delete header;
+}
+
+static class <T>SkipBaginit
+{
+ public:
+ <T>SkipBaginit();
+ ~<T>SkipBaginit();
+ private:
+ static int count;
+} <T>skipBaginit;
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SkipMap.ccP b/gnu/lib/libg++/include/gen/SkipMap.ccP
new file mode 100644
index 00000000000..1d86ad4e303
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SkipMap.ccP
@@ -0,0 +1,307 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1991 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <stream.h>
+#include <time.h>
+#include "<T>.<C>.SkipMap.h"
+
+/*
+ * Bags implemented via William Pugh SkipList algorithms.
+ * CACM, June 1990, p 668-676.
+ *
+ */
+
+MLCG* <T><C>SkipMap::gen = 0;
+int <T><C>SkipMapinit::count = 0;
+
+static int countbits(long bits)
+{
+ int n = 0;
+ while(bits>>=1) n++;
+ return n;
+}
+
+<T><C>SkipMap::<T><C>SkipMap(<C&> dflt, long size)
+: <T><C>Map(dflt),
+ level(0),
+ header(new <T><C>SkipMapNode (countbits(size)+1)),
+ max_levels (countbits(size)+1),
+ random_bits(gen->asLong()),
+ randoms_left(BITS_IN_RANDOM / 2)
+{
+ <T><C>SkipMapNodePtr *buffer_start = header->forward;
+ <T><C>SkipMapNodePtr *trav = &header->forward[max_levels];
+
+ count = 0;
+ while (trav > buffer_start)
+ *--trav = (<T><C>SkipMapNodePtr) header;
+}
+
+<T><C>SkipMap::<T><C>SkipMap(<T><C>SkipMap& b)
+: <T><C>Map(b.def),
+ level (0),
+ header (new <T><C>SkipMapNode (b.max_levels)),
+ max_levels (b.max_levels),
+ random_bits (gen->asLong()),
+ randoms_left (BITS_IN_RANDOM / 2)
+{
+ <T><C>SkipMapNodePtr *buffer_start = header->forward;
+ <T><C>SkipMapNodePtr *trav = &header->forward[max_levels];
+
+ count = 0;
+
+ while (trav > buffer_start)
+ *--trav = (<T><C>SkipMapNodePtr)header;
+
+ for (<T><C>SkipMapNodePtr t = b.leftmost(); t; t = b.succ(t))
+ (*this)[t->item] = t->cont;
+}
+
+<C>& <T><C>SkipMap::operator [] (<T&> item)
+{
+ <T><C>SkipMapNodePtr *update = new <T><C>SkipMapNodePtr[max_levels+1];
+ <T><C>SkipMapNodePtr curr =
+ (<T><C>SkipMapNodePtr) this->header;
+ int l = level;
+ <T><C>SkipMapNodePtr temp;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header &&
+ <T>CMP(temp->item, item) < 0)
+ curr = temp;
+ update[l] = curr;
+ }
+ while (--l >= 0);
+
+ if (temp != header && <T>CMP(temp->item, item) == 0)
+ {
+ delete update;
+ return temp->cont;
+ }
+
+ if ((l = random_level ()) > level)
+ {
+ l = ++level;
+ update[l] = (<T><C>SkipMapNodePtr)header;
+ };
+
+ temp = new <T><C>RealSkipMapNode (item, def, l);
+ <T><C>SkipMapNodePtr *temp_forward = temp->forward;
+
+ do
+ {
+ <T><C>SkipMapNodePtr *curr_forward = update[l]->forward;
+
+ temp_forward[l] = curr_forward[l];
+ curr_forward[l] = temp;
+ }
+ while (--l >= 0);
+
+ count++;
+ delete update;
+ return temp->cont;
+}
+
+void <T><C>SkipMap::del(<T&> key)
+{
+
+ int l = level;
+ int curr_level = level;
+ <T><C>SkipMapNodePtr *update = new <T><C>SkipMapNodePtr[max_levels+1];
+ <T><C>SkipMapNodePtr curr = (<T><C>SkipMapNodePtr)header;
+ <T><C>SkipMapNodePtr temp;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header
+ && <T>CMP(temp->item,key) < 0)
+ curr = temp;
+ update[l] = curr;
+ }
+ while (--l >= 0);
+
+ if (<T>CMP(temp->item,key)==0)
+ {
+ <T><C>SkipMapNodePtr *temp_forward = temp->forward;
+
+ for (l = 0;
+ l <= curr_level && (curr = update[l])->forward[l] == temp;
+ l++)
+ curr->forward[l] = temp_forward[l];
+
+ delete temp;
+
+ <T><C>SkipMapNodePtr *forward = header->forward;
+
+ while (forward[curr_level]==header && curr_level > 0)
+ curr_level--;
+
+ level = curr_level;
+ count--;
+ delete update;
+ return;
+ }
+}
+
+<T><C>SkipMapNodePtr <T><C>SkipMap::rightmost()
+{
+ <T><C>SkipMapNodePtr temp;
+ <T><C>SkipMapNode* curr = header;
+ int l = level;
+
+ do
+ while ((temp = curr->forward[l])!=header)
+ curr = temp;
+ while (--l >= 0);
+
+ return temp==header ? 0 : temp;
+}
+
+<T><C>SkipMapNodePtr <T><C>SkipMap::pred(<T><C>SkipMapNodePtr t)
+{
+ <T><C>SkipMapNodePtr temp, curr = (<T><C>SkipMapNodePtr) header;
+ int l = level;
+
+ do
+ while ((temp = curr->forward[l])!=t)
+ curr = temp;
+ while (--l >= 0);
+
+ return curr == header ? 0 : curr;
+}
+
+void <T><C>SkipMap::_kill()
+{
+ <T><C>SkipMapNode *p = this->header->forward[0];
+
+ while (p != header)
+ {
+ <T><C>SkipMapNodePtr q = p->forward[0];
+ delete p;
+ p = q;
+ }
+}
+
+void <T><C>SkipMap::clear()
+{
+ <T><C>SkipMapNodePtr *buffer_start = header->forward;
+ <T><C>SkipMapNodePtr *trav = &header->forward[level+1];
+ _kill();
+ count = 0;
+
+ while (trav > buffer_start)
+ *--trav = (<T><C>SkipMapNodePtr)header;
+}
+
+Pix <T><C>SkipMap::seek(<T&> key)
+{
+ <T><C>SkipMapNodePtr temp;
+ <T><C>SkipMapNode *curr = header;
+ int l = level;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header &&
+ <T>CMP(temp->item, key) < 0)
+ curr = temp;
+ }
+ while (--l >= 0);
+
+ if (<T>CMP(temp->item, key) != 0)
+ return 0;
+ else
+ {
+ return Pix(temp);
+ }
+}
+
+/*
+ * random function for probabilistic balancing
+ *
+ * Hardwired for p = .25. Not too flexible,
+ * but fast. Changing this would require a constructor
+ * that would accept a different value for p, etc.
+ * Perhaps someone else would like to implement this?
+ *
+ */
+int <T><C>SkipMap::random_level (void)
+{
+ int rlevel = 0;
+ int b;
+
+ do
+ {
+ b = random_bits & 3L;
+ if (!b)
+ rlevel++;
+ random_bits >>= 2;
+ if (--randoms_left == 0)
+ {
+ random_bits = gen->asLong();
+ randoms_left = BITS_IN_RANDOM / 2;
+ };
+ }
+ while (!b);
+
+ return rlevel > max_levels ? max_levels : rlevel;
+}
+
+int <T><C>SkipMap::OK()
+{
+ int v = 1;
+ if (header == 0)
+ v = 0;
+ else
+ {
+ int n = 0;
+ <T><C>SkipMapNodePtr trail = leftmost();
+ <T><C>SkipMapNodePtr t = 0;
+ if (trail) t = succ(trail);
+ if (t) n++;
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+
+<T><C>SkipMapinit::<T><C>SkipMapinit()
+{
+ if (!count)
+ <T><C>SkipMap::gen = new MLCG(time(0));
+ count++;
+}
+
+<T><C>SkipMapinit::~<T><C>SkipMapinit()
+{
+ count--;
+ if (!count)
+ delete <T><C>SkipMap::gen;
+}
+
+
diff --git a/gnu/lib/libg++/include/gen/SkipMap.hP b/gnu/lib/libg++/include/gen/SkipMap.hP
new file mode 100644
index 00000000000..8b48cf9da85
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SkipMap.hP
@@ -0,0 +1,176 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1991 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Bags implemented via William Pugh SkipList algorithms.
+ * CACM, June 1990, p 668-676.
+ *
+ */
+
+#ifndef _<T><C>SkipMap_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>SkipMap_h 1
+
+#include "<T>.<C>.Map.h"
+
+#include <limits.h>
+#include <MLCG.h>
+
+class <T><C>SkipMap;
+class <T><C>RealSkipMapNode;
+
+class <T><C>SkipMapNode
+{
+friend class <T><C>SkipMap;
+ private:
+ <T><C>RealSkipMapNode * * forward;
+ protected:
+ <T><C>SkipMapNode(int size);
+};
+
+class <T><C>RealSkipMapNode : public <T><C>SkipMapNode
+{
+friend class <T><C>SkipMap;
+ private:
+ <T> item;
+ <C> cont;
+ <T><C>RealSkipMapNode(<T&> h, <C&> i, int size);
+};
+
+typedef <T><C>RealSkipMapNode* <T><C>SkipMapNodePtr;
+
+inline <T><C>SkipMapNode::<T><C>SkipMapNode(int size)
+: forward(new <T><C>SkipMapNodePtr[size+1])
+{
+}
+
+inline <T><C>RealSkipMapNode::<T><C>RealSkipMapNode(<T&> h, <C&> i, int size)
+: item(h), cont(i),
+ <T><C>SkipMapNode(size)
+{
+}
+
+class <T><C>SkipMap : public <T><C>Map
+{
+friend class <T><C>SkipMapinit;
+ protected:
+ <T><C>SkipMapNode* header;
+ int level;
+ int max_levels;
+ int randoms_left;
+ long random_bits;
+
+ static MLCG* gen;
+ int random_level(void);
+
+ <T><C>SkipMapNodePtr leftmost();
+ <T><C>SkipMapNodePtr rightmost();
+ <T><C>SkipMapNodePtr pred(<T><C>SkipMapNodePtr t);
+ <T><C>SkipMapNodePtr succ(<T><C>SkipMapNodePtr t);
+ void _kill();
+ private:
+ enum { BITS_IN_RANDOM = LONGBITS-1 };
+
+ public:
+ <T><C>SkipMap( <C&> dflt, long size=DEFAULT_INITIAL_CAPACITY);
+ <T><C>SkipMap(<T><C>SkipMap& a);
+ ~<T><C>SkipMap();
+
+ <C>& operator [] (<T&> key);
+
+ void del(<T&> key);
+
+ Pix first();
+ void next(Pix& i);
+ <T>& key(Pix i);
+ <C>& contents(Pix i);
+
+ Pix seek(<T&> key);
+ int contains(<T&> key);
+ void clear();
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+inline <T><C>SkipMap::~<T><C>SkipMap()
+{
+ _kill();
+ delete header;
+}
+
+inline <T><C>SkipMapNodePtr <T><C>SkipMap::leftmost()
+{
+ return header->forward[0]==header ? 0 : header->forward[0];
+}
+
+inline Pix <T><C>SkipMap::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T><C>SkipMap::last()
+{
+ return Pix(rightmost());
+}
+
+inline <T><C>SkipMapNodePtr <T><C>SkipMap::succ(<T><C>SkipMapNodePtr t)
+{
+ return t->forward[0]==header ? 0 : t->forward[0];
+}
+
+inline void <T><C>SkipMap::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T><C>SkipMapNodePtr)i));
+}
+
+inline void <T><C>SkipMap::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T><C>SkipMapNodePtr)i));
+}
+
+inline <T>& <T><C>SkipMap::key (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>SkipMapNodePtr)i)->item;
+}
+
+inline <C>& <T><C>SkipMap::contents (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>SkipMapNodePtr)i)->cont;
+}
+
+inline int <T><C>SkipMap::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+static class <T><C>SkipMapinit
+{
+ public:
+ <T><C>SkipMapinit();
+ ~<T><C>SkipMapinit();
+ private:
+ static int count;
+} <T><C>skipMapinit;
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SkipSet.ccP b/gnu/lib/libg++/include/gen/SkipSet.ccP
new file mode 100644
index 00000000000..97525be8830
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SkipSet.ccP
@@ -0,0 +1,395 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1991 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Sets implemented via William Pugh SkipList algorithms.
+ * CACM, June 1990, p 668-676.
+ *
+ */
+
+#include <stream.h>
+#include <time.h>
+
+#include "<T>.SkipSet.h"
+
+MLCG* <T>SkipSet::gen = 0;
+int <T>SkipSetinit::count = 0;
+
+static int countbits(long bits)
+{
+ int n = 0;
+ while(bits>>=1L) n++;
+ return n;
+}
+
+<T>SkipSet::<T>SkipSet(long size)
+: level(0),
+ header(new <T>SkipSetNode (countbits(size)+1)),
+ max_levels (countbits(size)+1),
+ random_bits(gen->asLong()),
+ randoms_left(BITS_IN_RANDOM / 2)
+{
+ <T>SkipSetNodePtr *buffer_start = header->forward;
+ <T>SkipSetNodePtr *trav = &header->forward[max_levels];
+
+ count = 0;
+ while (trav > buffer_start)
+ *--trav = (<T>SkipSetNodePtr) header;
+}
+
+<T>SkipSet::<T>SkipSet(<T>SkipSet& b)
+: level (0),
+ header (new <T>SkipSetNode (b.max_levels)),
+ max_levels (b.max_levels),
+ random_bits (gen->asLong()),
+ randoms_left (BITS_IN_RANDOM / 2)
+{
+ <T>SkipSetNodePtr *buffer_start = header->forward;
+ <T>SkipSetNodePtr *trav = &header->forward[max_levels];
+
+ count = 0;
+
+ while (trav > buffer_start)
+ *--trav = (<T>SkipSetNodePtr)header;
+
+ for (<T>SkipSetNodePtr t = b.leftmost(); t; t = b.succ(t))
+ add(t->item);
+}
+
+/* relationals */
+
+int <T>SkipSet::operator == (<T>SkipSet& y)
+{
+ if (count != y.count)
+ return 0;
+ else
+ {
+ <T>SkipSetNodePtr t = leftmost();
+ <T>SkipSetNodePtr u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (!<T>EQ(t->item, u->item))
+ return 0;
+ else
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ }
+ }
+}
+
+int <T>SkipSet::operator <= (<T>SkipSet& y)
+{
+ if (count > y.count)
+ return 0;
+ else
+ {
+ <T>SkipSetNodePtr t = leftmost();
+ <T>SkipSetNodePtr u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (u == 0)
+ return 0;
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ u = y.succ(u);
+ }
+ }
+}
+
+
+void <T>SkipSet::operator |=(<T>SkipSet& y)
+{
+ if (&y == this) return;
+ <T>SkipSetNodePtr u = y.leftmost();
+ while (u != 0)
+ {
+ add(u->item);
+ u = y.succ(u);
+ }
+}
+
+void <T>SkipSet::operator &= (<T>SkipSet& y)
+{
+ if (y.count == 0)
+ clear();
+ else if (&y != this && count != 0)
+ {
+ <T>SkipSetNodePtr t = leftmost();
+ while (t != 0)
+ {
+ <T>SkipSetNodePtr s = succ(t);
+ if (y.seek(t->item) == 0) del(t->item);
+ t = s;
+ }
+ }
+}
+
+
+void <T>SkipSet::operator -=(<T>SkipSet& y)
+{
+ if (&y == this)
+ clear();
+ else if (y.count != 0)
+ {
+ <T>SkipSetNodePtr t = leftmost();
+ while (t != 0)
+ {
+ <T>SkipSetNodePtr s = succ(t);
+ if (y.seek(t->item) != 0) del(t->item);
+ t = s;
+ }
+ }
+}
+
+Pix <T>SkipSet::add (<T&> i)
+{
+ <T>SkipSetNodePtr *update = new <T>SkipSetNodePtr[max_levels+1];
+ <T>SkipSetNodePtr curr = (<T>SkipSetNodePtr) this->header;
+ int l = level;
+ <T>SkipSetNodePtr temp;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header &&
+ <T>CMP(temp->item, i) < 0)
+ curr = temp;
+ update[l] = curr;
+ }
+ while (--l >= 0);
+
+ if (temp != header && <T>CMP(temp->item, i) == 0)
+ return Pix(temp);
+
+ if ((l = random_level ()) > level)
+ {
+ l = ++level;
+ update[l] = (<T>SkipSetNodePtr)header;
+ };
+
+ temp = new <T>RealSkipSetNode (i, l);
+ <T>SkipSetNodePtr *temp_forward = temp->forward;
+
+ do
+ {
+ <T>SkipSetNodePtr *curr_forward = update[l]->forward;
+
+ temp_forward[l] = curr_forward[l];
+ curr_forward[l] = temp;
+ }
+ while (--l >= 0);
+
+ count++;
+ delete update;
+ return Pix(temp);
+}
+
+void <T>SkipSet::del(<T&> key)
+{
+
+ int l = level;
+ int curr_level = level;
+ <T>SkipSetNodePtr *update = new <T>SkipSetNodePtr[max_levels+1];
+ <T>SkipSetNodePtr curr = (<T>SkipSetNodePtr)header;
+ <T>SkipSetNodePtr temp;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header
+ && <T>CMP(temp->item,key) < 0)
+ curr = temp;
+ update[l] = curr;
+ }
+ while (--l >= 0);
+
+ if (<T>CMP(temp->item,key)==0)
+ {
+ <T>SkipSetNodePtr *temp_forward = temp->forward;
+
+ for (l = 0;
+ l <= curr_level && (curr = update[l])->forward[l] == temp;
+ l++)
+ curr->forward[l] = temp_forward[l];
+
+ delete temp;
+
+ <T>SkipSetNodePtr *forward = header->forward;
+
+ while (forward[curr_level]==header && curr_level > 0)
+ curr_level--;
+
+ level = curr_level;
+ count--;
+ delete update;
+ return;
+ }
+}
+
+<T>SkipSetNodePtr <T>SkipSet::rightmost()
+{
+ <T>SkipSetNodePtr temp;
+ <T>SkipSetNode* curr = header;
+ int l = level;
+
+ do
+ while ((temp = curr->forward[l])!=header)
+ curr = temp;
+ while (--l >= 0);
+
+ return temp==header ? 0 : temp;
+}
+
+<T>SkipSetNodePtr <T>SkipSet::pred(<T>SkipSetNodePtr t)
+{
+ <T>SkipSetNodePtr temp, curr = (<T>SkipSetNodePtr) header;
+ int l = level;
+
+ do
+ while ((temp = curr->forward[l])!=t)
+ curr = temp;
+ while (--l >= 0);
+
+ return curr == header ? 0 : curr;
+}
+
+void <T>SkipSet::_kill()
+{
+ <T>SkipSetNode *p = this->header->forward[0];
+
+ while (p != header)
+ {
+ <T>SkipSetNodePtr q = p->forward[0];
+ delete p;
+ p = q;
+ }
+}
+
+void <T>SkipSet::clear()
+{
+ <T>SkipSetNodePtr *buffer_start = header->forward;
+ <T>SkipSetNodePtr *trav = &header->forward[level+1];
+ _kill();
+ count = 0;
+
+ while (trav > buffer_start)
+ *--trav = (<T>SkipSetNodePtr)header;
+}
+
+Pix <T>SkipSet::seek(<T&> key)
+{
+ <T>SkipSetNodePtr temp;
+ <T>SkipSetNode *curr = header;
+ int l = level;
+
+ do
+ {
+ while ((temp = curr->forward[l])!=header &&
+ <T>CMP(temp->item, key) < 0)
+ curr = temp;
+ }
+ while (--l >= 0);
+
+ if (<T>CMP(temp->item, key) != 0)
+ return 0;
+ else
+ {
+ return Pix(temp);
+ }
+}
+
+
+/*
+ * random function for probabilistic balancing
+ *
+ * Hardwired for p = .25. Not too flexible,
+ * but fast. Changing this would require a constructor
+ * that would accept a different value for p, etc.
+ * Perhaps someone else would like to implement this?
+ *
+ */
+int <T>SkipSet::random_level (void)
+{
+ int rlevel = 0;
+ int b;
+
+ do
+ {
+ b = random_bits & 3L;
+ if (!b)
+ rlevel++;
+ random_bits >>= 2;
+ if (--randoms_left == 0)
+ {
+ random_bits = gen->asLong();
+ randoms_left = BITS_IN_RANDOM / 2;
+ };
+ }
+ while (!b);
+
+ return rlevel > max_levels ? max_levels : rlevel;
+}
+
+int <T>SkipSet::OK()
+{
+ int v = 1;
+ if (header == 0)
+ v = 0;
+ else
+ {
+ int n = 0;
+ <T>SkipSetNodePtr trail = leftmost();
+ <T>SkipSetNodePtr t = 0;
+ if (trail) t = succ(trail);
+ if (t) n++;
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+
+<T>SkipSetinit::<T>SkipSetinit()
+{
+ if (!count)
+ <T>SkipSet::gen = new MLCG(time(0));
+ count++;
+}
+
+<T>SkipSetinit::~<T>SkipSetinit()
+{
+ count--;
+ if (!count)
+ delete <T>SkipSet::gen;
+}
diff --git a/gnu/lib/libg++/include/gen/SkipSet.hP b/gnu/lib/libg++/include/gen/SkipSet.hP
new file mode 100644
index 00000000000..d4b782bbadf
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SkipSet.hP
@@ -0,0 +1,187 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1991 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ * Sets implemented via William Pugh SkipList algorithms.
+ * CACM, June 1990, p 668-676.
+ *
+ */
+
+#ifndef _<T>SkipSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SkipSet_h 1
+
+#include "<T>.Set.h"
+
+#include <limits.h>
+#include <MLCG.h>
+
+class <T>SkipSet;
+class <T>RealSkipSetNode;
+
+class <T>SkipSetNode
+{
+friend class <T>SkipSet;
+ private:
+ <T>RealSkipSetNode * * forward;
+ <T>SkipSetNode(int size);
+};
+
+class <T>RealSkipSetNode : public <T>SkipSetNode
+{
+friend class <T>SkipSet;
+ private:
+ <T> item;
+ <T>RealSkipSetNode(<T&> h, int size);
+};
+
+typedef <T>RealSkipSetNode* <T>SkipSetNodePtr;
+
+inline <T>SkipSetNode::<T>SkipSetNode(int size)
+: forward(new <T>SkipSetNodePtr[size+1])
+{
+}
+
+inline <T>RealSkipSetNode::<T>RealSkipSetNode(<T&> h, int size)
+: item(h),
+ <T>SkipSetNode(size)
+{
+}
+
+class <T>SkipSet : public <T>Set
+{
+friend class <T>SkipSetinit;
+ protected:
+ <T>SkipSetNode* header;
+ int level;
+ int max_levels;
+ int randoms_left;
+ long random_bits;
+
+ static MLCG* gen;
+ int random_level(void);
+
+ <T>SkipSetNodePtr leftmost(void);
+ <T>SkipSetNodePtr rightmost(void);
+ <T>SkipSetNodePtr pred(<T>SkipSetNodePtr t);
+ <T>SkipSetNodePtr succ(<T>SkipSetNodePtr t);
+ void _kill(void);
+
+ private:
+ enum { BITS_IN_RANDOM = LONGBITS-1 };
+ public:
+ <T>SkipSet(long size=DEFAULT_INITIAL_CAPACITY);
+ <T>SkipSet(<T>SkipSet& a);
+ ~<T>SkipSet();
+
+ Pix add(<T&> i);
+ void del(<T&> i);
+ int contains(<T&> i);
+
+ void clear(void);
+
+ Pix first(void);
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ Pix seek(<T&> i);
+
+ Pix last(void);
+ void prev(Pix& i);
+
+ void operator |= (<T>SkipSet& b);
+ void operator -= (<T>SkipSet& b);
+ void operator &= (<T>SkipSet& b);
+
+ int operator == (<T>SkipSet& b);
+ int operator != (<T>SkipSet& b);
+ int operator <= (<T>SkipSet& b);
+
+ int OK(void);
+};
+
+/*
+ * A little overkill on the inlines.
+ *
+ */
+
+inline <T>SkipSet::~<T>SkipSet(void)
+{
+ _kill();
+ delete header;
+}
+
+inline int <T>SkipSet::operator != (<T>SkipSet& b)
+{
+ return ! (*this == b);
+}
+
+inline <T>SkipSetNodePtr <T>SkipSet::leftmost(void)
+{
+ return header->forward[0];
+}
+
+inline <T>SkipSetNodePtr <T>SkipSet::succ(<T>SkipSetNodePtr t)
+{
+ <T>SkipSetNodePtr result = 0;
+ if (t->forward[0]!=header) result = t->forward[0];
+ return result;
+}
+
+inline Pix <T>SkipSet::first(void)
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>SkipSet::last(void)
+{
+ return Pix(rightmost());
+}
+
+inline void <T>SkipSet::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>SkipSetNodePtr)i));
+}
+
+inline void <T>SkipSet::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>SkipSetNodePtr)i));
+}
+
+inline <T>& <T>SkipSet::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>SkipSetNodePtr)i)->item;
+}
+
+
+inline int <T>SkipSet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+static class <T>SkipSetinit
+{
+ public:
+ <T>SkipSetinit();
+ ~<T>SkipSetinit();
+ private:
+ static int count;
+} <T>skipSetinit;
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SplayBag.ccP b/gnu/lib/libg++/include/gen/SplayBag.ccP
new file mode 100644
index 00000000000..1ff1421db4d
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayBag.ccP
@@ -0,0 +1,445 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.SplayBag.h"
+
+
+/*
+
+ struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985
+ splay tree algorithms
+
+ All routines use a version of their `simple top-down' splay alg. (p 669)
+
+*/
+
+struct _dummySplayNode
+{
+ <T>SplayNode* lt;
+ <T>SplayNode* rt;
+ <T>SplayNode* par;
+} _dummy_null;
+
+
+/*
+ traversal primitives
+*/
+
+
+<T>SplayNode* <T>SplayBag::leftmost()
+{
+ <T>SplayNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T>SplayNode* <T>SplayBag::rightmost()
+{
+ <T>SplayNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T>SplayNode* <T>SplayBag::succ(<T>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ if (t->rt != 0)
+ {
+ t = t->rt;
+ while (t->lt != 0) t = t->lt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->lt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+<T>SplayNode* <T>SplayBag::pred(<T>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ else if (t->lt != 0)
+ {
+ t = t->lt;
+ while (t->rt != 0) t = t->rt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->rt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+
+
+Pix <T>SplayBag::seek(<T&> key, Pix i)
+{
+ if (root == 0) return 0;
+
+ <T>SplayNode* t = (<T>SplayNode*) i;
+ if (t != 0)
+ {
+ int cmp = <T>CMP(key, t->item);
+ if (cmp == 0)
+ {
+ t = succ(t);
+ if (t != 0 && <T>EQ(key, t->item))
+ return Pix(t);
+ else
+ return 0;
+ }
+ else if (cmp < 0)
+ return 0;
+ }
+
+ t = root;
+ int comp = <T>CMP(key, t->item);
+ if (comp == 0)
+ return Pix(t);
+
+ <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null);
+ <T>SplayNode* l = dummy;
+ <T>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ while (comp != 0)
+ {
+ if (comp > 0)
+ {
+ <T>SplayNode* tr = t->rt;
+ if (tr == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tr->item);
+ if (comp <= 0 || tr->rt == 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ if (comp >= 0)
+ break;
+ }
+ else
+ {
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = tr->rt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ else
+ {
+ <T>SplayNode* tl = t->lt;
+ if (tl == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tl->item);
+ if (comp >= 0 || tl->lt == 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ if (comp <= 0)
+ break;
+ }
+ else
+ {
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tl->lt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ if (comp != 0)
+ return 0;
+ else
+ {
+ l = pred(t);
+ while (l != 0 && <T>EQ(l->item, key)) { t = l; l = pred(l); }
+ return Pix(t);
+ }
+}
+
+int <T>SplayBag::nof(<T&> item)
+{
+ int n = 0;
+ <T>SplayNode* t = (<T>SplayNode*)(seek(item));
+ if (t != 0)
+ {
+ do
+ {
+ ++n;
+ t = succ(t);
+ } while (t != 0 && <T>EQ(item, t->item));
+ }
+ return n;
+}
+
+Pix <T>SplayBag::add(<T&> item)
+{
+ ++count;
+ <T>SplayNode* newnode = new <T>SplayNode(item);
+ <T>SplayNode* t = root;
+ if (t == 0)
+ {
+ root = newnode;
+ return Pix(root);
+ }
+
+ int comp = <T>CMP(item, t->item);
+
+ <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null);
+ <T>SplayNode* l = dummy;
+ <T>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ int done = 0;
+ while (!done)
+ {
+ if (comp >= 0)
+ {
+ <T>SplayNode* tr = t->rt;
+ if (tr == 0)
+ {
+ tr = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, tr->item);
+
+ if (comp <= 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ }
+ else
+ {
+ <T>SplayNode* trr = tr->rt;
+ if (trr == 0)
+ {
+ trr = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, trr->item);
+
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = trr;
+ }
+ }
+ else
+ {
+ <T>SplayNode* tl = t->lt;
+ if (tl == 0)
+ {
+ tl = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, tl->item);
+
+ if (comp >= 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ }
+ else
+ {
+ <T>SplayNode* tll = tl->lt;
+ if (tll == 0)
+ {
+ tll = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, tll->item);
+
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tll;
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return Pix(root);
+}
+
+void <T>SplayBag::_del(<T>SplayNode* t)
+{
+ if (t == 0) return;
+
+ <T>SplayNode* p = t->par;
+
+ --count;
+ if (t->rt == 0)
+ {
+ if (t == root)
+ {
+ if ((root = t->lt) != 0) root->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ if ((p->lt = t->lt) != 0) p->lt->par = p;
+ }
+ else
+ if ((p->rt = t->lt) != 0) p->rt->par = p;
+ }
+ else
+ {
+ <T>SplayNode* r = t->rt;
+ <T>SplayNode* l = r->lt;
+ for(;;)
+ {
+ if (l == 0)
+ {
+ if (t == root)
+ {
+ root = r;
+ r->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ p->lt = r;
+ r->par = p;
+ }
+ else
+ {
+ p->rt = r;
+ r->par = p;
+ }
+ if ((r->lt = t->lt) != 0) r->lt->par = r;
+ break;
+ }
+ else
+ {
+ if ((r->lt = l->rt) != 0) r->lt->par = r;
+ l->rt = r; r->par = l;
+ r = l;
+ l = l->lt;
+ }
+ }
+ }
+ delete t;
+}
+
+
+void <T>SplayBag::remove(<T&> key)
+{
+ <T>SplayNode* t = (<T>SplayNode*)(seek(key));
+ while (t != 0)
+ {
+ _del(t);
+ t = (<T>SplayNode*)(seek(key));
+ }
+}
+
+
+void <T>SplayBag::_kill(<T>SplayNode* t)
+{
+ if (t != 0)
+ {
+ _kill(t->lt);
+ _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T>SplayNode* <T>SplayBag::_copy(<T>SplayNode* t)
+{
+ if (t != 0)
+ {
+ <T>SplayNode* l = _copy(t->lt);
+ <T>SplayNode* r = _copy(t->rt);
+ <T>SplayNode* x = new <T>SplayNode(t->item, l, r);
+ if (l != 0) l->par = x;
+ if (r != 0) r->par = x;
+ return x;
+ }
+ else
+ return 0;
+}
+
+int <T>SplayBag::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T>SplayNode* trail = leftmost();
+ <T>SplayNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) <= 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/include/gen/SplayBag.hP b/gnu/lib/libg++/include/gen/SplayBag.hP
new file mode 100644
index 00000000000..9059d453df5
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayBag.hP
@@ -0,0 +1,126 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1982 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>SplayBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SplayBag_h 1
+
+#include "<T>.Bag.h"
+#include "<T>.SplayNode.h"
+
+class <T>SplayBag : public <T>Bag
+{
+protected:
+ <T>SplayNode* root;
+
+ <T>SplayNode* leftmost();
+ <T>SplayNode* rightmost();
+ <T>SplayNode* pred(<T>SplayNode* t);
+ <T>SplayNode* succ(<T>SplayNode* t);
+ void _kill(<T>SplayNode* t);
+ <T>SplayNode* _copy(<T>SplayNode* t);
+ void _del(<T>SplayNode* t);
+
+public:
+ <T>SplayBag();
+ <T>SplayBag(<T>SplayBag& a);
+ inline ~<T>SplayBag();
+
+ Pix add(<T&> item);
+ inline void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+
+inline <T>SplayBag::~<T>SplayBag()
+{
+ _kill(root);
+}
+
+inline <T>SplayBag::<T>SplayBag()
+{
+ root = 0;
+ count = 0;
+}
+
+inline <T>SplayBag::<T>SplayBag(<T>SplayBag& b)
+{
+ count = b.count;
+ root = _copy(b.root);
+}
+
+inline Pix <T>SplayBag::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>SplayBag::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T>SplayBag::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>SplayNode*)i));
+}
+
+inline void <T>SplayBag::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>SplayNode*)i));
+}
+
+inline <T>& <T>SplayBag::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>SplayNode*)i)->item;
+}
+
+inline void <T>SplayBag::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T>SplayBag::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline void <T>SplayBag::del(<T&> key)
+{
+ _del((<T>SplayNode*)(seek(key)));
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SplayMap.ccP b/gnu/lib/libg++/include/gen/SplayMap.ccP
new file mode 100644
index 00000000000..5b9ffe96a96
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayMap.ccP
@@ -0,0 +1,401 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.<C>.SplayMap.h"
+
+
+/*
+
+ struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985
+ splay tree algorithms
+
+ All routines use a version of their `simple top-down' splay alg. (p 669)
+
+*/
+
+struct _dummySplayNode
+{
+ <T><C>SplayNode* lt;
+ <T><C>SplayNode* rt;
+ <T><C>SplayNode* par;
+} _dummy_null;
+
+
+/*
+ traversal primitives
+*/
+
+
+<T><C>SplayNode* <T><C>SplayMap::leftmost()
+{
+ <T><C>SplayNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T><C>SplayNode* <T><C>SplayMap::rightmost()
+{
+ <T><C>SplayNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T><C>SplayNode* <T><C>SplayMap::succ(<T><C>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ if (t->rt != 0)
+ {
+ t = t->rt;
+ while (t->lt != 0) t = t->lt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->lt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+<T><C>SplayNode* <T><C>SplayMap::pred(<T><C>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ else if (t->lt != 0)
+ {
+ t = t->lt;
+ while (t->rt != 0) t = t->rt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->rt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+
+Pix <T><C>SplayMap::seek(<T&> key)
+{
+ <T><C>SplayNode* t = root;
+ if (t == 0)
+ return 0;
+
+ int comp = <T>CMP(key, t->item);
+ if (comp == 0)
+ return Pix(t);
+
+ <T><C>SplayNode* dummy = (<T><C>SplayNode*)(&_dummy_null);
+ <T><C>SplayNode* l = dummy;
+ <T><C>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ while (comp != 0)
+ {
+ if (comp > 0)
+ {
+ <T><C>SplayNode* tr = t->rt;
+ if (tr == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tr->item);
+ if (comp <= 0 || tr->rt == 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ if (comp >= 0)
+ break;
+ }
+ else
+ {
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = tr->rt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ else
+ {
+ <T><C>SplayNode* tl = t->lt;
+ if (tl == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tl->item);
+ if (comp >= 0 || tl->lt == 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ if (comp <= 0)
+ break;
+ }
+ else
+ {
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tl->lt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return (comp == 0) ? Pix(t) : 0;
+}
+
+
+<C>& <T><C>SplayMap::operator [] (<T&> item)
+{
+ <T><C>SplayNode* t = root;
+ if (t == 0)
+ {
+ ++count;
+ root = new <T><C>SplayNode(item, def);
+ return root->cont;
+ }
+ int comp = <T>CMP(item, t->item);
+ if (comp == 0)
+ return t->cont;
+
+ <T><C>SplayNode* dummy = (<T><C>SplayNode*)(&_dummy_null);
+ <T><C>SplayNode* l = dummy;
+ <T><C>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ while (comp != 0)
+ {
+ if (comp > 0)
+ {
+ <T><C>SplayNode* tr = t->rt;
+ if (tr == 0)
+ {
+ ++count;
+ tr = new <T><C>SplayNode(item, def);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, tr->item);
+
+ if (comp <= 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ }
+ else
+ {
+ <T><C>SplayNode* trr = tr->rt;
+ if (trr == 0)
+ {
+ ++count;
+ trr = new <T><C>SplayNode(item, def);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, trr->item);
+
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = trr;
+ }
+ }
+ else
+ {
+ <T><C>SplayNode* tl = t->lt;
+ if (tl == 0)
+ {
+ ++count;
+ tl = new <T><C>SplayNode(item, def);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, tl->item);
+
+ if (comp >= 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ }
+ else
+ {
+ <T><C>SplayNode* tll = tl->lt;
+ if (tll == 0)
+ {
+ ++count;
+ tll = new <T><C>SplayNode(item, def);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, tll->item);
+
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tll;
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return root->cont;
+}
+
+void <T><C>SplayMap::del(<T&> key)
+{
+ <T><C>SplayNode* t = (<T><C>SplayNode*)(seek(key));
+ if (t == 0) return;
+
+ <T><C>SplayNode* p = t->par;
+
+ --count;
+ if (t->rt == 0)
+ {
+ if (t == root)
+ {
+ if ((root = t->lt) != 0) root->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ if ((p->lt = t->lt) != 0) p->lt->par = p;
+ }
+ else
+ if ((p->rt = t->lt) != 0) p->rt->par = p;
+ }
+ else
+ {
+ <T><C>SplayNode* r = t->rt;
+ <T><C>SplayNode* l = r->lt;
+ for(;;)
+ {
+ if (l == 0)
+ {
+ if (t == root)
+ {
+ root = r;
+ r->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ p->lt = r;
+ r->par = p;
+ }
+ else
+ {
+ p->rt = r;
+ r->par = p;
+ }
+ if ((r->lt = t->lt) != 0) r->lt->par = r;
+ break;
+ }
+ else
+ {
+ if ((r->lt = l->rt) != 0) r->lt->par = r;
+ l->rt = r; r->par = l;
+ r = l;
+ l = l->lt;
+ }
+ }
+ }
+ delete t;
+}
+
+
+void <T><C>SplayMap::_kill(<T><C>SplayNode* t)
+{
+ if (t != 0)
+ {
+ _kill(t->lt);
+ _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T><C>SplayNode* <T><C>SplayMap::_copy(<T><C>SplayNode* t)
+{
+ if (t != 0)
+ {
+ <T><C>SplayNode* l = _copy(t->lt);
+ <T><C>SplayNode* r = _copy(t->rt);
+ <T><C>SplayNode* x = new <T><C>SplayNode(t->item, t->cont, l, r);
+ if (l != 0) l->par = x;
+ if (r != 0) r->par = x;
+ return x;
+ }
+ else
+ return 0;
+}
+
+
+int <T><C>SplayMap::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T><C>SplayNode* trail = leftmost();
+ <T><C>SplayNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/SplayMap.hP b/gnu/lib/libg++/include/gen/SplayMap.hP
new file mode 100644
index 00000000000..3acb1d4b14d
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayMap.hP
@@ -0,0 +1,154 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T><C>SplayMap_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>SplayMap_h 1
+
+#include "<T>.<C>.Map.h"
+
+#ifndef _<T><C>SplayNode
+#define _<T><C>SplayNode 1
+
+struct <T><C>SplayNode
+{
+ <T><C>SplayNode* lt;
+ <T><C>SplayNode* rt;
+ <T><C>SplayNode* par;
+ <T> item;
+ <C> cont;
+ <T><C>SplayNode(<T&> h, <C&> c,
+ <T><C>SplayNode* l=0,
+ <T><C>SplayNode* r=0);
+ ~<T><C>SplayNode();
+};
+
+
+inline <T><C>SplayNode::<T><C>SplayNode(<T&> h, <C&> c,
+ <T><C>SplayNode* l,
+ <T><C>SplayNode* r)
+ :lt(l), rt(r), par(0), item(h), cont(c) {}
+
+inline <T><C>SplayNode::~<T><C>SplayNode() {}
+
+typedef <T><C>SplayNode* <T><C>SplayNodePtr;
+
+#endif
+
+class <T><C>SplayMap : public <T><C>Map
+{
+protected:
+ <T><C>SplayNode* root;
+
+ <T><C>SplayNode* leftmost();
+ <T><C>SplayNode* rightmost();
+ <T><C>SplayNode* pred(<T><C>SplayNode* t);
+ <T><C>SplayNode* succ(<T><C>SplayNode* t);
+ void _kill(<T><C>SplayNode* t);
+ <T><C>SplayNode* _copy(<T><C>SplayNode* t);
+
+public:
+ <T><C>SplayMap(<C&> dflt);
+ <T><C>SplayMap(<T><C>SplayMap& a);
+ inline ~<T><C>SplayMap();
+
+ <C>& operator [] (<T&> key);
+
+ void del(<T&> key);
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& key(Pix i);
+ inline <C>& contents(Pix i);
+
+ Pix seek(<T&> key);
+ inline int contains(<T&> key);
+
+ inline void clear();
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+
+inline <T><C>SplayMap::~<T><C>SplayMap()
+{
+ _kill(root);
+}
+
+inline <T><C>SplayMap::<T><C>SplayMap(<C&> dflt) :<T><C>Map(dflt)
+{
+ root = 0;
+}
+
+inline <T><C>SplayMap::<T><C>SplayMap(<T><C>SplayMap& b) :<T><C>Map(b.def)
+{
+ count = b.count;
+ root = _copy(b.root);
+}
+
+inline Pix <T><C>SplayMap::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T><C>SplayMap::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T><C>SplayMap::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T><C>SplayNode*)i));
+}
+
+inline void <T><C>SplayMap::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T><C>SplayNode*)i));
+}
+
+inline <T>& <T><C>SplayMap::key (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>SplayNode*)i)->item;
+}
+
+inline <C>& <T><C>SplayMap::contents (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T><C>SplayNode*)i)->cont;
+}
+
+inline void <T><C>SplayMap::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T><C>SplayMap::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SplayNode.ccP b/gnu/lib/libg++/include/gen/SplayNode.ccP
new file mode 100644
index 00000000000..74f071140fe
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayNode.ccP
@@ -0,0 +1,21 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1992 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SplayNode.h"
diff --git a/gnu/lib/libg++/include/gen/SplayNode.hP b/gnu/lib/libg++/include/gen/SplayNode.hP
new file mode 100644
index 00000000000..e50ced51dcf
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayNode.hP
@@ -0,0 +1,44 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1982 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>SplayNode
+#define _<T>SplayNode 1
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include "<T>.defs.h"
+
+struct <T>SplayNode
+{
+ <T>SplayNode* lt;
+ <T>SplayNode* rt;
+ <T>SplayNode* par;
+ <T> item;
+ <T>SplayNode(<T&> h, <T>SplayNode* l=0, <T>SplayNode* r=0);
+ ~<T>SplayNode();
+};
+
+
+inline <T>SplayNode::<T>SplayNode(<T&> h, <T>SplayNode* l, <T>SplayNode* r)
+:lt(l), rt(r), par(0), item(h) {}
+
+inline <T>SplayNode::~<T>SplayNode() {}
+
+typedef <T>SplayNode* <T>SplayNodePtr;
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SplayPQ.ccP b/gnu/lib/libg++/include/gen/SplayPQ.ccP
new file mode 100644
index 00000000000..890b9585e3a
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayPQ.ccP
@@ -0,0 +1,523 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.SplayPQ.h"
+
+
+/*
+
+ struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985
+ splay tree algorithms
+
+ All routines use a version of their `simple top-down' splay alg. (p 669)
+
+*/
+
+struct _dummySplayNode
+{
+ <T>SplayNode* lt;
+ <T>SplayNode* rt;
+ <T>SplayNode* par;
+} _dummy_null;
+
+
+/*
+ traversal primitives
+*/
+
+
+<T>SplayNode* <T>SplayPQ::leftmost()
+{
+ <T>SplayNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T>SplayNode* <T>SplayPQ::rightmost()
+{
+ <T>SplayNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T>SplayNode* <T>SplayPQ::succ(<T>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ if (t->rt != 0)
+ {
+ t = t->rt;
+ while (t->lt != 0) t = t->lt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->lt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+<T>SplayNode* <T>SplayPQ::pred(<T>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ else if (t->lt != 0)
+ {
+ t = t->lt;
+ while (t->rt != 0) t = t->rt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->rt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+
+Pix <T>SplayPQ::seek(<T&> key)
+{
+ <T>SplayNode* t = root;
+ if (t == 0)
+ return 0;
+
+ int comp = <T>CMP(key, t->item);
+ if (comp == 0)
+ return Pix(t);
+
+ <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null);
+ <T>SplayNode* l = dummy;
+ <T>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ while (comp != 0)
+ {
+ if (comp > 0)
+ {
+ <T>SplayNode* tr = t->rt;
+ if (tr == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tr->item);
+ if (comp <= 0 || tr->rt == 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ if (comp >= 0)
+ break;
+ }
+ else
+ {
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = tr->rt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ else
+ {
+ <T>SplayNode* tl = t->lt;
+ if (tl == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tl->item);
+ if (comp >= 0 || tl->lt == 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ if (comp <= 0)
+ break;
+ }
+ else
+ {
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tl->lt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return (comp == 0) ? Pix(t) : 0;
+}
+
+
+Pix <T>SplayPQ::enq(<T&> item)
+{
+ ++count;
+ <T>SplayNode* newnode = new <T>SplayNode(item);
+ <T>SplayNode* t = root;
+ if (t == 0)
+ {
+ root = newnode;
+ return Pix(root);
+ }
+
+ int comp = <T>CMP(item, t->item);
+
+ <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null);
+ <T>SplayNode* l = dummy;
+ <T>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ int done = 0;
+ while (!done)
+ {
+ if (comp >= 0)
+ {
+ <T>SplayNode* tr = t->rt;
+ if (tr == 0)
+ {
+ tr = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, tr->item);
+
+ if (comp <= 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ }
+ else
+ {
+ <T>SplayNode* trr = tr->rt;
+ if (trr == 0)
+ {
+ trr = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, trr->item);
+
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = trr;
+ }
+ }
+ else
+ {
+ <T>SplayNode* tl = t->lt;
+ if (tl == 0)
+ {
+ tl = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, tl->item);
+
+ if (comp >= 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ }
+ else
+ {
+ <T>SplayNode* tll = tl->lt;
+ if (tll == 0)
+ {
+ tll = newnode;
+ comp = 0; done = 1;
+ }
+ else
+ comp = <T>CMP(item, tll->item);
+
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tll;
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return Pix(root);
+}
+
+
+void <T>SplayPQ::del(Pix pix)
+{
+ <T>SplayNode* t = (<T>SplayNode*)pix;
+ if (t == 0) return;
+
+ <T>SplayNode* p = t->par;
+
+ --count;
+ if (t->rt == 0)
+ {
+ if (t == root)
+ {
+ if ((root = t->lt) != 0) root->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ if ((p->lt = t->lt) != 0) p->lt->par = p;
+ }
+ else
+ if ((p->rt = t->lt) != 0) p->rt->par = p;
+ }
+ else
+ {
+ <T>SplayNode* r = t->rt;
+ <T>SplayNode* l = r->lt;
+ for(;;)
+ {
+ if (l == 0)
+ {
+ if (t == root)
+ {
+ root = r;
+ r->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ p->lt = r;
+ r->par = p;
+ }
+ else
+ {
+ p->rt = r;
+ r->par = p;
+ }
+ if ((r->lt = t->lt) != 0) r->lt->par = r;
+ break;
+ }
+ else
+ {
+ if ((r->lt = l->rt) != 0) r->lt->par = r;
+ l->rt = r; r->par = l;
+ r = l;
+ l = l->lt;
+ }
+ }
+ }
+ delete t;
+}
+
+<T>& <T>SplayPQ::front()
+{
+ if (root == 0)
+ error ("min: empty tree\n");
+// else
+ {
+ <T>SplayNode* t = root;
+ <T>SplayNode* l = root->lt;
+ for(;;)
+ {
+ if (l == 0)
+ {
+ root = t;
+ root->par = 0;
+ return root->item;
+ }
+ else
+ {
+ if ((t->lt = l->rt) != 0) t->lt->par = t;
+ l->rt = t; t->par = l;
+ t = l;
+ l = l->lt;
+ }
+ }
+ }
+}
+
+void <T>SplayPQ::del_front()
+{
+ if (root != 0)
+ {
+ --count;
+ <T>SplayNode* t = root;
+ <T>SplayNode* l = root->lt;
+ if (l == 0)
+ {
+ if ((root = t->rt) != 0) root->par = 0;
+ delete t;
+ }
+ else
+ {
+ for(;;)
+ {
+ <T>SplayNode* ll = l->lt;
+ if (ll == 0)
+ {
+ if ((t->lt = l->rt) != 0) t->lt->par = t;
+ delete l;
+ break;
+ }
+ else
+ {
+ <T>SplayNode* lll = ll->lt;
+ if (lll == 0)
+ {
+ if ((l->lt = ll->rt) != 0) l->lt->par = l;
+ delete ll;
+ break;
+ }
+ else
+ {
+ t->lt = ll; ll->par = t;
+ if ((l->lt = ll->rt) != 0) l->lt->par = l;
+ ll->rt = l; l->par = ll;
+ t = ll;
+ l = lll;
+ }
+ }
+ }
+ }
+ }
+}
+
+<T> <T>SplayPQ::deq()
+{
+ if (root == 0)
+ error("deq: empty tree");
+// else
+ {
+ --count;
+ <T>SplayNode* t = root;
+ <T>SplayNode* l = root->lt;
+ if (l == 0)
+ {
+ if ((root = t->rt) != 0) root->par = 0;
+ <T> res = t->item;
+ delete t;
+ return res;
+ }
+ else
+ {
+ for(;;)
+ {
+ <T>SplayNode* ll = l->lt;
+ if (ll == 0)
+ {
+ if ((t->lt = l->rt) != 0) t->lt->par = t;
+ <T> res = l->item;
+ delete l;
+ return res;
+ }
+ else
+ {
+ <T>SplayNode* lll = ll->lt;
+ if (lll == 0)
+ {
+ if ((l->lt = ll->rt) != 0) l->lt->par = l;
+ <T> res = ll->item;
+ delete ll;
+ return res;
+ }
+ else
+ {
+ t->lt = ll; ll->par = t;
+ if ((l->lt = ll->rt) != 0) l->lt->par = l;
+ ll->rt = l; l->par = ll;
+ t = ll;
+ l = lll;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void <T>SplayPQ::_kill(<T>SplayNode* t)
+{
+ if (t != 0)
+ {
+ _kill(t->lt);
+ _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T>SplayNode* <T>SplayPQ::_copy(<T>SplayNode* t)
+{
+ if (t != 0)
+ {
+ <T>SplayNode* l = _copy(t->lt);
+ <T>SplayNode* r = _copy(t->rt);
+ <T>SplayNode* x = new <T>SplayNode(t->item, l, r);
+ if (l != 0) l->par = x;
+ if (r != 0) r->par = x;
+ return x;
+ }
+ else
+ return 0;
+}
+
+int <T>SplayPQ::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T>SplayNode* trail = leftmost();
+ <T>SplayNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/SplayPQ.hP b/gnu/lib/libg++/include/gen/SplayPQ.hP
new file mode 100644
index 00000000000..1084892fc8f
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplayPQ.hP
@@ -0,0 +1,123 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>SplayPQ_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SplayPQ_h 1
+
+#include "<T>.PQ.h"
+#include "<T>.SplayNode.h"
+
+class <T>SplayPQ : public <T>PQ
+{
+protected:
+ <T>SplayNode* root;
+
+ <T>SplayNode* leftmost();
+ <T>SplayNode* rightmost();
+ <T>SplayNode* pred(<T>SplayNode* t);
+ <T>SplayNode* succ(<T>SplayNode* t);
+ void _kill(<T>SplayNode* t);
+ <T>SplayNode* _copy(<T>SplayNode* t);
+
+public:
+ <T>SplayPQ();
+ <T>SplayPQ(<T>SplayPQ& a);
+ inline virtual ~<T>SplayPQ();
+
+ Pix enq(<T&> item);
+ <T> deq();
+
+ <T>& front();
+ void del_front();
+
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ Pix last();
+ inline void next(Pix& i);
+ void prev(Pix& i);
+ inline <T>& operator () (Pix i);
+ void del(Pix i);
+ Pix seek(<T&> item);
+
+ int OK(); // rep invariant
+};
+
+
+inline <T>SplayPQ::~<T>SplayPQ()
+{
+ _kill(root);
+}
+
+inline <T>SplayPQ::<T>SplayPQ()
+{
+ root = 0;
+ count = 0;
+}
+
+inline <T>SplayPQ::<T>SplayPQ(<T>SplayPQ& b)
+{
+ count = b.count;
+ root = _copy(b.root);
+}
+
+inline Pix <T>SplayPQ::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>SplayPQ::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T>SplayPQ::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>SplayNode*)i));
+}
+
+inline void <T>SplayPQ::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>SplayNode*)i));
+}
+
+inline <T>& <T>SplayPQ::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>SplayNode*)i)->item;
+}
+
+inline void <T>SplayPQ::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T>SplayPQ::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/SplaySet.ccP b/gnu/lib/libg++/include/gen/SplaySet.ccP
new file mode 100644
index 00000000000..ebee425dbe4
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplaySet.ccP
@@ -0,0 +1,499 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.SplaySet.h"
+
+
+/*
+
+ struct to simulate the special `null' node in the Sleater & Tarjan JACM 1985
+ splay tree algorithms
+
+ All routines use a version of their `simple top-down' splay alg. (p 669)
+
+*/
+
+struct _dummySplayNode
+{
+ <T>SplayNode* lt;
+ <T>SplayNode* rt;
+ <T>SplayNode* par;
+} _dummy_null;
+
+
+/*
+ traversal primitives
+*/
+
+
+<T>SplayNode* <T>SplaySet::leftmost()
+{
+ <T>SplayNode* t = root;
+ if (t != 0) while (t->lt != 0) t = t->lt;
+ return t;
+}
+
+<T>SplayNode* <T>SplaySet::rightmost()
+{
+ <T>SplayNode* t = root;
+ if (t != 0) while (t->rt != 0) t = t->rt;
+ return t;
+}
+
+<T>SplayNode* <T>SplaySet::succ(<T>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ if (t->rt != 0)
+ {
+ t = t->rt;
+ while (t->lt != 0) t = t->lt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->lt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+<T>SplayNode* <T>SplaySet::pred(<T>SplayNode* t)
+{
+ if (t == 0)
+ return 0;
+ else if (t->lt != 0)
+ {
+ t = t->lt;
+ while (t->rt != 0) t = t->rt;
+ return t;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (t->par == 0 || t == t->par->rt)
+ return t->par;
+ else
+ t = t->par;
+ }
+ }
+}
+
+
+Pix <T>SplaySet::seek(<T&> key)
+{
+ <T>SplayNode* t = root;
+ if (t == 0)
+ return 0;
+
+ int comp = <T>CMP(key, t->item);
+ if (comp == 0)
+ return Pix(t);
+
+ <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null);
+ <T>SplayNode* l = dummy;
+ <T>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ while (comp != 0)
+ {
+ if (comp > 0)
+ {
+ <T>SplayNode* tr = t->rt;
+ if (tr == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tr->item);
+ if (comp <= 0 || tr->rt == 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ if (comp >= 0)
+ break;
+ }
+ else
+ {
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = tr->rt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ else
+ {
+ <T>SplayNode* tl = t->lt;
+ if (tl == 0)
+ break;
+ else
+ {
+ comp = <T>CMP(key, tl->item);
+ if (comp >= 0 || tl->lt == 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ if (comp <= 0)
+ break;
+ }
+ else
+ {
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tl->lt;
+ comp = <T>CMP(key, t->item);
+ }
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return (comp == 0) ? Pix(t) : 0;
+}
+
+
+
+Pix <T>SplaySet::add(<T&> item)
+{
+ <T>SplayNode* t = root;
+ if (t == 0)
+ {
+ ++count;
+ root = new <T>SplayNode(item);
+ return Pix(root);
+ }
+ int comp = <T>CMP(item, t->item);
+ if (comp == 0)
+ return Pix(t);
+
+ <T>SplayNode* dummy = (<T>SplayNode*)(&_dummy_null);
+ <T>SplayNode* l = dummy;
+ <T>SplayNode* r = dummy;
+ dummy->rt = dummy->lt = dummy->par = 0;
+
+ while (comp != 0)
+ {
+ if (comp > 0)
+ {
+ <T>SplayNode* tr = t->rt;
+ if (tr == 0)
+ {
+ ++count;
+ tr = new <T>SplayNode(item);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, tr->item);
+
+ if (comp <= 0)
+ {
+ l->rt = t; t->par = l;
+ l = t;
+ t = tr;
+ }
+ else
+ {
+ <T>SplayNode* trr = tr->rt;
+ if (trr == 0)
+ {
+ ++count;
+ trr = new <T>SplayNode(item);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, trr->item);
+
+ if ((t->rt = tr->lt) != 0) t->rt->par = t;
+ tr->lt = t; t->par = tr;
+ l->rt = tr; tr->par = l;
+ l = tr;
+ t = trr;
+ }
+ }
+ else
+ {
+ <T>SplayNode* tl = t->lt;
+ if (tl == 0)
+ {
+ ++count;
+ tl = new <T>SplayNode(item);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, tl->item);
+
+ if (comp >= 0)
+ {
+ r->lt = t; t->par = r;
+ r = t;
+ t = tl;
+ }
+ else
+ {
+ <T>SplayNode* tll = tl->lt;
+ if (tll == 0)
+ {
+ ++count;
+ tll = new <T>SplayNode(item);
+ comp = 0;
+ }
+ else
+ comp = <T>CMP(item, tll->item);
+
+ if ((t->lt = tl->rt) != 0) t->lt->par = t;
+ tl->rt = t; t->par = tl;
+ r->lt = tl; tl->par = r;
+ r = tl;
+ t = tll;
+ }
+ }
+ }
+ if ((r->lt = t->rt) != 0) r->lt->par = r;
+ if ((l->rt = t->lt) != 0) l->rt->par = l;
+ if ((t->lt = dummy->rt) != 0) t->lt->par = t;
+ if ((t->rt = dummy->lt) != 0) t->rt->par = t;
+ t->par = 0;
+ root = t;
+ return Pix(root);
+}
+
+void <T>SplaySet::del(<T&> key)
+{
+ <T>SplayNode* t = (<T>SplayNode*)(seek(key));
+ if (t == 0) return;
+
+ <T>SplayNode* p = t->par;
+
+ --count;
+ if (t->rt == 0)
+ {
+ if (t == root)
+ {
+ if ((root = t->lt) != 0) root->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ if ((p->lt = t->lt) != 0) p->lt->par = p;
+ }
+ else
+ if ((p->rt = t->lt) != 0) p->rt->par = p;
+ }
+ else
+ {
+ <T>SplayNode* r = t->rt;
+ <T>SplayNode* l = r->lt;
+ for(;;)
+ {
+ if (l == 0)
+ {
+ if (t == root)
+ {
+ root = r;
+ r->par = 0;
+ }
+ else if (t == p->lt)
+ {
+ p->lt = r;
+ r->par = p;
+ }
+ else
+ {
+ p->rt = r;
+ r->par = p;
+ }
+ if ((r->lt = t->lt) != 0) r->lt->par = r;
+ break;
+ }
+ else
+ {
+ if ((r->lt = l->rt) != 0) r->lt->par = r;
+ l->rt = r; r->par = l;
+ r = l;
+ l = l->lt;
+ }
+ }
+ }
+ delete t;
+}
+
+
+void <T>SplaySet::_kill(<T>SplayNode* t)
+{
+ if (t != 0)
+ {
+ _kill(t->lt);
+ _kill(t->rt);
+ delete t;
+ }
+}
+
+
+<T>SplayNode* <T>SplaySet::_copy(<T>SplayNode* t)
+{
+ if (t != 0)
+ {
+ <T>SplayNode* l = _copy(t->lt);
+ <T>SplayNode* r = _copy(t->rt);
+ <T>SplayNode* x = new <T>SplayNode(t->item, l, r);
+ if (l != 0) l->par = x;
+ if (r != 0) r->par = x;
+ return x;
+ }
+ else
+ return 0;
+}
+
+/* relationals */
+
+int <T>SplaySet::operator == (<T>SplaySet& y)
+{
+ if (count != y.count)
+ return 0;
+ else
+ {
+ <T>SplayNode* t = leftmost();
+ <T>SplayNode* u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (!<T>EQ(t->item, u->item))
+ return 0;
+ else
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ }
+ }
+}
+
+int <T>SplaySet::operator <= (<T>SplaySet& y)
+{
+ if (count > y.count)
+ return 0;
+ else
+ {
+ <T>SplayNode* t = leftmost();
+ <T>SplayNode* u = y.leftmost();
+ for (;;)
+ {
+ if (t == 0)
+ return 1;
+ else if (u == 0)
+ return 0;
+ int cmp = <T>CMP(t->item, u->item);
+ if (cmp == 0)
+ {
+ t = succ(t);
+ u = y.succ(u);
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ u = y.succ(u);
+ }
+ }
+}
+
+
+void <T>SplaySet::operator |=(<T>SplaySet& y)
+{
+ if (&y == this) return;
+ <T>SplayNode* u = y.leftmost();
+ while (u != 0)
+ {
+ add(u->item);
+ u = y.succ(u);
+ }
+}
+
+void <T>SplaySet::operator &= (<T>SplaySet& y)
+{
+ if (y.count == 0)
+ clear();
+ else if (&y != this && count != 0)
+ {
+ <T>SplayNode* t = leftmost();
+ while (t != 0)
+ {
+ <T>SplayNode* s = succ(t);
+ if (y.seek(t->item) == 0) del(t->item);
+ t = s;
+ }
+ }
+}
+
+
+void <T>SplaySet::operator -=(<T>SplaySet& y)
+{
+ if (&y == this)
+ clear();
+ else if (y.count != 0)
+ {
+ <T>SplayNode* t = leftmost();
+ while (t != 0)
+ {
+ <T>SplayNode* s = succ(t);
+ if (y.seek(t->item) != 0) del(t->item);
+ t = s;
+ }
+ }
+}
+
+int <T>SplaySet::OK()
+{
+ int v = 1;
+ if (root == 0)
+ v = count == 0;
+ else
+ {
+ int n = 1;
+ <T>SplayNode* trail = leftmost();
+ <T>SplayNode* t = succ(trail);
+ while (t != 0)
+ {
+ ++n;
+ v &= <T>CMP(trail->item, t->item) < 0;
+ trail = t;
+ t = succ(t);
+ }
+ v &= n == count;
+ }
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/SplaySet.hP b/gnu/lib/libg++/include/gen/SplaySet.hP
new file mode 100644
index 00000000000..e6935833481
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/SplaySet.hP
@@ -0,0 +1,145 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>SplaySet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>SplaySet_h 1
+
+#include "<T>.Set.h"
+#include "<T>.SplayNode.h"
+
+class <T>SplaySet : public <T>Set
+{
+protected:
+ <T>SplayNode* root;
+
+ <T>SplayNode* leftmost();
+ <T>SplayNode* rightmost();
+ <T>SplayNode* pred(<T>SplayNode* t);
+ <T>SplayNode* succ(<T>SplayNode* t);
+ void _kill(<T>SplayNode* t);
+ <T>SplayNode* _copy(<T>SplayNode* t);
+
+public:
+ <T>SplaySet();
+ <T>SplaySet(<T>SplaySet& a);
+ inline ~<T>SplaySet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item);
+
+ Pix last();
+ void prev(Pix& i);
+
+ <T>SplaySet& operator = (const <T>SplaySet& b);
+ void operator |= (<T>SplaySet& b);
+ void operator -= (<T>SplaySet& b);
+ void operator &= (<T>SplaySet& b);
+
+ int operator == (<T>SplaySet& b);
+ int operator != (<T>SplaySet& b);
+ int operator <= (<T>SplaySet& b);
+
+ int OK();
+};
+
+
+inline <T>SplaySet::~<T>SplaySet()
+{
+ _kill(root);
+}
+
+inline <T>SplaySet::<T>SplaySet()
+{
+ root = 0;
+ count = 0;
+}
+
+inline <T>SplaySet::<T>SplaySet(<T>SplaySet& b)
+{
+ count = b.count;
+ root = _copy(b.root);
+}
+
+
+inline <T>SplaySet& <T>SplaySet::operator = (const <T>SplaySet& b)
+{
+ if (this != &b)
+ {
+ _kill (root);
+ count = b.count;
+ root = _copy (b.root);
+ }
+ return *this;
+}
+
+inline int <T>SplaySet::operator != (<T>SplaySet& b)
+{
+ return ! (*this == b);
+}
+
+inline Pix <T>SplaySet::first()
+{
+ return Pix(leftmost());
+}
+
+inline Pix <T>SplaySet::last()
+{
+ return Pix(rightmost());
+}
+
+inline void <T>SplaySet::next(Pix& i)
+{
+ if (i != 0) i = Pix(succ((<T>SplayNode*)i));
+}
+
+inline void <T>SplaySet::prev(Pix& i)
+{
+ if (i != 0) i = Pix(pred((<T>SplayNode*)i));
+}
+
+inline <T>& <T>SplaySet::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return ((<T>SplayNode*)i)->item;
+}
+
+inline void <T>SplaySet::clear()
+{
+ _kill(root);
+ count = 0;
+ root = 0;
+}
+
+inline int <T>SplaySet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Stack.ccP b/gnu/lib/libg++/include/gen/Stack.ccP
new file mode 100644
index 00000000000..efb6b8edbde
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Stack.ccP
@@ -0,0 +1,11 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.Stack.h"
+
+<T>Stack::~<T>Stack() {}
+
+void <T>Stack::error(const char* msg)
+{
+ (*lib_error_handler)("Stack", msg);
+}
diff --git a/gnu/lib/libg++/include/gen/Stack.hP b/gnu/lib/libg++/include/gen/Stack.hP
new file mode 100644
index 00000000000..094676880fc
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Stack.hP
@@ -0,0 +1,51 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>Stack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Stack_h
+
+#include <builtin.h>
+
+#include "<T>.defs.h"
+
+class <T>Stack
+{
+public:
+ <T>Stack() { }
+ virtual ~<T>Stack();
+
+ virtual void push(<T&> item) = 0;
+ virtual <T> pop() = 0;
+ virtual <T>& top() = 0;
+ virtual void del_top() = 0;
+
+ virtual int empty() = 0;
+ virtual int full() = 0;
+ virtual int length() = 0;
+
+ virtual void clear() = 0;
+
+ void error(const char*);
+ virtual int OK() = 0;
+};
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/VHBag.ccP b/gnu/lib/libg++/include/gen/VHBag.ccP
new file mode 100644
index 00000000000..daa8313beae
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VHBag.ccP
@@ -0,0 +1,264 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.VHBag.h"
+
+/* codes for status fields */
+
+#define EMPTYCELL 0
+#define VALIDCELL 1
+#define DELETEDCELL 2
+
+
+<T>VHBag::<T>VHBag(unsigned int sz)
+{
+ tab = new <T>[size = sz];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+}
+
+<T>VHBag::<T>VHBag(<T>VHBag& a)
+{
+ tab = new <T>[size = a.size];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+ for (Pix p = a.first(); p; a.next(p)) add(a(p));
+}
+
+
+/*
+ * hashing method: double hash based on high bits of hash fct,
+ * followed by linear probe. Can't do too much better if table
+ * sizes not constrained to be prime.
+*/
+
+
+static inline unsigned int doublehashinc(unsigned int h, unsigned int s)
+{
+ unsigned int dh = ((h / s) % s);
+ return (dh > 1)? dh : 1;
+}
+
+Pix <T>VHBag::seek(<T&> key, Pix p)
+{
+ <T>* t = (<T>*) p;
+ if (t == 0 || !<T>EQ(*t, key))
+ {
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return 0;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ return Pix(&tab[h]);
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ return 0;
+ }
+ else
+ {
+ int seent = 0;
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return 0;
+ else if (&tab[h] == t)
+ seent = 1;
+ else if (seent && status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ return Pix(&tab[h]);
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ return 0;
+ }
+}
+
+int <T>VHBag::nof(<T&> item)
+{
+ int n = 0;
+ unsigned int hashval = <T>HASH(item);
+ unsigned int h = hashval % size;
+ unsigned int firsth = size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return n;
+ else if (h != firsth && status[h] == VALIDCELL && <T>EQ(item, tab[h]))
+ {
+ ++n;
+ if (firsth >= size)
+ firsth = h;
+ }
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ return n;
+}
+
+
+Pix <T>VHBag::add(<T&> item)
+{
+ if (HASHTABLE_TOO_CROWDED(count, size))
+ resize();
+ unsigned int bestspot = size;
+ unsigned int hashval = <T>HASH(item);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ {
+ if (bestspot >= size) bestspot = h;
+ tab[bestspot] = item;
+ status[bestspot] = VALIDCELL;
+ ++count;
+ return Pix(&tab[bestspot]);
+ }
+ else if (status[h] == DELETEDCELL)
+ {
+ if (bestspot >= size) bestspot = h;
+ }
+
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ tab[bestspot] = item;
+ status[bestspot] = VALIDCELL;
+ ++count;
+ return Pix(&tab[bestspot]);
+}
+
+
+void <T>VHBag::del(<T&> key)
+{
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ {
+ status[h] = DELETEDCELL;
+ --count;
+ return;
+ }
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+}
+
+void <T>VHBag::remove(<T&> key)
+{
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ {
+ status[h] = DELETEDCELL;
+ --count;
+ }
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+}
+
+void <T>VHBag::clear()
+{
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+}
+
+void <T>VHBag::resize(unsigned int newsize)
+{
+ if (newsize <= count)
+ {
+ newsize = DEFAULT_INITIAL_CAPACITY;
+ while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1;
+ }
+ <T>* oldtab = tab;
+ char* oldstatus = status;
+ unsigned int oldsize = size;
+ tab = new <T>[size = newsize];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+ for (unsigned int i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
+ delete [] oldtab;
+ delete oldstatus;
+}
+
+Pix <T>VHBag::first()
+{
+ for (unsigned int pos = 0; pos < size; ++pos)
+ if (status[pos] == VALIDCELL) return Pix(&tab[pos]);
+ return 0;
+}
+
+void <T>VHBag::next(Pix& i)
+{
+ if (i == 0) return;
+ unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1;
+ for (; pos < size; ++pos)
+ if (status[pos] == VALIDCELL)
+ {
+ i = Pix(&tab[pos]);
+ return;
+ }
+ i = 0;
+}
+
+
+int <T>VHBag::OK()
+{
+ int v = tab != 0;
+ v &= status != 0;
+ int n = 0;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL) ++n;
+ else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL)
+ v = 0;
+ }
+ v &= n == count;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/VHBag.hP b/gnu/lib/libg++/include/gen/VHBag.hP
new file mode 100644
index 00000000000..7a7cc32e468
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VHBag.hP
@@ -0,0 +1,84 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>VHBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>VHBag_h 1
+
+#include "<T>.Bag.h"
+
+
+class <T>VHBag : public <T>Bag
+{
+protected:
+ <T>* tab;
+ char* status;
+ unsigned int size;
+
+public:
+ <T>VHBag(unsigned int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>VHBag(<T>VHBag& a);
+ inline ~<T>VHBag();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ inline int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int capacity();
+ void resize(unsigned int newsize = 0);
+
+ int OK();
+};
+
+
+inline <T>VHBag::~<T>VHBag()
+{
+ delete [] tab;
+ delete status;
+}
+
+
+inline int <T>VHBag::capacity()
+{
+ return size;
+}
+
+inline int <T>VHBag::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>& <T>VHBag::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return *((<T>*)i);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/VHMap.ccP b/gnu/lib/libg++/include/gen/VHMap.ccP
new file mode 100644
index 00000000000..d3f2fcfc835
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VHMap.ccP
@@ -0,0 +1,210 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.<C>.VHMap.h"
+
+/* codes for status fields */
+
+#define EMPTYCELL 0
+#define VALIDCELL 1
+#define DELETEDCELL 2
+
+
+<T><C>VHMap::<T><C>VHMap(<C&> dflt, unsigned int sz)
+ :<T><C>Map(dflt)
+{
+ tab = new <T>[size = sz];
+ cont = new <C>[size];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+}
+
+<T><C>VHMap::<T><C>VHMap(<T><C>VHMap& a) : <T><C>Map(a.def)
+{
+ tab = new <T>[size = a.size];
+ cont = new <C>[size];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+ for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p);
+}
+
+
+/*
+ * hashing method: double hash based on high bits of hash fct,
+ * followed by linear probe. Can't do too much better if table
+ * sizes not constrained to be prime.
+*/
+
+
+static inline unsigned int doublehashinc(unsigned int h, unsigned int s)
+{
+ unsigned int dh = ((h / s) % s);
+ return (dh > 1)? dh : 1;
+}
+
+Pix <T><C>VHMap::seek(<T&> key)
+{
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return 0;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ return Pix(&tab[h]);
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ return 0;
+}
+
+
+<C>& <T><C>VHMap::operator [](<T&> item)
+{
+ if (HASHTABLE_TOO_CROWDED(count, size))
+ resize();
+
+ unsigned int bestspot = size;
+ unsigned int hashval = <T>HASH(item);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ {
+ ++count;
+ if (bestspot >= size) bestspot = h;
+ tab[bestspot] = item;
+ status[bestspot] = VALIDCELL;
+ cont[bestspot] = def;
+ return cont[bestspot];
+ }
+ else if (status[h] == DELETEDCELL)
+ {
+ if (bestspot >= size) bestspot = h;
+ }
+ else if (<T>EQ(tab[h],item))
+ return cont[h];
+
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+
+ ++count;
+ status[bestspot] = VALIDCELL;
+ tab[bestspot] = item;
+ cont[bestspot] = def;
+ return cont[bestspot];
+}
+
+
+void <T><C>VHMap::del(<T&> key)
+{
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ {
+ status[h] = DELETEDCELL;
+ --count;
+ return;
+ }
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+}
+
+
+void <T><C>VHMap::clear()
+{
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+}
+
+void <T><C>VHMap::resize(unsigned int newsize)
+{
+ if (newsize <= count)
+ {
+ newsize = DEFAULT_INITIAL_CAPACITY;
+ while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1;
+ }
+ <T>* oldtab = tab;
+ <C>* oldcont = cont;
+ char* oldstatus = status;
+ unsigned int oldsize = size;
+ tab = new <T>[size = newsize];
+ cont = new <C>[size];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+ for (unsigned int i = 0; i < oldsize; ++i)
+ if (oldstatus[i] == VALIDCELL)
+ (*this)[oldtab[i]] = oldcont[i];
+ delete [] oldtab;
+ delete [] oldcont;
+ delete oldstatus;
+}
+
+Pix <T><C>VHMap::first()
+{
+ for (unsigned int pos = 0; pos < size; ++pos)
+ if (status[pos] == VALIDCELL) return Pix(&tab[pos]);
+ return 0;
+}
+
+void <T><C>VHMap::next(Pix& i)
+{
+ if (i == 0) return;
+ unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1;
+ for (; pos < size; ++pos)
+ if (status[pos] == VALIDCELL)
+ {
+ i = Pix(&tab[pos]);
+ return;
+ }
+ i = 0;
+}
+
+
+int <T><C>VHMap::OK()
+{
+ int v = tab != 0;
+ v &= status != 0;
+ int n = 0;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL) ++n;
+ else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL)
+ v = 0;
+ }
+ v &= n == count;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/VHMap.hP b/gnu/lib/libg++/include/gen/VHMap.hP
new file mode 100644
index 00000000000..ccc9328bcba
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VHMap.hP
@@ -0,0 +1,84 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T><C>VHMap_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T><C>VHMap_h 1
+
+#include "<T>.<C>.Map.h"
+
+
+class <T><C>VHMap : public <T><C>Map
+{
+protected:
+ <T>* tab;
+ <C>* cont;
+ char* status;
+ unsigned int size;
+
+public:
+ <T><C>VHMap(<C&> dflt,unsigned int sz=DEFAULT_INITIAL_CAPACITY);
+ <T><C>VHMap(<T><C>VHMap& a);
+ inline ~<T><C>VHMap();
+
+ <C>& operator [] (<T&> key);
+
+ void del(<T&> key);
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& key(Pix i);
+ inline <C>& contents(Pix i);
+
+ Pix seek(<T&> key);
+ inline int contains(<T&> key);
+
+ void clear();
+ void resize(unsigned int newsize = 0);
+
+ int OK();
+};
+
+inline <T><C>VHMap::~<T><C>VHMap()
+{
+ delete [] tab;
+ delete [] cont;
+ delete [] status;
+}
+
+inline int <T><C>VHMap::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>& <T><C>VHMap::key(Pix i)
+{
+ if (i == 0) error("null Pix");
+ return *((<T>*)i);
+}
+
+inline <C>& <T><C>VHMap::contents(Pix i)
+{
+ if (i == 0) error("null Pix");
+ return cont[((unsigned)(i) - (unsigned)(tab)) / sizeof(<T>)];
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/VHSet.ccP b/gnu/lib/libg++/include/gen/VHSet.ccP
new file mode 100644
index 00000000000..414a7288207
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VHSet.ccP
@@ -0,0 +1,263 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.VHSet.h"
+
+/* codes for status fields */
+
+#define EMPTYCELL 0
+#define VALIDCELL 1
+#define DELETEDCELL 2
+
+
+<T>VHSet::<T>VHSet(unsigned int sz)
+{
+ tab = new <T>[size = sz];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+}
+
+<T>VHSet::<T>VHSet(<T>VHSet& a)
+{
+ tab = new <T>[size = a.size];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+ for (Pix p = a.first(); p; a.next(p)) add(a(p));
+}
+
+
+/*
+ * hashing method: double hash based on high bits of hash fct,
+ * followed by linear probe. Can't do too much better if table
+ * sizes not constrained to be prime.
+*/
+
+
+static inline unsigned int doublehashinc(unsigned int h, unsigned int s)
+{
+ unsigned int dh = ((h / s) % s);
+ return (dh > 1)? dh : 1;
+}
+
+Pix <T>VHSet::seek(<T&> key)
+{
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return 0;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ return Pix(&tab[h]);
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ return 0;
+}
+
+
+Pix <T>VHSet::add(<T&> item)
+{
+ if (HASHTABLE_TOO_CROWDED(count, size))
+ resize();
+
+ unsigned int bestspot = size;
+ unsigned int hashval = <T>HASH(item);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ {
+ if (bestspot >= size) bestspot = h;
+ tab[bestspot] = item;
+ status[bestspot] = VALIDCELL;
+ ++count;
+ return Pix(&tab[bestspot]);
+ }
+ else if (status[h] == DELETEDCELL)
+ {
+ if (bestspot >= size) bestspot = h;
+ }
+ else if (<T>EQ(tab[h],item))
+ return Pix(&tab[h]);
+
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+ tab[bestspot] = item;
+ status[bestspot] = VALIDCELL;
+ ++count;
+ return Pix(&tab[bestspot]);
+
+}
+
+
+void <T>VHSet::del(<T&> key)
+{
+ unsigned int hashval = <T>HASH(key);
+ unsigned int h = hashval % size;
+ for (unsigned int i = 0; i <= size; ++i)
+ {
+ if (status[h] == EMPTYCELL)
+ return;
+ else if (status[h] == VALIDCELL && <T>EQ(key, tab[h]))
+ {
+ status[h] = DELETEDCELL;
+ --count;
+ return;
+ }
+ if (i == 0)
+ h = (h + doublehashinc(hashval, size)) % size;
+ else if (++h >= size)
+ h -= size;
+ }
+}
+
+
+void <T>VHSet::clear()
+{
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+}
+
+void <T>VHSet::resize(unsigned int newsize)
+{
+ if (newsize <= count)
+ {
+ newsize = DEFAULT_INITIAL_CAPACITY;
+ while (HASHTABLE_TOO_CROWDED(count, newsize)) newsize <<= 1;
+ }
+ <T>* oldtab = tab;
+ char* oldstatus = status;
+ unsigned int oldsize = size;
+ tab = new <T>[size = newsize];
+ status = new char[size];
+ for (unsigned int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = 0;
+ for (unsigned int i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
+ delete [] oldtab;
+ delete oldstatus;
+}
+
+Pix <T>VHSet::first()
+{
+ for (unsigned int pos = 0; pos < size; ++pos)
+ if (status[pos] == VALIDCELL) return Pix(&tab[pos]);
+ return 0;
+}
+
+void <T>VHSet::next(Pix& i)
+{
+ if (i == 0) return;
+ unsigned int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1;
+ for (; pos < size; ++pos)
+ if (status[pos] == VALIDCELL)
+ {
+ i = Pix(&tab[pos]);
+ return;
+ }
+ i = 0;
+}
+
+int <T>VHSet:: operator == (<T>VHSet& b)
+{
+ if (count != b.count)
+ return 0;
+ else
+ {
+ for (unsigned int i = 0; i < size; ++i)
+ if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
+ return 0;
+ for (unsigned int i = 0; i < b.size; ++i)
+ if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0)
+ return 0;
+ return 1;
+ }
+}
+
+int <T>VHSet::operator <= (<T>VHSet& b)
+{
+ if (count > b.count)
+ return 0;
+ else
+ {
+ for (unsigned int i = 0; i < size; ++i)
+ if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
+ return 0;
+ return 1;
+ }
+}
+
+void <T>VHSet::operator |= (<T>VHSet& b)
+{
+ if (&b == this || b.count == 0)
+ return;
+ for (unsigned int i = 0; i < b.size; ++i)
+ if (b.status[i] == VALIDCELL) add(b.tab[i]);
+}
+
+void <T>VHSet::operator &= (<T>VHSet& b)
+{
+ if (&b == this || count == 0)
+ return;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
+ {
+ status[i] = DELETEDCELL;
+ --count;
+ }
+ }
+}
+
+void <T>VHSet::operator -= (<T>VHSet& b)
+{
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL && b.seek(tab[i]) != 0)
+ {
+ status[i] = DELETEDCELL;
+ --count;
+ }
+ }
+}
+
+int <T>VHSet::OK()
+{
+ int v = tab != 0;
+ v &= status != 0;
+ int n = 0;
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL) ++n;
+ else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL)
+ v = 0;
+ }
+ v &= n == count;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/VHSet.hP b/gnu/lib/libg++/include/gen/VHSet.hP
new file mode 100644
index 00000000000..e7180b32020
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VHSet.hP
@@ -0,0 +1,96 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>VHSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>VHSet_h 1
+
+#include "<T>.Set.h"
+
+
+
+class <T>VHSet : public <T>Set
+{
+protected:
+ <T>* tab;
+ char* status;
+ unsigned int size;
+
+public:
+ <T>VHSet(unsigned int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>VHSet(<T>VHSet& a);
+ inline ~<T>VHSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item);
+
+ void operator |= (<T>VHSet& b);
+ void operator -= (<T>VHSet& b);
+ void operator &= (<T>VHSet& b);
+
+ int operator == (<T>VHSet& b);
+ int operator != (<T>VHSet& b);
+ int operator <= (<T>VHSet& b);
+
+ int capacity();
+ void resize(unsigned int newsize = 0);
+
+ int OK();
+};
+
+
+inline <T>VHSet::~<T>VHSet()
+{
+ delete [] tab;
+ delete status;
+}
+
+
+inline int <T>VHSet::capacity()
+{
+ return size;
+}
+
+inline int <T>VHSet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+inline <T>& <T>VHSet::operator () (Pix i)
+{
+ if (i == 0) error("null Pix");
+ return *((<T>*)i);
+}
+
+inline int <T>VHSet::operator != (<T>VHSet& b)
+{
+ return ! ((*this) == b);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/VOHSet.ccP b/gnu/lib/libg++/include/gen/VOHSet.ccP
new file mode 100644
index 00000000000..252fdcb4c5b
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VOHSet.ccP
@@ -0,0 +1,305 @@
+// 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)
+ based on code by Doug Schmidt
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.VOHSet.h"
+
+
+/* codes for status fields */
+#define EMPTYCELL 0
+#define VALIDCELL 1
+#define DELETEDCELL 2
+
+
+<T>VOHSet::<T>VOHSet(int sz)
+{
+// The size of the hash table is always the smallest power of 2 >= the size
+// indicated by the user. This allows several optimizations, including
+// the use of actual double hashing and elimination of the mod instruction.
+
+ size = 1;
+ while (size < sz) size <<= 1;
+ tab = new <T>[size];
+ status = new char[size];
+ for (int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = cnt = 0;
+}
+
+<T>VOHSet::<T>VOHSet(<T>VOHSet& a)
+{
+ tab = new <T>[size = a.size];
+ status = new char[size];
+ for (int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = cnt = 0;
+ for (Pix p = a.first(); p; a.next(p)) add(a(p));
+}
+
+Pix <T>VOHSet::seek(<T&> key)
+{
+// Uses ordered double hashing to perform a search of the table.
+// This greatly speeds up the average-case time for an unsuccessful search.
+
+ unsigned hashval = <T>HASH(key);
+
+ // We can avoid the mod operation since size is a power of 2.
+ unsigned h = hashval & (size - 1);
+
+ // The increment must be odd, since all odd numbers are relatively
+ // prime to a power of 2!!
+ unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1));
+
+ // There is always at least 1 empty cell, so this loop is guaranteed to halt!
+ while (status[h] != EMPTYCELL)
+ {
+ int cmp = <T>CMP (key, tab[h]);
+ if (cmp == 0)
+ {
+ if (status[h] == VALIDCELL)
+ return Pix(&tab[h]);
+ else
+ return 0;
+ }
+ else if (cmp < 0)
+ return 0;
+ else
+ h = ((h + inc) & (size - 1));
+ }
+ return 0;
+}
+
+// This adds an item if it doesn't already exist. By performing the initial
+// comparison we assure that the table always contains at least 1 empty
+// spot. This speeds up later searching by a constant factor.
+// The insertion algorithm uses ordered double hashing. See Standish's
+// 1980 ``Data Structure's Techniques'' book for details.
+
+Pix <T>VOHSet::add(<T&> x)
+{
+ if (size <= cnt+1)
+ resize();
+
+ unsigned hashval = <T>HASH(x);
+ unsigned h = hashval & (size - 1);
+
+ if (status[h] != VALIDCELL) // save some work if possible
+ {
+ if (status[h] == EMPTYCELL)
+ cnt++;
+ count++;
+ tab[h] = x;
+ status[h] = VALIDCELL;
+ return Pix(&tab[h]);
+ }
+
+ <T> item = x;
+ Pix mypix = 0;
+ unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1));
+
+ for (;;)
+ {
+ if (status[h] != VALIDCELL)
+ {
+ if (status[h] == EMPTYCELL)
+ cnt++;
+ count++;
+ tab[h] = item;
+ status[h] = VALIDCELL;
+ return (mypix == 0)? Pix(&tab[h]) : mypix;
+ }
+ int cmp = <T>CMP(item, tab[h]);
+ if (cmp == 0)
+ return (mypix == 0)? Pix(&tab[h]) : mypix;
+ else if (cmp < 0)
+ {
+ <T> temp = tab[h];
+ tab[h] = item;
+ item = temp;
+ if (mypix == 0) mypix = Pix(&tab[h]);
+ hashval = <T>HASH(item);
+ h = hashval & (size - 1);
+ inc = ((((hashval / size) << 1) + 1) & (size - 1));
+ }
+ else
+ h = ((h + inc) & (size - 1));
+ }
+}
+
+
+void <T>VOHSet::del(<T&> key)
+{
+// This performs a deletion by marking the item's status field.
+// Note that we only decrease the count, *not* the cnt, since this
+// would cause trouble for subsequent steps in the algorithm. See
+// Reingold and Hanson's ``Data Structure's'' book for a justification
+// of this approach.
+
+ unsigned hashval = <T>HASH(key);
+ unsigned h = hashval & (size - 1);
+ unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1));
+
+ while (status[h] != EMPTYCELL)
+ {
+ int cmp = <T>CMP(key, tab[h]);
+ if (cmp > 0)
+ h = ((h + inc) & (size - 1));
+ else if (status[h] == VALIDCELL && cmp == 0)
+ {
+ status[h] = DELETEDCELL;
+ count--;
+ return;
+ }
+ else
+ return;
+ }
+}
+
+void <T>VOHSet::clear()
+{
+ for (int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = cnt = 0;
+}
+
+void <T>VOHSet::resize(int newsize)
+{
+ if (newsize <= count)
+ newsize = count;
+ int s = 1;
+ while (s <= newsize) s <<= 1;
+ newsize = s;
+
+ <T>* oldtab = tab;
+ char* oldstatus = status;
+ int oldsize = size;
+ tab = new <T>[size = newsize];
+ status = new char[size];
+ for (int i = 0; i < size; ++i) status[i] = EMPTYCELL;
+ count = cnt = 0;
+
+ for (int i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
+ delete [] oldtab;
+ delete oldstatus;
+}
+
+Pix <T>VOHSet::first()
+{
+ for (int pos = 0; pos < size; ++pos)
+ if (status[pos] == VALIDCELL) return Pix(&tab[pos]);
+ return 0;
+}
+
+void <T>VOHSet::next(Pix& i)
+{
+ if (i == 0) return;
+ int pos = ((unsigned)i - (unsigned)tab) / sizeof(<T>) + 1;
+ for (; pos < size; ++pos)
+ if (status[pos] == VALIDCELL)
+ {
+ i = Pix(&tab[pos]);
+ return;
+ }
+ i = 0;
+}
+
+
+int <T>VOHSet:: operator == (<T>VOHSet& b)
+{
+ if (count != b.count)
+ return 0;
+ else
+ {
+ for (int i = 0; i < size; ++i)
+ if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
+ return 0;
+ for (int i = 0; i < b.size; ++i)
+ if (b.status[i] == VALIDCELL && seek(b.tab[i]) == 0)
+ return 0;
+ return 1;
+ }
+}
+
+int <T>VOHSet:: operator != (<T>VOHSet& b)
+{
+ return !(*this == b);
+}
+
+int <T>VOHSet::operator <= (<T>VOHSet& b)
+{
+ if (count > b.count)
+ return 0;
+ else
+ {
+ for (int i = 0; i < size; ++i)
+ if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
+ return 0;
+ return 1;
+ }
+}
+
+void <T>VOHSet::operator |= (<T>VOHSet& b)
+{
+ if (&b == this || b.count == 0)
+ return;
+ for (int i = 0; i < b.size; ++i)
+ if (b.status[i] == VALIDCELL) add(b.tab[i]);
+}
+
+void <T>VOHSet::operator &= (<T>VOHSet& b)
+{
+ if (&b == this || count == 0)
+ return;
+ for (int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL && b.seek(tab[i]) == 0)
+ {
+ status[i] = DELETEDCELL;
+ --count;
+ }
+ }
+}
+
+void <T>VOHSet::operator -= (<T>VOHSet& b)
+{
+ for (int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL && b.seek(tab[i]) != 0)
+ {
+ status[i] = DELETEDCELL;
+ --count;
+ }
+ }
+}
+
+int <T>VOHSet::OK()
+{
+ int v = tab != 0;
+ v &= status != 0;
+ int n = 0;
+ for (int i = 0; i < size; ++i)
+ {
+ if (status[i] == VALIDCELL) ++n;
+ else if (status[i] != DELETEDCELL && status[i] != EMPTYCELL)
+ v = 0;
+ }
+ v &= n == count;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/VOHSet.hP b/gnu/lib/libg++/include/gen/VOHSet.hP
new file mode 100644
index 00000000000..a3ff2c81482
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VOHSet.hP
@@ -0,0 +1,88 @@
+// 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)
+ based on code by Doug Schmidt
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>VOHSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>VOHSet_h 1
+
+#include "<T>.Set.h"
+
+
+
+class <T>VOHSet : public <T>Set
+{
+ <T>* tab;
+ char* status;
+ int size;
+ int cnt; // keeps track of VALIDCELLs and DELETEDCELLs
+
+public:
+ <T>VOHSet(int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>VOHSet(<T>VOHSet&);
+ inline ~<T>VOHSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ Pix seek(<T&> item);
+
+ void operator |= (<T>VOHSet& b);
+ void operator -= (<T>VOHSet& b);
+ void operator &= (<T>VOHSet& b);
+
+ int operator == (<T>VOHSet& b);
+ int operator != (<T>VOHSet& b);
+ int operator <= (<T>VOHSet& b);
+
+ int capacity();
+ void resize(int newsize = 0);
+
+ int OK();
+};
+
+
+inline <T>VOHSet::~<T>VOHSet()
+{
+ delete [] tab;
+ delete status;
+}
+
+
+inline int <T>VOHSet::contains(<T&> key)
+{
+ return seek(key) != 0;
+}
+
+
+inline <T>& <T>VOHSet::operator () (Pix p)
+{
+ if (p == 0) error("null Pix");
+ return *((<T>*)p);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/VQueue.ccP b/gnu/lib/libg++/include/gen/VQueue.ccP
new file mode 100644
index 00000000000..8eca22d1714
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VQueue.ccP
@@ -0,0 +1,83 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.VQueue.h"
+
+<T>VQueue::<T>VQueue(<T>VQueue& b)
+:size(b.size), cnt(b.cnt), inp(b.inp), outp(b.outp), s(new <T> [b.size])
+{
+ int j = outp;
+ for (int i = 0; i < cnt; ++i)
+ {
+ s[j] = b.s[j];
+ if (++j == size) j = 0;
+ }
+}
+
+void <T>VQueue::operator = (<T>VQueue& b)
+{
+ if (&b == this) return;
+ if (size != b.size)
+ {
+ delete [] s;
+ s = new <T> [b.size];
+ size = b.size;
+ }
+ inp = b.inp; outp = b.outp; cnt = b.cnt;
+ int j = outp;
+ for (int i = 0; i < cnt; ++i)
+ {
+ s[j] = b.s[j];
+ if (++j == size) j = 0;
+ }
+}
+
+
+void <T>VQueue::resize(int newsz)
+{
+ if (newsz < cnt)
+ error("resize: new size too small");
+ <T>* news = new <T> [newsz];
+ int j = outp;
+ for (int i = 0; i < cnt; ++i)
+ {
+ news[i] = s[j];
+ if (++j == size) j = 0;
+ }
+ inp = cnt;
+ outp = 0;
+ delete [] s;
+ s = news;
+ size = newsz;
+}
+
+int <T>VQueue::OK()
+{
+ int v = s != 0; // have space
+ v &= size >= 0; // a legal size
+ v &= inp >= 0 && inp <= size; // pointers with bounds
+ v &= outp >= 0 && outp <= size;
+ int c = (size + inp - outp) % size;
+ v &= cnt == size || cnt == c; // correct count
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/VQueue.hP b/gnu/lib/libg++/include/gen/VQueue.hP
new file mode 100644
index 00000000000..287a78187a1
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VQueue.hP
@@ -0,0 +1,130 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>VQueue_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>VQueue_h 1
+
+#include "<T>.Queue.h"
+
+class <T>VQueue : public <T>Queue
+{
+protected:
+ int size;
+ int cnt;
+ int inp;
+ int outp;
+ <T>* s;
+
+public:
+
+ <T>VQueue(int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>VQueue(<T>VQueue&);
+ inline ~<T>VQueue();
+
+ void operator = (<T>VQueue&);
+
+ inline void enq(<T&> item);
+ inline <T> deq();
+ inline <T>& front();
+ inline void del_front();
+
+ inline int length();
+ inline int empty();
+ inline int full();
+
+ int capacity();
+ void resize(int sz);
+ inline void clear();
+
+ int OK();
+};
+
+
+inline <T>VQueue::<T>VQueue(int sz)
+{
+ s = new <T> [size = sz];
+ cnt = inp = outp = 0;
+}
+
+inline <T>VQueue::~<T>VQueue()
+{
+ delete [] s;
+}
+
+inline void <T>VQueue::clear()
+{
+ inp = outp = 0;
+ cnt = 0;
+}
+
+inline int <T>VQueue::empty()
+{
+ return cnt <= 0;
+}
+
+inline int <T>VQueue::capacity()
+{
+ return size;
+}
+
+inline int <T>VQueue::full()
+{
+ return cnt >= size;
+}
+
+inline int <T>VQueue::length()
+{
+ return cnt;
+}
+
+inline void <T>VQueue::enq(<T&> item)
+{
+ if (cnt >= size) error("enq to full Queue.");
+ ++cnt;
+ s[inp] = item;
+ if (++inp == size) inp = 0;
+}
+
+inline <T> <T>VQueue::deq()
+{
+ if (cnt <= 0) error("deq from empty Queue.");
+ --cnt;
+ int i = outp;
+ if (++outp == size) outp = 0;
+ return s[i];
+}
+
+
+inline void <T>VQueue::del_front()
+{
+ if (cnt <= 0) error("delete from empty Queue.");
+ --cnt;
+ if (++outp == size) outp = 0;
+}
+
+inline <T>& <T>VQueue::front()
+{
+ if (empty()) error("top from empty Queue.");
+ return s[outp];
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/VStack.ccP b/gnu/lib/libg++/include/gen/VStack.ccP
new file mode 100644
index 00000000000..a5e8292fabf
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VStack.ccP
@@ -0,0 +1,66 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include "<T>.VStack.h"
+
+// error handling
+
+
+<T>VStack::<T>VStack(<T>VStack& b)
+:size(b.size), ptr(b.ptr), s(new <T> [b.size])
+{
+ for (int i = 0; i < ptr; ++i) s[i] = b.s[i];
+}
+
+void <T>VStack::operator = (<T>VStack& b)
+{
+ if (&b == this) return;
+ if (size < b.ptr)
+ {
+ delete [] s;
+ s = new <T> [b.size];
+ size = b.size;
+ }
+ ptr = b.ptr;
+ for (int i = 0; i < ptr; ++i) s[i] = b.s[i];
+}
+
+
+void <T>VStack::resize(int newsz)
+{
+ if (newsz < ptr) error("resize: new size too small");
+ <T>* news = new <T> [newsz];
+ for (int i = 0; i < ptr; ++i) news[i] = s[i];
+ delete [] s;
+ s = news;
+ size = newsz;
+}
+
+int <T>VStack::OK()
+{
+ int v = s != 0; // have space
+ v &= size >= 0; // a legal size
+ v &= ptr <= size; // ptr within bounds
+ v &= ptr >= 0;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/VStack.hP b/gnu/lib/libg++/include/gen/VStack.hP
new file mode 100644
index 00000000000..c7f7631a4cc
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/VStack.hP
@@ -0,0 +1,120 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>VStack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>VStack_h 1
+
+#include "<T>.Stack.h"
+
+class <T>VStack : public <T>Stack
+{
+protected:
+ int size;
+ int ptr;
+ <T>* s;
+
+public:
+
+ <T>VStack(int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>VStack(<T>VStack&);
+ inline ~<T>VStack();
+
+ void operator = (<T>VStack&);
+ inline void push(<T&> item);
+ inline <T> pop();
+ inline <T>& top();
+ inline void del_top();
+
+ inline int length();
+ inline int empty();
+ inline int full();
+ inline void clear();
+
+ void resize(int sz);
+ int capacity();
+
+ int OK();
+};
+
+
+inline <T>VStack::<T>VStack(int sz)
+{
+ s = new <T> [size = sz];
+ ptr = 0;
+}
+
+inline <T>VStack::~<T>VStack()
+{
+ delete [] s;
+}
+
+inline void <T>VStack::clear()
+{
+ ptr = 0;
+}
+
+inline int <T>VStack::capacity()
+{
+ return size;
+}
+
+inline int <T>VStack::empty()
+{
+ return ptr == 0;
+}
+
+inline int <T>VStack::full()
+{
+ return ptr == size;
+}
+
+inline int <T>VStack::length()
+{
+ return ptr;
+}
+
+inline void <T>VStack::push(<T&> item)
+{
+ if (full()) error("push to full stack.");
+ s[ptr++] = item;
+}
+
+inline <T> <T>VStack::pop()
+{
+ if (empty()) error("pop from empty stack.");
+ return s[--ptr];
+}
+
+
+inline void <T>VStack::del_top()
+{
+ if (empty()) error("del_top from empty stack.");
+ --ptr;
+}
+
+inline <T>& <T>VStack::top()
+{
+ if (empty()) error("top from empty stack.");
+ return s[ptr-1];
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/Vec.ccP b/gnu/lib/libg++/include/gen/Vec.ccP
new file mode 100644
index 00000000000..ac3825b0b8d
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Vec.ccP
@@ -0,0 +1,470 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <builtin.h>
+#include "<T>.Vec.h"
+
+// error handling
+
+
+void default_<T>Vec_error_handler(const char* msg)
+{
+ cerr << "Fatal <T>Vec error. " << msg << "\n";
+ exit(1);
+}
+
+one_arg_error_handler_t <T>Vec_error_handler = default_<T>Vec_error_handler;
+
+one_arg_error_handler_t set_<T>Vec_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = <T>Vec_error_handler;
+ <T>Vec_error_handler = f;
+ return old;
+}
+
+void <T>Vec::error(const char* msg)
+{
+ (*<T>Vec_error_handler)(msg);
+}
+
+void <T>Vec::range_error()
+{
+ (*<T>Vec_error_handler)("Index out of range.");
+}
+
+<T>Vec::<T>Vec(const <T>Vec& v)
+{
+ s = new <T> [len = v.len];
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ const <T>* u = v.s;
+ while (t < top) *t++ = *u++;
+}
+
+<T>Vec::<T>Vec(int l, <T&> fill_value)
+{
+ s = new <T> [len = l];
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) *t++ = fill_value;
+}
+
+
+<T>Vec& <T>Vec::operator = (const <T>Vec& v)
+{
+ if (this != &v)
+ {
+ delete [] s;
+ s = new <T> [len = v.len];
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ const <T>* u = v.s;
+ while (t < top) *t++ = *u++;
+ }
+ return *this;
+}
+
+void <T>Vec::apply(<T>Procedure f)
+{
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) (*f)(*t++);
+}
+
+// can't just realloc since there may be need for constructors/destructors
+void <T>Vec::resize(int newl)
+{
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ int minl = (len < newl)? len : newl;
+ <T>* top = &(s[minl]);
+ <T>* t = s;
+ while (t < top) *p++ = *t++;
+ delete [] s;
+ s = news;
+ len = newl;
+}
+
+<T>Vec concat(<T>Vec & a, <T>Vec & b)
+{
+ int newl = a.len + b.len;
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ <T>* top = &(a.s[a.len]);
+ <T>* t = a.s;
+ while (t < top) *p++ = *t++;
+ top = &(b.s[b.len]);
+ t = b.s;
+ while (t < top) *p++ = *t++;
+ return <T>Vec(newl, news);
+}
+
+
+<T>Vec combine(<T>Combiner f, <T>Vec& a, <T>Vec& b)
+{
+ int newl = (a.len < b.len)? a.len : b.len;
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ <T>* top = &(a.s[newl]);
+ <T>* t = a.s;
+ <T>* u = b.s;
+ while (t < top) *p++ = (*f)(*t++, *u++);
+ return <T>Vec(newl, news);
+}
+
+<T> <T>Vec::reduce(<T>Combiner f, <T&> base)
+{
+ <T> r = base;
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ while (t < top) r = (*f)(r, *t++);
+ return r;
+}
+
+<T>Vec reverse(<T>Vec& a)
+{
+ <T>* news = new <T> [a.len];
+ if (a.len != 0)
+ {
+ <T>* lo = news;
+ <T>* hi = &(news[a.len - 1]);
+ while (lo < hi)
+ {
+ <T> tmp = *lo;
+ *lo++ = *hi;
+ *hi-- = tmp;
+ }
+ }
+ return <T>Vec(a.len, news);
+}
+
+void <T>Vec::reverse()
+{
+ if (len != 0)
+ {
+ <T>* lo = s;
+ <T>* hi = &(s[len - 1]);
+ while (lo < hi)
+ {
+ <T> tmp = *lo;
+ *lo++ = *hi;
+ *hi-- = tmp;
+ }
+ }
+}
+
+int <T>Vec::index(<T&> targ)
+{
+ for (int i = 0; i < len; ++i) if (<T>EQ(targ, s[i])) return i;
+ return -1;
+}
+
+<T>Vec map(<T>Mapper f, <T>Vec& a)
+{
+ <T>* news = new <T> [a.len];
+ <T>* p = news;
+ <T>* top = &(a.s[a.len]);
+ <T>* t = a.s;
+ while(t < top) *p++ = (*f)(*t++);
+ return <T>Vec(a.len, news);
+}
+
+int operator == (<T>Vec& a, <T>Vec& b)
+{
+ if (a.len != b.len)
+ return 0;
+ <T>* top = &(a.s[a.len]);
+ <T>* t = a.s;
+ <T>* u = b.s;
+ while (t < top) if (!(<T>EQ(*t++, *u++))) return 0;
+ return 1;
+}
+
+void <T>Vec::fill(<T&> val, int from, int n)
+{
+ int to;
+ if (n < 0)
+ to = len - 1;
+ else
+ to = from + n - 1;
+ if ((unsigned)from > (unsigned)to)
+ range_error();
+ <T>* t = &(s[from]);
+ <T>* top = &(s[to]);
+ while (t <= top) *t++ = val;
+}
+
+<T>Vec <T>Vec::at(int from, int n)
+{
+ int to;
+ if (n < 0)
+ {
+ n = len - from;
+ to = len - 1;
+ }
+ else
+ to = from + n - 1;
+ if ((unsigned)from > (unsigned)to)
+ range_error();
+ <T>* news = new <T> [n];
+ <T>* p = news;
+ <T>* t = &(s[from]);
+ <T>* top = &(s[to]);
+ while (t <= top) *p++ = *t++;
+ return <T>Vec(n, news);
+}
+
+<T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f)
+{
+ int newl = a.len + b.len;
+ <T>* news = new <T> [newl];
+ <T>* p = news;
+ <T>* topa = &(a.s[a.len]);
+ <T>* as = a.s;
+ <T>* topb = &(b.s[b.len]);
+ <T>* bs = b.s;
+
+ for (;;)
+ {
+ if (as >= topa)
+ {
+ while (bs < topb) *p++ = *bs++;
+ break;
+ }
+ else if (bs >= topb)
+ {
+ while (as < topa) *p++ = *as++;
+ break;
+ }
+ else if ((*f)(*as, *bs) <= 0)
+ *p++ = *as++;
+ else
+ *p++ = *bs++;
+ }
+ return <T>Vec(newl, news);
+}
+
+static int gsort(<T>*, int, <T>Comparator);
+
+void <T>Vec::sort (<T>Comparator compar)
+{
+ gsort(s, len, compar);
+}
+
+
+// An adaptation of Schmidt's new quicksort
+
+static inline void SWAP(<T>* A, <T>* B)
+{
+ <T> tmp = *A; *A = *B; *B = tmp;
+}
+
+/* This should be replaced by a standard ANSI macro. */
+#define BYTES_PER_WORD 8
+#define BYTES_PER_LONG 4
+
+/* The next 4 #defines implement a very fast in-line stack abstraction. */
+
+#define STACK_SIZE (BYTES_PER_WORD * BYTES_PER_LONG)
+#define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0)
+#define POP(LOW,HIGH) do {LOW = (--top)->lo;HIGH = top->hi;} while (0)
+#define STACK_NOT_EMPTY (stack < top)
+
+/* Discontinue quicksort algorithm when partition gets below this size.
+ This particular magic number was chosen to work best on a Sun 4/260. */
+#define MAX_THRESH 4
+
+
+/* Order size using quicksort. This implementation incorporates
+ four optimizations discussed in Sedgewick:
+
+ 1. Non-recursive, using an explicit stack of pointer that
+ store the next array partition to sort. To save time, this
+ maximum amount of space required to store an array of
+ MAX_INT is allocated on the stack. Assuming a 32-bit integer,
+ this needs only 32 * sizeof (stack_node) == 136 bits. Pretty
+ cheap, actually.
+
+ 2. Chose the pivot element using a median-of-three decision tree.
+ This reduces the probability of selecting a bad pivot value and
+ eliminates certain extraneous comparisons.
+
+ 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
+ insertion sort to order the MAX_THRESH items within each partition.
+ This is a big win, since insertion sort is faster for small, mostly
+ sorted array segements.
+
+ 4. The larger of the two sub-partitions is always pushed onto the
+ stack first, with the algorithm then concentrating on the
+ smaller partition. This *guarantees* no more than log (n)
+ stack size is needed! */
+
+static int gsort (<T> *base_ptr, int total_elems, <T>Comparator cmp)
+{
+/* Stack node declarations used to store unfulfilled partition obligations. */
+ struct stack_node { <T> *lo; <T> *hi; };
+ <T> pivot_buffer;
+ int max_thresh = MAX_THRESH;
+
+ if (total_elems > MAX_THRESH)
+ {
+ <T> *lo = base_ptr;
+ <T> *hi = lo + (total_elems - 1);
+ <T> *left_ptr;
+ <T> *right_ptr;
+ stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */
+ stack_node *top = stack + 1;
+
+ while (STACK_NOT_EMPTY)
+ {
+ {
+ <T> *pivot = &pivot_buffer;
+ {
+ /* Select median value from among LO, MID, and HI. Rearrange
+ LO and HI so the three values are sorted. This lowers the
+ probability of picking a pathological pivot value and
+ skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
+
+ <T> *mid = lo + ((hi - lo) >> 1);
+
+ if ((*cmp) (*mid, *lo) < 0)
+ SWAP (mid, lo);
+ if ((*cmp) (*hi, *mid) < 0)
+ {
+ SWAP (mid, hi);
+ if ((*cmp) (*mid, *lo) < 0)
+ SWAP (mid, lo);
+ }
+ *pivot = *mid;
+ pivot = &pivot_buffer;
+ }
+ left_ptr = lo + 1;
+ right_ptr = hi - 1;
+
+ /* Here's the famous ``collapse the walls'' section of quicksort.
+ Gotta like those tight inner loops! They are the main reason
+ that this algorithm runs much faster than others. */
+ do
+ {
+ while ((*cmp) (*left_ptr, *pivot) < 0)
+ left_ptr += 1;
+
+ while ((*cmp) (*pivot, *right_ptr) < 0)
+ right_ptr -= 1;
+
+ if (left_ptr < right_ptr)
+ {
+ SWAP (left_ptr, right_ptr);
+ left_ptr += 1;
+ right_ptr -= 1;
+ }
+ else if (left_ptr == right_ptr)
+ {
+ left_ptr += 1;
+ right_ptr -= 1;
+ break;
+ }
+ }
+ while (left_ptr <= right_ptr);
+
+ }
+
+ /* Set up pointers for next iteration. First determine whether
+ left and right partitions are below the threshold size. If so,
+ ignore one or both. Otherwise, push the larger partition's
+ bounds on the stack and continue sorting the smaller one. */
+
+ if ((right_ptr - lo) <= max_thresh)
+ {
+ if ((hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */
+ POP (lo, hi);
+ else /* Ignore small left partition. */
+ lo = left_ptr;
+ }
+ else if ((hi - left_ptr) <= max_thresh) /* Ignore small right partition. */
+ hi = right_ptr;
+ else if ((right_ptr - lo) > (hi - left_ptr)) /* Push larger left partition indices. */
+ {
+ PUSH (lo, right_ptr);
+ lo = left_ptr;
+ }
+ else /* Push larger right partition indices. */
+ {
+ PUSH (left_ptr, hi);
+ hi = right_ptr;
+ }
+ }
+ }
+
+ /* Once the BASE_PTR array is partially sorted by quicksort the rest
+ is completely sorted using insertion sort, since this is efficient
+ for partitions below MAX_THRESH size. BASE_PTR points to the beginning
+ of the array to sort, and END_PTR points at the very last element in
+ the array (*not* one beyond it!). */
+
+
+ {
+ <T> *end_ptr = base_ptr + 1 * (total_elems - 1);
+ <T> *run_ptr;
+ <T> *tmp_ptr = base_ptr;
+ <T> *thresh = (end_ptr < (base_ptr + max_thresh))?
+ end_ptr : (base_ptr + max_thresh);
+
+ /* Find smallest element in first threshold and place it at the
+ array's beginning. This is the smallest array element,
+ and the operation speeds up insertion sort's inner loop. */
+
+ for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr += 1)
+ if ((*cmp) (*run_ptr, *tmp_ptr) < 0)
+ tmp_ptr = run_ptr;
+
+ if (tmp_ptr != base_ptr)
+ SWAP (tmp_ptr, base_ptr);
+
+ /* Insertion sort, running from left-hand-side up to `right-hand-side.'
+ Pretty much straight out of the original GNU qsort routine. */
+
+ for (run_ptr = base_ptr + 1; (tmp_ptr = run_ptr += 1) <= end_ptr; )
+ {
+
+ while ((*cmp) (*run_ptr, *(tmp_ptr -= 1)) < 0)
+ ;
+
+ if ((tmp_ptr += 1) != run_ptr)
+ {
+ <T> *trav;
+
+ for (trav = run_ptr + 1; --trav >= run_ptr;)
+ {
+ <T> c = *trav;
+ <T> *hi, *lo;
+
+ for (hi = lo = trav; (lo -= 1) >= tmp_ptr; hi = lo)
+ *hi = *lo;
+ *hi = c;
+ }
+ }
+
+ }
+ }
+ return 1;
+}
diff --git a/gnu/lib/libg++/include/gen/Vec.hP b/gnu/lib/libg++/include/gen/Vec.hP
new file mode 100644
index 00000000000..91993d1c4f1
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/Vec.hP
@@ -0,0 +1,135 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>Vec_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>Vec_h 1
+
+#include <builtin.h>
+#include "<T>.defs.h"
+
+#ifndef _<T>_typedefs
+#define _<T>_typedefs 1
+typedef void (*<T>Procedure)(<T&>);
+typedef <T> (*<T>Mapper)(<T&>);
+typedef <T> (*<T>Combiner)(<T&>, <T&>);
+typedef int (*<T>Predicate)(<T&>);
+typedef int (*<T>Comparator)(<T&>, <T&>);
+#endif
+
+
+class <T>Vec
+{
+protected:
+ int len;
+ <T> *s;
+
+ <T>Vec(int l, <T>* d);
+public:
+ <T>Vec ();
+ <T>Vec (int l);
+ <T>Vec (int l, <T&> fill_value);
+ <T>Vec (const <T>Vec&);
+ ~<T>Vec ();
+
+ <T>Vec & operator = (const <T>Vec & a);
+ <T>Vec at(int from = 0, int n = -1);
+
+ int capacity() const;
+ void resize(int newlen);
+
+ <T>& operator [] (int n);
+ <T>& elem(int n);
+
+ friend <T>Vec concat(<T>Vec & a, <T>Vec & b);
+ friend <T>Vec map(<T>Mapper f, <T>Vec & a);
+ friend <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f);
+ friend <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b);
+ friend <T>Vec reverse(<T>Vec & a);
+
+ void reverse();
+ void sort(<T>Comparator f);
+ void fill(<T&> val, int from = 0, int n = -1);
+
+ void apply(<T>Procedure f);
+ <T> reduce(<T>Combiner f, <T&> base);
+ int index(<T&> targ);
+
+ friend int operator == (<T>Vec& a, <T>Vec& b);
+ friend int operator != (<T>Vec& a, <T>Vec& b);
+
+ void error(const char* msg);
+ void range_error();
+};
+
+extern void default_<T>Vec_error_handler(const char*);
+extern one_arg_error_handler_t <T>Vec_error_handler;
+
+extern one_arg_error_handler_t
+ set_<T>Vec_error_handler(one_arg_error_handler_t f);
+
+
+inline <T>Vec::<T>Vec()
+{
+ len = 0; s = 0;
+}
+
+inline <T>Vec::<T>Vec(int l)
+{
+ s = new <T> [len = l];
+}
+
+
+inline <T>Vec::<T>Vec(int l, <T>* d) :len(l), s(d) {}
+
+
+inline <T>Vec::~<T>Vec()
+{
+ delete [] s;
+}
+
+
+inline <T>& <T>Vec::operator [] (int n)
+{
+ if ((unsigned)n >= (unsigned)len)
+ range_error();
+ return s[n];
+}
+
+inline <T>& <T>Vec::elem(int n)
+{
+ return s[n];
+}
+
+
+inline int <T>Vec::capacity() const
+{
+ return len;
+}
+
+
+
+inline int operator != (<T>Vec& a, <T>Vec& b)
+{
+ return !(a == b);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPBag.ccP b/gnu/lib/libg++/include/gen/XPBag.ccP
new file mode 100644
index 00000000000..e2a7834077b
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPBag.ccP
@@ -0,0 +1,72 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPBag.h"
+
+int <T>XPBag::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ if (!v) error("invariant failure");
+ return v;
+}
+
+Pix <T>XPBag::seek(<T&> item, Pix i)
+{
+ if (i == 0) i = p.first(); else next(i);
+ for (; i != 0; p.next(i)) if (<T>EQ(p(i), item)) return i;
+ return 0;
+}
+
+int <T>XPBag::nof(<T&> item)
+{
+ int n = 0;
+ for (int i = p.low(); i < p.fence(); p.next(i)) if (<T>EQ(p[i], item)) ++n;
+ return n;
+}
+
+void <T>XPBag::del(<T&> item)
+{
+ for (int i = p.low(); i < p.fence(); p.next(i))
+ {
+ if (<T>EQ(p[i], item))
+ {
+ --count;
+ p[i] = p.low_element();
+ p.del_low();
+ return;
+ }
+ }
+}
+
+void <T>XPBag::remove(<T&> item)
+{
+ for (int i = p.low(); i < p.fence(); p.next(i))
+ {
+ if (<T>EQ(p[i], item))
+ {
+ --count;
+ p[i] = p.low_element();
+ p.del_low();
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/include/gen/XPBag.hP b/gnu/lib/libg++/include/gen/XPBag.hP
new file mode 100644
index 00000000000..da8c199e212
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPBag.hP
@@ -0,0 +1,98 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>XPBag_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPBag_h 1
+
+#include "<T>.Bag.h"
+#include "<T>.XPlex.h"
+
+class <T>XPBag : public <T>Bag
+{
+protected:
+ <T>XPlex p;
+
+public:
+ <T>XPBag(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>XPBag(const <T>XPBag&);
+
+ inline Pix add(<T&> item);
+ void del(<T&> item);
+#undef remove
+ void remove(<T&>item);
+ int nof(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+
+inline <T>XPBag::<T>XPBag(int chunksize)
+ : p(chunksize) { count = 0; }
+
+inline <T>XPBag::<T>XPBag(const <T>XPBag& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>XPBag::first()
+{
+ return p.first();
+}
+
+inline void <T>XPBag::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>XPBag::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>XPBag::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>XPBag::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+inline Pix <T>XPBag::add(<T&> item)
+{
+ ++count;
+ return p.index_to_Pix(p.add_high(item));
+}
+
+inline int <T>XPBag::contains(<T&> item)
+{
+ return seek(item) != 0;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPDeque.ccP b/gnu/lib/libg++/include/gen/XPDeque.ccP
new file mode 100644
index 00000000000..6b363d9bdc4
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPDeque.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPDeque.h"
diff --git a/gnu/lib/libg++/include/gen/XPDeque.hP b/gnu/lib/libg++/include/gen/XPDeque.hP
new file mode 100644
index 00000000000..a73d8fdada8
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPDeque.hP
@@ -0,0 +1,133 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>XPDeque_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPDeque_h
+
+#include "<T>.XPlex.h"
+#include "<T>.Deque.h"
+
+class <T>XPDeque : public <T>Deque
+{
+ <T>XPlex p;
+
+public:
+ <T>XPDeque(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>XPDeque(const <T>XPDeque& d);
+ inline ~<T>XPDeque();
+
+ void operator = (const <T>XPDeque&);
+
+ inline void push(<T&> item); // insert at front
+ inline void enq(<T&> item); // insert at rear
+
+ inline <T>& front();
+ inline <T>& rear();
+
+ inline <T> deq();
+ inline void del_front();
+ inline void del_rear();
+
+ inline void clear();
+ inline int empty();
+ inline int full();
+ inline int length();
+
+ inline int OK();
+};
+
+inline <T>XPDeque::<T>XPDeque(int chunksize)
+ : p(chunksize) {}
+inline <T>XPDeque::<T>XPDeque(const <T>XPDeque& d) : p(d.p) {}
+
+inline <T>XPDeque::~<T>XPDeque() {}
+
+inline void <T>XPDeque::push(<T&>item)
+{
+ p.add_low(item);
+}
+
+inline void <T>XPDeque::enq(<T&>item)
+{
+ p.add_high(item);
+}
+
+inline <T> <T>XPDeque::deq()
+{
+ <T> res = p.low_element();
+ p.del_low();
+ return res;
+}
+
+inline <T>& <T>XPDeque::front()
+{
+ return p.low_element();
+}
+
+inline <T>& <T>XPDeque::rear()
+{
+ return p.high_element();
+}
+
+inline void <T>XPDeque::del_front()
+{
+ p.del_low();
+}
+
+inline void <T>XPDeque::del_rear()
+{
+ p.del_high();
+}
+
+inline void <T>XPDeque::operator =(const <T>XPDeque& s)
+{
+ p.operator = (s.p);
+}
+
+
+inline int <T>XPDeque::empty()
+{
+ return p.empty();
+}
+
+inline int <T>XPDeque::full()
+{
+ return p.full();
+}
+
+inline int <T>XPDeque::length()
+{
+ return p.length();
+}
+
+inline int <T>XPDeque::OK()
+{
+ return p.OK();
+}
+
+inline void <T>XPDeque::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPPQ.ccP b/gnu/lib/libg++/include/gen/XPPQ.ccP
new file mode 100644
index 00000000000..4d7a8644b12
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPPQ.ccP
@@ -0,0 +1,143 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPPQ.h"
+
+int <T>XPPQ::OK()
+{
+ int v = p.OK();
+ v &= p.low() == 1;
+ v &= count == p.length();
+ if (!v) error("invariant failure");
+ return v;
+}
+
+Pix <T>XPPQ::seek(<T&> item)
+{
+ for (int i = p.low(); i < p.fence(); p.next(i))
+ if (<T>EQ(p[i],item)) return p.index_to_Pix(i);
+ return 0;
+}
+
+// standard 2-ary heap ops
+// pointers are used a lot to avoid thrashing across chunks with plexes
+
+Pix <T>XPPQ::enq(<T&> item)
+{
+ p.add_high(item);
+ <T>* pk = &(p.high_element());
+ int par = ++count >> 1;
+ while (par != 0)
+ {
+ <T>* ppar = &(p[par]);
+ if (!(<T>LE(*ppar, item)))
+ {
+ *pk = *ppar;
+ pk = ppar;
+ par >>= 1;
+ }
+ else
+ break;
+ }
+ *pk = item;
+ return Pix(pk);
+}
+
+void <T>XPPQ::del_front()
+{
+ if (count == 0) error("empty PQ");
+ --count;
+ <T>* pk = &(p.low_element());
+ <T>* ph = &(p.high_element());
+ int child = 2;
+ while (child <= count)
+ {
+ <T>* pchild = &(p[child]);
+ if (child < count)
+ {
+ <T>* prchild = &(p[child+1]);
+ if (!(<T>LE(*pchild, *prchild)))
+ {
+ pchild = prchild;
+ ++child;
+ }
+ }
+ if (!(<T>LE(*ph, *pchild)))
+ {
+ *pk = *pchild;
+ pk = pchild;
+ child <<= 1;
+ }
+ else
+ break;
+ }
+ *pk = *ph;
+ p.del_high();
+}
+
+
+void <T>XPPQ::del(Pix i)
+{
+ if (i == 0) error("null Pix");
+ --count;
+ int k = p.Pix_to_index(i);
+ <T>* pk = &(p[k]);
+ <T>* ph = &(p.high_element());
+ int child = k << 1;
+ while (child <= count)
+ {
+ <T>* pchild = &(p[child]);
+ if (child < count)
+ {
+ <T>* prchild = &(p[child+1]);
+ if (!(<T>LE(*pchild, *prchild)))
+ {
+ pchild = prchild;
+ ++child;
+ }
+ }
+ if (!(<T>LE(*ph, *pchild)))
+ {
+ *pk = *pchild;
+ pk = pchild;
+ child <<= 1;
+ }
+ else
+ break;
+ }
+ int par = child >> 2;
+ while (par != 0)
+ {
+ <T>* ppar = &(p[par]);
+ if (!(<T>LE(*ppar, *ph)))
+ {
+ *pk = *ppar;
+ pk = ppar;
+ par >>= 1;
+ }
+ else
+ break;
+ }
+ *pk = *ph;
+ p.del_high();
+}
+
+
diff --git a/gnu/lib/libg++/include/gen/XPPQ.hP b/gnu/lib/libg++/include/gen/XPPQ.hP
new file mode 100644
index 00000000000..472670009d7
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPPQ.hP
@@ -0,0 +1,105 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>XPPQ_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPPQ_h 1
+
+#include "<T>.PQ.h"
+#include "<T>.XPlex.h"
+
+class <T>XPPQ : public <T>PQ
+{
+protected:
+ <T>XPlex p;
+
+public:
+ <T>XPPQ(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>XPPQ(const <T>XPPQ&);
+
+ Pix enq(<T&> item);
+ inline <T> deq();
+
+ inline <T>& front();
+ void del_front();
+
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ void del(Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item);
+
+ int OK(); // rep invariant
+};
+
+inline <T>XPPQ::<T>XPPQ(int chunksize)
+ : p(1, chunksize) { count = 0; }
+
+inline <T>XPPQ::<T>XPPQ(const <T>XPPQ& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>XPPQ::first()
+{
+ return p.first();
+}
+
+inline void <T>XPPQ::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>XPPQ::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline <T>& <T>XPPQ::front ()
+{
+ return p.low_element();
+}
+
+inline <T> <T>XPPQ::deq ()
+{
+ <T> x = p.low_element();
+ del_front();
+ return x;
+}
+
+inline void <T>XPPQ::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>XPPQ::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+inline int <T>XPPQ::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPQueue.ccP b/gnu/lib/libg++/include/gen/XPQueue.ccP
new file mode 100644
index 00000000000..77bfd1c7a95
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPQueue.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPQueue.h"
diff --git a/gnu/lib/libg++/include/gen/XPQueue.hP b/gnu/lib/libg++/include/gen/XPQueue.hP
new file mode 100644
index 00000000000..a5baf7bd68e
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPQueue.hP
@@ -0,0 +1,114 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>XPQueue_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPQueue_h
+
+#include "<T>.XPlex.h"
+#include "<T>.Queue.h"
+
+class <T>XPQueue : public <T>Queue
+{
+protected:
+ <T>XPlex p;
+
+public:
+ <T>XPQueue(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>XPQueue(const <T>XPQueue& q);
+ inline ~<T>XPQueue();
+
+ void operator = (const <T>XPQueue&);
+
+ inline void enq(<T&> item);
+ inline <T> deq();
+ inline <T>& front();
+ inline void del_front();
+
+ inline void clear();
+ inline int empty();
+ inline int full();
+ inline int length();
+
+ inline int OK();
+};
+
+inline <T>XPQueue::<T>XPQueue(int chunksize)
+ : p(chunksize) {}
+inline <T>XPQueue::<T>XPQueue(const <T>XPQueue& q) : p(q.p) {}
+
+inline <T>XPQueue::~<T>XPQueue() {}
+
+inline void <T>XPQueue::enq(<T&>item)
+{
+ p.add_high(item);
+}
+
+inline <T> <T>XPQueue::deq()
+{
+ <T> res = p.low_element();
+ p.del_low();
+ return res;
+}
+
+inline <T>& <T>XPQueue::front()
+{
+ return p.low_element();
+}
+
+
+inline void <T>XPQueue::del_front()
+{
+ p.del_low();
+}
+
+inline void <T>XPQueue::operator =(const <T>XPQueue& s)
+{
+ p.operator = (s.p);
+}
+
+inline int <T>XPQueue::empty()
+{
+ return p.empty();
+}
+
+inline int <T>XPQueue::full()
+{
+ return p.full();
+}
+
+inline int <T>XPQueue::length()
+{
+ return p.length();
+}
+
+inline int <T>XPQueue::OK()
+{
+ return p.OK();
+}
+
+inline void <T>XPQueue::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPSet.ccP b/gnu/lib/libg++/include/gen/XPSet.ccP
new file mode 100644
index 00000000000..596fa8847ad
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPSet.ccP
@@ -0,0 +1,63 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPSet.h"
+
+int <T>XPSet::OK()
+{
+ int v = p.OK();
+ v &= count == p.length();
+ if (!v) error("invariant failure");
+ return v;
+}
+
+Pix <T>XPSet::seek(<T&> item)
+{
+ for (int i = p.low(); i < p.fence(); p.next(i))
+ if (<T>EQ(p[i],item)) return p.index_to_Pix(i);
+ return 0;
+}
+
+Pix <T>XPSet::add(<T&> item)
+{
+ Pix i = seek(item);
+ if (i == 0)
+ {
+ ++count;
+ i = p.index_to_Pix(p.add_high(item));
+ }
+ return i;
+}
+
+void <T>XPSet::del(<T&> item)
+{
+ for (int i = p.low(); i < p.fence(); p.next(i))
+ {
+ if (<T>EQ(p[i], item))
+ {
+ --count;
+ p[i] = p.low_element();
+ p.del_low();
+ return;
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/include/gen/XPSet.hP b/gnu/lib/libg++/include/gen/XPSet.hP
new file mode 100644
index 00000000000..a87d8eb0b55
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPSet.hP
@@ -0,0 +1,89 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>XPSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPSet_h 1
+
+#include "<T>.Set.h"
+#include "<T>.XPlex.h"
+
+class <T>XPSet : public <T>Set
+{
+protected:
+ <T>XPlex p;
+
+public:
+ <T>XPSet(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>XPSet(const <T>XPSet&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ inline int contains(<T&> item);
+
+ inline void clear();
+
+ inline Pix first();
+ inline void next(Pix& i);
+ inline <T>& operator () (Pix i);
+ inline int owns(Pix i);
+ Pix seek(<T&> item);
+
+ int OK();
+};
+
+
+inline <T>XPSet::<T>XPSet(int chunksize)
+ : p(chunksize) { count = 0; }
+
+inline <T>XPSet::<T>XPSet(const <T>XPSet& s) : p(s.p) { count = s.count; }
+
+inline Pix <T>XPSet::first()
+{
+ return p.first();
+}
+
+inline void <T>XPSet::next(Pix & idx)
+{
+ p.next(idx);
+}
+
+inline <T>& <T>XPSet::operator ()(Pix idx)
+{
+ return p(idx);
+}
+
+inline void <T>XPSet::clear()
+{
+ count = 0; p.clear();
+}
+
+inline int <T>XPSet::contains (<T&> item)
+{
+ return seek(item) != 0;
+}
+
+inline int <T>XPSet::owns (Pix idx)
+{
+ return p.owns(idx);
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPStack.ccP b/gnu/lib/libg++/include/gen/XPStack.ccP
new file mode 100644
index 00000000000..fe24f0f044a
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPStack.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPStack.h"
diff --git a/gnu/lib/libg++/include/gen/XPStack.hP b/gnu/lib/libg++/include/gen/XPStack.hP
new file mode 100644
index 00000000000..41f78adf5ce
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPStack.hP
@@ -0,0 +1,115 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>XPStack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPStack_h
+
+#include "<T>.XPlex.h"
+#include "<T>.Stack.h"
+
+class <T>XPStack : public <T>Stack
+{
+ <T>XPlex p;
+
+public:
+ <T>XPStack(int chunksize = DEFAULT_INITIAL_CAPACITY);
+ <T>XPStack(const <T>XPStack& s);
+ inline ~<T>XPStack();
+
+ void operator = (const <T>XPStack&);
+
+ inline void push(<T&> item);
+ inline <T> pop();
+ inline <T>& top();
+ inline void del_top();
+
+ inline int empty();
+ inline int full();
+ inline int length();
+
+ inline void clear();
+
+ inline int OK();
+
+};
+
+
+inline <T>XPStack::<T>XPStack(int chunksize)
+ : p(chunksize) {}
+inline <T>XPStack::<T>XPStack(const <T>XPStack& s) : p(s.p) {}
+
+inline <T>XPStack::~<T>XPStack() {}
+
+inline void <T>XPStack::push(<T&>item)
+{
+ p.add_high(item);
+}
+
+inline <T> <T>XPStack::pop()
+{
+ <T> res = p.high_element();
+ p.del_high();
+ return res;
+}
+
+inline <T>& <T>XPStack::top()
+{
+ return p.high_element();
+}
+
+inline void <T>XPStack::del_top()
+{
+ p.del_high();
+}
+
+inline void <T>XPStack::operator =(const <T>XPStack& s)
+{
+ p.operator = (s.p);
+}
+
+inline int <T>XPStack::empty()
+{
+ return p.empty();
+}
+
+inline int <T>XPStack::full()
+{
+ return p.full();
+}
+
+inline int <T>XPStack::length()
+{
+ return p.length();
+}
+
+inline int <T>XPStack::OK()
+{
+ return p.OK();
+}
+
+inline void <T>XPStack::clear()
+{
+ p.clear();
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/XPlex.ccP b/gnu/lib/libg++/include/gen/XPlex.ccP
new file mode 100644
index 00000000000..f5304222993
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPlex.ccP
@@ -0,0 +1,397 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPlex.h"
+
+
+<T>XPlex:: <T>XPlex()
+{
+ lo = fnc = 0;
+ csize = DEFAULT_INITIAL_CAPACITY;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, lo, lo, fnc, lo+csize));
+ hd = ch;
+}
+
+<T>XPlex:: <T>XPlex(int chunksize)
+{
+ if (chunksize == 0) error("invalid constructor specification");
+ lo = fnc = 0;
+ if (chunksize > 0)
+ {
+ csize = chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, lo, lo, fnc, csize));
+ hd = ch;
+ }
+ else
+ {
+ csize = -chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, chunksize, lo, fnc, fnc));
+ hd = ch;
+ }
+}
+
+
+<T>XPlex:: <T>XPlex(int l, int chunksize)
+{
+ if (chunksize == 0) error("invalid constructor specification");
+ lo = fnc = l;
+ if (chunksize > 0)
+ {
+ csize = chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, lo, lo, fnc, csize+lo));
+ hd = ch;
+ }
+ else
+ {
+ csize = -chunksize;
+ <T>* data = new <T>[csize];
+ set_cache(new <T>IChunk(data, chunksize+lo, lo, fnc, fnc));
+ hd = ch;
+ }
+}
+
+void <T>XPlex::make_initial_chunks(int up)
+{
+ int need = fnc - lo;
+ hd = 0;
+ if (up)
+ {
+ int l = lo;
+ do
+ {
+ int sz;
+ if (need >= csize)
+ sz = csize;
+ else
+ sz = need;
+ <T>* data = new <T> [csize];
+ <T>IChunk* h = new <T>IChunk(data, l, l, l+sz, l+csize);
+ if (hd != 0)
+ h->link_to_next(hd);
+ else
+ hd = h;
+ l += sz;
+ need -= sz;
+ } while (need > 0);
+ }
+ else
+ {
+ int hi = fnc;
+ do
+ {
+ int sz;
+ if (need >= csize)
+ sz = csize;
+ else
+ sz = need;
+ <T>* data = new <T> [csize];
+ <T>IChunk* h = new <T>IChunk(data, hi-csize, hi-sz, hi, hi);
+ if (hd != 0)
+ h->link_to_next(hd);
+ hd = h;
+ hi -= sz;
+ need -= sz;
+ } while (need > 0);
+ }
+ set_cache(hd);
+}
+
+<T>XPlex:: <T>XPlex(int l, int hi, const <T&> initval, int chunksize)
+{
+ lo = l;
+ fnc = hi + 1;
+ if (chunksize == 0)
+ {
+ csize = fnc - l;
+ make_initial_chunks(1);
+ }
+ else if (chunksize < 0)
+ {
+ csize = -chunksize;
+ make_initial_chunks(0);
+ }
+ else
+ {
+ csize = chunksize;
+ make_initial_chunks(1);
+ }
+ fill(initval);
+}
+
+<T>XPlex::<T>XPlex(const <T>XPlex& a)
+{
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = a.csize;
+ make_initial_chunks();
+ for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
+}
+
+void <T>XPlex::operator= (const <T>XPlex& a)
+{
+ if (&a != this)
+ {
+ invalidate();
+ lo = a.lo;
+ fnc = a.fnc;
+ csize = a.csize;
+ make_initial_chunks();
+ for (int i = a.low(); i < a.fence(); a.next(i)) (*this)[i] = a[i];
+ }
+}
+
+
+void <T>XPlex::cache(int idx) const
+{
+ const <T>IChunk* tail = tl();
+ const <T>IChunk* t = ch;
+ while (idx >= t->fence_index())
+ {
+ if (t == tail) index_error();
+ t = (t->next());
+ }
+ while (idx < t->low_index())
+ {
+ if (t == hd) index_error();
+ t = (t->prev());
+ }
+ set_cache(t);
+}
+
+
+void <T>XPlex::cache(const <T>* p) const
+{
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->next());
+ if (t == old) index_error();
+ }
+ set_cache(t);
+}
+
+int <T>XPlex::owns(Pix px) const
+{
+ <T>* p = (<T>*)px;
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->next());
+ if (t == old) { set_cache(t); return 0; }
+ }
+ set_cache(t);
+ return 1;
+}
+
+
+<T>* <T>XPlex::dosucc(const <T>* p) const
+{
+ if (p == 0) return 0;
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+
+ while (!t->actual_pointer(p))
+ {
+ t = (t->next());
+ if (t == old) return 0;
+ }
+ int i = t->index_of(p) + 1;
+ if (i >= fnc) return 0;
+ if (i >= t->fence_index()) t = (t->next());
+ set_cache(t);
+ return (t->pointer_to(i));
+}
+
+<T>* <T>XPlex::dopred(const <T>* p) const
+{
+ if (p == 0) return 0;
+ const <T>IChunk* old = ch;
+ const <T>IChunk* t = ch;
+ while (!t->actual_pointer(p))
+ {
+ t = (t->prev());
+ if (t == old) return 0;
+ }
+ int i = t->index_of(p) - 1;
+ if (i < lo) return 0;
+ if (i < t->low_index()) t = (t->prev());
+ set_cache(t);
+ return (t->pointer_to(i));
+}
+
+
+int <T>XPlex::add_high(const <T&> elem)
+{
+ <T>IChunk* t = tl();
+ if (!t->can_grow_high())
+ {
+ if (t-><T>IChunk::empty() && one_chunk())
+ t->clear(fnc);
+ else
+ {
+ <T>* data = new <T> [csize];
+ t = (new <T>IChunk(data, fnc, fnc, fnc,fnc+csize));
+ t->link_to_prev(tl());
+ }
+ }
+ *((t-><T>IChunk::grow_high())) = elem;
+ set_cache(t);
+ return fnc++;
+}
+
+int <T>XPlex::del_high ()
+{
+ if (empty()) empty_error();
+ <T>IChunk* t = tl();
+ t-><T>IChunk::shrink_high();
+ if (t-><T>IChunk::empty() && !one_chunk())
+ {
+ <T>IChunk* pred = t->prev();
+ del_chunk(t);
+ t = pred;
+ }
+ set_cache(t);
+ return --fnc - 1;
+}
+
+int <T>XPlex::add_low (const <T&> elem)
+{
+ <T>IChunk* t = hd;
+ if (!t->can_grow_low())
+ {
+ if (t-><T>IChunk::empty() && one_chunk())
+ t->cleardown(lo);
+ else
+ {
+ <T>* data = new <T> [csize];
+ hd = new <T>IChunk(data, lo-csize, lo, lo, lo);
+ hd->link_to_next(t);
+ t = hd;
+ }
+ }
+ *((t-><T>IChunk::grow_low())) = elem;
+ set_cache(t);
+ return --lo;
+}
+
+
+int <T>XPlex::del_low ()
+{
+ if (empty()) empty_error();
+ <T>IChunk* t = hd;
+ t-><T>IChunk::shrink_low();
+ if (t-><T>IChunk::empty() && !one_chunk())
+ {
+ hd = t->next();
+ del_chunk(t);
+ t = hd;
+ }
+ set_cache(t);
+ return ++lo;
+}
+
+void <T>XPlex::reverse()
+{
+ <T> tmp;
+ int l = lo;
+ int h = fnc - 1;
+ <T>IChunk* loch = hd;
+ <T>IChunk* hich = tl();
+ while (l < h)
+ {
+ <T>* lptr = loch->pointer_to(l);
+ <T>* hptr = hich->pointer_to(h);
+ tmp = *lptr;
+ *lptr = *hptr;
+ *hptr = tmp;
+ if (++l >= loch->fence_index()) loch = loch->next();
+ if (--h < hich->low_index()) hich = hich->prev();
+ }
+}
+
+void <T>XPlex::fill(const <T&> x)
+{
+ for (int i = lo; i < fnc; ++i) (*this)[i] = x;
+}
+
+void <T>XPlex::fill(const <T&> x, int l, int hi)
+{
+ for (int i = l; i <= hi; ++i) (*this)[i] = x;
+}
+
+
+void <T>XPlex::clear()
+{
+ if (fnc != lo)
+ {
+ <T>IChunk* t = tl();
+ while (t != hd)
+ {
+ <T>IChunk* prv = t->prev();
+ del_chunk(t);
+ t = prv;
+ }
+ t-><T>IChunk::clear(lo);
+ set_cache(t);
+ fnc = lo;
+ }
+}
+
+
+int <T>XPlex::OK () const
+{
+ int v = hd != 0 && ch != 0; // at least one chunk
+
+ v &= fnc == tl()->fence_index();// last chunk fence == plex fence
+ v &= lo == ((hd))-><T>IChunk::low_index(); // first lo == plex lo
+
+// loop for others:
+ int found_ch = 0; // to make sure ch is in list;
+ const <T>IChunk* t = (hd);
+ for (;;)
+ {
+ if (t == ch) ++found_ch;
+ v &= t-><T>IChunk::OK(); // each chunk is OK
+ if (t == tl())
+ break;
+ else // and has indices contiguous to succ
+ {
+ v &= t->top_index() == t->next()->base_index();
+ if (t != hd) // internal chunks full
+ {
+ v &= !t->empty();
+ v &= !t->can_grow_low();
+ v &= !t->can_grow_high();
+ }
+ t = t->next();
+ }
+ }
+ v &= found_ch == 1;
+ if (!v) error("invariant failure");
+ return v;
+}
diff --git a/gnu/lib/libg++/include/gen/XPlex.hP b/gnu/lib/libg++/include/gen/XPlex.hP
new file mode 100644
index 00000000000..82445b30874
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/XPlex.hP
@@ -0,0 +1,238 @@
+// 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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _<T>XPlex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _<T>XPlex_h 1
+
+#include "<T>.Plex.h"
+
+class <T>XPlex: public <T>Plex
+{
+ <T>IChunk* ch; // cached chunk
+
+ void make_initial_chunks(int up = 1);
+
+ void cache(int idx) const;
+ void cache(const <T>* p) const;
+
+ <T>* dopred(const <T>* p) const;
+ <T>* dosucc(const <T>* p) const;
+
+ inline void set_cache(const <T>IChunk* t) const; // logically,
+ // not physically const
+public:
+ <T>XPlex(); // set low = 0;
+ // fence = 0;
+ // csize = default
+
+ <T>XPlex(int ch_size); // low = 0;
+ // fence = 0;
+ // csize = ch_size
+
+ <T>XPlex(int lo, // low = lo;
+ int ch_size); // fence=lo
+ // csize = ch_size
+
+ <T>XPlex(int lo, // low = lo
+ int hi, // fence = hi+1
+ const <T&> initval,// fill with initval,
+ int ch_size = 0); // csize= ch_size
+ // or fence-lo if 0
+
+ <T>XPlex(const <T>XPlex&);
+
+ void operator= (const <T>XPlex&);
+
+// virtuals
+
+
+ inline <T>& high_element ();
+ inline <T>& low_element ();
+
+ inline const <T>& high_element () const;
+ inline const <T>& low_element () const;
+
+ inline Pix first() const;
+ inline Pix last() const;
+ inline void prev(Pix& ptr) const;
+ inline void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ inline <T>& operator () (Pix p);
+ inline const <T>& operator () (Pix p) const;
+
+ inline int low() const;
+ inline int high() const;
+ inline int valid(int idx) const;
+ inline void prev(int& idx) const;
+ inline void next(int& x) const;
+ inline <T>& operator [] (int index);
+ inline const <T>& operator [] (int index) const;
+
+ inline int Pix_to_index(Pix p) const;
+ inline Pix index_to_Pix(int idx) const;
+
+ inline int can_add_high() const;
+ inline int can_add_low() const;
+ inline int full() const;
+
+ int add_high(const <T&> elem);
+ int del_high ();
+ int add_low (const <T&> elem);
+ int del_low ();
+
+ void fill(const <T&> x);
+ void fill(const <T&> x, int from, int to);
+ void clear();
+ void reverse();
+
+ int OK () const;
+
+};
+
+
+inline void <T>XPlex::prev(int& idx) const
+{
+ --idx;
+}
+
+inline void <T>XPlex::next(int& idx) const
+{
+ ++idx;
+}
+
+inline int <T>XPlex::full () const
+{
+ return 0;
+}
+
+inline int <T>XPlex::can_add_high() const
+{
+ return 1;
+}
+
+inline int <T>XPlex::can_add_low() const
+{
+ return 1;
+}
+
+inline int <T>XPlex::valid (int idx) const
+{
+ return idx >= lo && idx < fnc;
+}
+
+inline int <T>XPlex::low() const
+{
+ return lo;
+}
+
+inline int <T>XPlex::high() const
+{
+ return fnc - 1;
+}
+
+inline <T>& <T>XPlex:: operator [] (int idx)
+{
+ if (!ch->actual_index(idx)) cache(idx);
+ return *(ch->pointer_to(idx));
+}
+
+inline const <T>& <T>XPlex:: operator [] (int idx) const
+{
+ if (!ch->actual_index(idx)) cache(idx);
+ return *((const <T>*)(ch->pointer_to(idx)));
+}
+
+inline <T>& <T>XPlex::low_element ()
+{
+ if (empty()) index_error();
+ return *(hd->pointer_to(lo));
+}
+
+inline const <T>& <T>XPlex::low_element () const
+{
+ if (empty()) index_error();
+ return *((const <T>*)(hd->pointer_to(lo)));
+}
+
+inline <T>& <T>XPlex::high_element ()
+{
+ if (empty()) index_error();
+ return *(tl()->pointer_to(fnc - 1));
+}
+
+inline const <T>& <T>XPlex::high_element () const
+{
+ if (empty()) index_error();
+ return *((const <T>*)(tl()->pointer_to(fnc - 1)));
+}
+
+inline int <T>XPlex::Pix_to_index(Pix px) const
+{
+ <T>* p = (<T>*)px;
+ if (!ch->actual_pointer(p)) cache(p);
+ return ch->index_of(p);
+}
+
+inline Pix <T>XPlex::index_to_Pix(int idx) const
+{
+ if (!ch->actual_index(idx)) cache(idx);
+ return (Pix)(ch->pointer_to(idx));
+}
+
+inline Pix <T>XPlex::first() const
+{
+ return Pix(hd-><T>IChunk::first_pointer());
+}
+
+inline Pix <T>XPlex::last() const
+{
+ return Pix(tl()-><T>IChunk::last_pointer());
+}
+
+inline void <T>XPlex::prev(Pix& p) const
+{
+ Pix q = Pix(ch-><T>IChunk::pred((<T>*) p));
+ p = (q == 0)? Pix(dopred((const <T>*) p)) : q;
+}
+
+inline void <T>XPlex::next(Pix& p) const
+{
+ Pix q = Pix(ch-><T>IChunk::succ((<T>*) p));
+ p = (q == 0)? Pix(dosucc((const <T>*)p)) : q;
+}
+
+inline <T>& <T>XPlex:: operator () (Pix p)
+{
+ return *((<T>*)p);
+}
+
+inline const <T>& <T>XPlex:: operator () (Pix p) const
+{
+ return *((const <T>*)p);
+}
+
+inline void <T>XPlex::set_cache(const <T>IChunk* t) const
+{
+ ((<T>XPlex*)(this))->ch = (<T>IChunk*)t;
+}
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/defs.hP b/gnu/lib/libg++/include/gen/defs.hP
new file mode 100644
index 00000000000..f03617594fe
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/defs.hP
@@ -0,0 +1,57 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _<T>defs_h
+#define _<T>defs_h 1
+
+
+// equality operator
+#ifndef <T>EQ
+#define <T>EQ(a, b) ((a) == (b))
+#endif
+
+// less-than-or-equal
+#ifndef <T>LE
+#define <T>LE(a, b) ((a) <= (b))
+#endif
+
+// comparison : less-than -> < 0; equal -> 0; greater-than -> > 0
+#ifndef <T>CMP
+#define <T>CMP(a, b) ( ((a) <= (b))? (((a) == (b))? 0 : -1) : 1 )
+#endif
+
+// hash function
+#ifndef <T>HASH
+extern unsigned int hash(<T&>);
+#define <T>HASH(x) hash(x)
+#endif
+
+// initial capacity for structures requiring one
+
+#ifndef DEFAULT_INITIAL_CAPACITY
+#define DEFAULT_INITIAL_CAPACITY 100
+#endif
+
+// HASHTABLE_TOO_CROWDED(COUNT, SIZE) is true iff a hash table with COUNT
+// elements and SIZE slots is too full, and should be resized.
+// This is so if available space is less than 1/8.
+
+#define HASHTABLE_TOO_CROWDED(COUNT, SIZE) ((SIZE) - ((SIZE) >> 3) <= (COUNT))
+
+#endif
diff --git a/gnu/lib/libg++/include/gen/intSList.hP b/gnu/lib/libg++/include/gen/intSList.hP
new file mode 100644
index 00000000000..24aa3b6a685
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/intSList.hP
@@ -0,0 +1,33 @@
+/* : Light weight List: This will simply reuse code from a int List, which
+was genclassed from the SLList libg++ class. The classes generated from this file
+will all be derived classes from class VoidSLList or intSLList. Note that class SLList does not
+offer all the functionality of List classes, such as sharing of sub-Lists.
+However, no additional code is needed at all and no .cc file is generated. So it costs nothing
+to use these type-safe Lists. Only member functions needing type casting are re-defined */
+
+
+#ifndef _<T>SList_h
+#define _<T>SList_h 1
+
+#include "int.SLList.h"
+#include "<T>.defs.h"
+
+class <T>SList : public intSLList
+{
+public:
+ <T>SList() {}
+ <T>SList(<T>SList& a) : (a) {}
+ ~<T>SList() {}
+
+ <T>SList& operator = (<T>SList& a) {
+ return (<T>SList&) intSLList::operator= (a); }
+
+ <T>& operator () (Pix p) { return (<T>&) (intSLList::operator() (p)); }
+ <T>& front() { return (<T>&) intSLList::front(); }
+ <T>& rear() { return (<T>&) intSLList::rear(); }
+ <T> remove_front() { return (<T>) intSLList::remove_front(); }
+
+};
+
+#endif /* conditional include */
+
diff --git a/gnu/lib/libg++/include/gen/intVec.hP b/gnu/lib/libg++/include/gen/intVec.hP
new file mode 100644
index 00000000000..e3838700251
--- /dev/null
+++ b/gnu/lib/libg++/include/gen/intVec.hP
@@ -0,0 +1,80 @@
+/* : light weight Vector: This will simply reuse code from */
+/* a int Vec, which was genclassed from the Vec libg++ class. */
+/* The classes generated from this file will all be derived classes */
+/* from class VoidVec or intVec. No .cc file is generated. So */
+/* it costs nothing to use these type-safe Vectors. Only member */
+/* functions needing type casting are re-defined. */
+/* */
+
+#ifndef _<T>Vec_h
+#define _<T>Vec_h 1
+
+#include "int.Vec.h"
+#include "<T>.defs.h"
+
+
+#ifndef _<T>_typedefs
+#define _<T>_typedefs 1
+typedef void (*<T>Procedure)(<T> );
+typedef <T> (*<T>Mapper)(<T> );
+typedef <T> (*<T>Combiner)(<T> , <T> );
+typedef int (*<T>Predicate)(<T> );
+typedef int (*<T>Comparator)(<T> , <T> );
+#endif
+
+class <T>Vec : public intVec
+{
+protected:
+ <T>Vec(int l, <T>* d) : (l, (int*) d) {};
+public:
+ <T>Vec() {};
+ <T>Vec(int l) : (l) {};
+ <T>Vec(int l, <T&> fill_value) : (l, fill_value) {};
+ <T>Vec(<T>Vec& v) : (v) {};
+ <T>Vec(intVec& v) {fake_copy(v, s, len);}
+ ~<T>Vec() {};
+
+ <T>Vec& operator = (<T>Vec& a)
+ {return (<T>Vec&) intVec::operator= (a);}
+ <T>Vec at(int from, int n) {return (<T>Vec) intVec::at(from, n);}
+
+ <T>& operator [] (int n) {return (<T>&)intVec::operator[] (n);}
+ <T>& elem(int n) {return (<T>&)intVec::elem(n);}
+
+ friend <T>Vec concat(<T>Vec& a, <T>Vec& b);
+ friend <T>Vec map(<T>Mapper f, <T>Vec & a);
+ friend <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f);
+ friend <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b);
+ friend <T>Vec reverse(<T>Vec& a);
+
+ void sort(<T>Comparator f);
+ void apply(<T>Procedure f);
+ <T> reduce(<T>Combiner f, <T> base);
+};
+
+inline <T>Vec concat(<T>Vec& a, <T>Vec& b)
+{return (<T>Vec)concat((intVec&)a, (intVec&)b);}
+
+inline <T>Vec map(<T>Mapper f, <T>Vec & a) {
+ return (<T>Vec)map((intMapper)f, (intVec&)a); }
+
+inline <T>Vec merge(<T>Vec & a, <T>Vec & b, <T>Comparator f) {
+ return (<T>Vec)merge((intVec&)a, (intVec&)b, (intComparator)f); }
+
+inline <T>Vec combine(<T>Combiner f, <T>Vec & a, <T>Vec & b) {
+ return (<T>Vec)combine((intCombiner)f, (intVec&)a, (intVec&)b); }
+
+inline <T>Vec reverse(<T>Vec& a) {
+ return (<T>Vec)reverse((intVec&)a);}
+
+inline void <T>Vec::sort(<T>Comparator f) {
+ intVec::sort((intComparator) f); }
+
+inline void <T>Vec::apply(<T>Procedure f) {
+ intVec::apply((intProcedure) f); }
+
+inline <T> <T>Vec::reduce(<T>Combiner f, <T> base) {
+ return (<T>)intVec::reduce((intCombiner)f, base);}
+
+#endif /* conditional include */
+
diff --git a/gnu/lib/libg++/libg++/genclass/Makefile b/gnu/lib/libg++/libg++/genclass/Makefile
new file mode 100644
index 00000000000..81c0956229b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/genclass/Makefile
@@ -0,0 +1,17 @@
+# $NetBSD: Makefile,v 1.1.1.1 1996/03/09 00:01:12 phil Exp $
+# Makefile for g++ library genclass
+
+PROG= genclass
+SRCS= genclass.sh
+NOMAN=
+STRIP=
+
+SRCDIR=${.CURDIR}
+
+BINDIR ?= /usr/bin
+
+genclass: genclass.sh
+ cp $(SRCDIR)/genclass.sh genclass
+
+.include <bsd.prog.mk>
+
diff --git a/gnu/lib/libg++/libg++/genclass/genclass.sh b/gnu/lib/libg++/libg++/genclass/genclass.sh
new file mode 100644
index 00000000000..5db4bca4dff
--- /dev/null
+++ b/gnu/lib/libg++/libg++/genclass/genclass.sh
@@ -0,0 +1,452 @@
+#!/bin/sh
+
+# Copyright (C) 1989 Free Software Foundation, Inc.
+#
+# genclass program enhanced by Wendell C. Baker
+# (original by Doug Lea (dl@rocky.oswego.edu))
+
+#This file is part of GNU libg++.
+
+#GNU libg++ 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 1, or (at your option)
+#any later version.
+
+#GNU libg++ is distributed in the hope that 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 libg++; see the file COPYING. If not, write to
+#the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+#
+# genclass -list [proto ...]
+# genclass -catalog [proto ...]
+# genclass type1 {ref|val} proto [out_prefix]
+# genclass -2 type1 {ref|val} type2 {ref, val} proto [out_prefix]
+#
+# Generate classes from prototypes
+#
+name=genclass ;
+usage="
+ $name -list [proto ...]
+ $name -catalog [proto ...]
+ $name type1 {ref|val} proto [out_prefix]
+ $name -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]" ;
+
+case "$1" in
+-usage)
+ #
+ # -usage
+ #
+ echo "usage: $usage" 1>&2 ;
+ exit 0;
+ ;;
+-version)
+ #
+ # -version
+ #
+ # 2.7.1 is substituted by the build process.
+ # We currently use the libg++ version number (extracted from ../Makefile).
+ echo "$name: version 2.7.1" ;
+ exit 0;
+ ;;
+-requires)
+ #
+ # -requires
+ #
+ # The following line should contain any nonstandard programs
+ # which must be in the users's path (i.e. not referenced by a
+ # fullpath);it allows one to check a script for dependencies
+ # without exhaustively testing its usages.
+ # ... in this case genclass depends on nothing else.
+ echo ;
+ exit 0;
+ ;;
+esac ;
+
+# pull it in from the environment
+[ "$TRACE" = "" ] || set -xv
+
+# Search in standard g++ prototype directory and in the current directory
+# NOTE: this variable is edited by the install process
+PROTODIR=/usr/include/g++/gen
+
+pwd=`pwd`
+
+case "$1" in
+-catalog*|-list*)
+ #
+ # genclass -catalog [proto ...]
+ # genclass -list [proto ...]
+ #
+ option="$1" ;
+ shift ;
+
+ case $# in
+ 0)
+ #
+ # -catalog
+ # -list
+ #
+ select=all ;
+ select_pattern=p ;
+ ;;
+ *)
+ #
+ # -catalog proto ...
+ # -list proto ...
+ #
+ select="$@" ;
+ select_pattern= ;
+ for i in $@ ; do
+ select_pattern="\
+$select_pattern
+/.*$i\$/ p
+" ;
+ done ;
+
+ ;;
+ esac ;
+
+ #
+ # select_pattern is now a (possibly-vacuous) newline-
+ # separated list of patterns of the form:
+ #
+ # /.*Proto1$/ p
+ # /.*Proto2$/ p
+ # /.*Proto3$/ p
+ #
+ # or select_pattern is simply ``p'' to select everything
+
+ # Hmmm... not all systems have a fmt program; should we
+ # just go ahead and use ``nroff -Tcrt | cat -s'' here?
+ fmt='nroff -Tcrt | cat -s'
+ #fmt=fmt ;
+
+ case "$option" in
+ -catalog*)
+ #
+ # -catalog [proto ...]
+ #
+ echo "\
+Catalog of ${name} class templates
+directories searched:
+ $PROTODIR
+ $pwd
+selecting: $select
+classes available:" ;
+ ;;
+ -list*)
+ #
+ # -list [proto ...]
+ #
+ # no need to do anything (the list is coming out next)
+ ;;
+ esac ;
+
+# The sed script does the following:
+# - If it does not end in a .ccP or .hP then
+# it's not a template and we are not intereseted.
+# - Get rid of pathname components [s;.*/;;]
+# - Just take the template names
+# - change quoting conventions and select off what we want to see
+# -if it did not pass the patterns, kill it
+
+ ls $pwd $PROTODIR | sed -e '
+/\.ccP$/ !{
+ /\.hP$/ !{
+ d
+ }
+}
+s;.*/;;
+s/\.ccP$//
+s/\.hP$//
+' -e "$select_pattern
+d
+" | sort -u | case "$option" in
+ -catalog*)
+ # The library catalog information preceded the list
+ # format the list, and tab in in a bit to make it readable.
+ # Re-evaluate $fmt because it might contain a shell command
+ eval $fmt | sed -e 's/.*/ &/' ;
+ ;;
+ -list*)
+ # nothing special, just let the sorted list dribble out
+ # we must use cat to receive (and reproduce) the incoming list
+ cat ;
+ ;;
+ esac ;
+ exit 0;
+ ;;
+-2)
+ #
+ # genclass -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]
+ #
+ N=2 ;
+
+ case $# in
+ 6) # genclass -2 type1 {ref|val} type2 {ref|val} proto
+ ;;
+ 7) # genclass -2 type1 {ref|val} type2 {ref|val} proto out_prefix
+ ;;
+ *)
+ echo "usage: $usage" 1>&2 ;
+ exit 1;
+ esac ;
+ shift ;
+ ;;
+*)
+ #
+ # genclass type1 {ref|val} proto [out_prefix]
+ #
+ N=1 ;
+
+ case $# in
+ 3) # genclass type1 {ref|val} proto
+ ;;
+ 4) # genclass type1 {ref|val} proto out_prefix
+ ;;
+ *)
+ echo "usage: $usage" 1>&2 ;
+ exit 1;
+ esac ;
+ ;;
+esac
+
+#
+# Args are now (the point being the leading ``-2'' is gone)
+#
+# type1 {ref|val} proto [out_prefix]
+# type1 {ref|val} type2 {ref|val} proto [out_prefix]
+#
+
+#
+# Quote all of the $1 $2 etc references to guard against
+# dynamic syntax errors due to vacuous arguments (i.e. '')
+# as sometimes occurs when genclass is used from a Makefile
+#
+
+T1="$1";
+T1NAME="$T1." ;
+T1SEDNAME="$T1" ;
+
+case "$2" in
+ref)
+ T1ACC="\&" ;
+ ;;
+val)
+ T1ACC=" " ;
+ ;;
+*)
+ echo "${name}: Must specify type1 access as ref or val" 1>&2 ;
+ echo "usage: $usage" 1>&2 ;
+ exit 1;
+ ;;
+esac
+
+# N is either 1 or 2
+
+case $N in
+1)
+ #
+ # type1 {ref|val} proto [out_prefix]
+ #
+ class="$3" ;
+
+ T2="" ;
+ T2ACC="" ;
+ ;;
+2)
+ #
+ # type1 {ref|val} type2 {ref|val} proto [out_prefix]
+ #
+ class="$5" ;
+
+ T2="$3";
+ T2NAME="$T2." ;
+ T2SEDNAME="$T2" ;
+
+ case "$4" in
+ ref)
+ T2ACC="\&" ;
+ ;;
+ val)
+ T2ACC=" " ;
+ ;;
+ *)
+ echo "${name}: Must specify type2 access: ref or val" 1>&2 ;
+ echo "usage: $usage" 1>&2 ;
+ exit 1;;
+ esac;
+ ;;
+esac
+
+defaultprefix="$T1NAME$T2NAME" ;
+
+case $# in
+3) # type1 {ref|val} proto
+ replaceprefix="N" ;
+ prefix="$defaultprefix" ;
+ ;;
+5) # type1 {ref|val} type2 {ref|val} proto
+ replaceprefix="N" ;
+ prefix="$defaultprefix" ;
+ ;;
+4) # type1 {ref|val} proto out_prefix
+ prefix="$4" ;
+ replaceprefix="Y" ;
+ ;;
+6) # type1 {ref|val} type2 {ref|val} proto out_prefix
+ prefix="$6" ;
+ replaceprefix="Y" ;
+ ;;
+*)
+ echo "${name}: too many arguments" 1>&2 ;
+ echo "usage: $usage" 1>&2 ;
+ exit 1;
+ ;;
+esac ;
+
+src_h=$class.hP
+src_cc=$class.ccP
+out_h=$prefix$class.h;
+out_cc=$prefix$class.cc ;
+
+#
+# Note #1: The .h and .cc parts are done separately
+# in case only a .h exists for the prototype
+#
+# Note #2: Bind the .h and .cc parts to the fullpath
+# directories at the same time to ensure consistency.
+#
+
+if [ -f $pwd/$src_h ] ; then
+ fullsrc_h=$pwd/$src_h ;
+ fullsrc_cc=$pwd/$src_cc ;
+elif [ -f $PROTODIR/$src_h ] ; then
+ fullsrc_h=$PROTODIR/$src_h ;
+ fullsrc_cc=$PROTODIR/$src_cc ;
+else
+ echo "${name}: there is no prototype for class $class - file $src_h" 1>&2 ;
+ $0 -list ;
+ exit 1;
+fi
+
+CASES="$N$replaceprefix" ;
+# CASES is one of { 2Y 2N 1Y 1N }
+
+#
+# WATCHOUT - we have no way of checking whether or not
+# the proper case type is being used with the prototype.
+#
+# For example, we have no way of ensuring that any of
+# Map variants are specified with the -2 argument set
+# Further, we have no way of ensuring that -2 is not
+# used with the prototypes which require only one.
+#
+# The second problem is not serious because it still
+# results in correctly-generated C++ code; the first
+# problem is serious because it results in C++ code that
+# still has ``<C>'' and ``<C&>'' syntax inside it. Such
+# code of course will not compile.
+#
+# SO THE BEST WE CAN DO - is check for the presence of
+# <C> and <C&> AFTER the thing has been generated.
+#
+
+case $CASES in
+2Y) # Two output substitutions, change the prefix
+ sed < $fullsrc_h > $out_h -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+s/<C>/$T2/g
+s/<C&>/$T2$T2ACC/g
+s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g
+s/$T1SEDNAME\./$prefix/g
+s/$T2SEDNAME\./$prefix/g
+" ;
+ ;;
+2N) # Two output substitutions, use the default prefix
+ sed < $fullsrc_h > $out_h -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+s/<C>/$T2/g
+s/<C&>/$T2$T2ACC/g
+" ;
+ ;;
+1Y) # One output substitution, change the prefix
+ sed < $fullsrc_h > $out_h -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+s/$T1SEDNAME\./$prefix/g
+" ;
+ ;;
+1N) # One output substitution, use the default prefix
+ sed < $fullsrc_h > $out_h -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+" ;
+ ;;
+esac
+
+if egrep '<C&?>' $out_h > /dev/null ; then
+ echo "${name}: the $class class requires the -2 syntax for the 2nd type" 1>&2 ;
+ echo "usage: $usage" 1>&2 ;
+ # the user does not get to see the mistakes (he might try to compile it)
+ rm $out_h ;
+ exit 1;
+fi ;
+
+if [ ! -f $fullsrc_cc ] ; then
+ echo "${name}: warning, class has a .h but no .cc file" 1>&2 ;
+ exit 0;
+fi
+
+case $CASES in
+2Y) # Two output substitutions, change the prefix
+ sed < $fullsrc_cc > $out_cc -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+s/<C>/$T2/g
+s/<C&>/$T2$T2ACC/g
+s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g
+s/$T1SEDNAME\./$prefix/g
+s/$T2SEDNAME\./$prefix/g
+"
+ ;;
+2N) # Two output substitutions, use the default prefix
+ sed < $fullsrc_cc > $out_cc -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+s/<C>/$T2/g
+s/<C&>/$T2$T2ACC/g
+"
+ ;;
+1Y) # One output substitution, change the prefix
+ sed < $fullsrc_cc > $out_cc -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+s/$T1SEDNAME\./$prefix/g
+"
+ ;;
+1N) # One output substitution, use the default prefix
+ sed < $fullsrc_cc > $out_cc -e "
+s/<T>/$T1/g
+s/<T&>/$T1$T1ACC/g
+"
+ ;;
+esac
+
+if egrep '<C&?>' $out_h $out_cc > /dev/null ; then
+ echo "${name}: the $class class requires the -2 syntax for the 2nd type" 1>&2 ;
+ echo "usage: $usage" 1>&2 ;
+ # the user does not get to see the mistakes (he might try to compile it)
+ rm $out_h $out_cc ;
+ exit 1;
+fi ;
+
+exit 0;
diff --git a/gnu/lib/libg++/libg++/src/ACG.cc b/gnu/lib/libg++/libg++/src/ACG.cc
new file mode 100644
index 00000000000..b8a3c89e582
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/ACG.cc
@@ -0,0 +1,292 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
+_G_uint32_t 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 _G_uint32_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
+};
+
+//
+// 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 _G_uint32_t LC_A = 66049;
+static const _G_uint32_t LC_C = 3907864577;
+static inline _G_uint32_t LCG(_G_uint32_t x)
+{
+ return( x * LC_A + LC_C );
+}
+
+
+ACG::ACG(_G_uint32_t seed, int size)
+{
+ register int l;
+ initialSeed = seed;
+
+ //
+ // Determine the size of the state table
+ //
+
+ for (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 _G_uint32_t[stateSize + auxSize];
+ auxState = &state[stateSize];
+
+ reset();
+}
+
+//
+// Initialize the state
+//
+void
+ACG::reset()
+{
+ register _G_uint32_t 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(_G_int32_t));
+}
+
+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.
+//
+
+_G_uint32_t
+ACG::asLong()
+{
+ _G_uint32_t 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 _G_uint32_t 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 _G_uint32_t *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++/src/ACG.h b/gnu/lib/libg++/libg++/src/ACG.h
new file mode 100644
index 00000000000..aa1d25914a8
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 {
+
+ _G_uint32_t initialSeed; // used to reset generator
+ int initialTableEntry;
+
+ _G_uint32_t *state;
+ _G_uint32_t *auxState;
+ short stateSize;
+ short auxSize;
+ _G_uint32_t lcgRecurr;
+ short j;
+ short k;
+
+protected:
+
+public:
+ ACG(_G_uint32_t seed = 0, int size = 55);
+ virtual ~ACG();
+ //
+ // Return a long-words word of random bits
+ //
+ virtual _G_uint32_t asLong();
+ virtual void reset();
+};
+
+#endif
diff --git a/gnu/lib/libg++/libg++/src/AllocRing.cc b/gnu/lib/libg++/libg++/src/AllocRing.cc
new file mode 100644
index 00000000000..519f36486d1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) operator delete (nodes[current].ptr);
+ p = operator new (size);
+ nodes[current].ptr = p;
+ nodes[current].sz = size;
+ }
+ ++current;
+ if (current >= n) current = 0;
+ return p;
+}
diff --git a/gnu/lib/libg++/libg++/src/AllocRing.h b/gnu/lib/libg++/libg++/src/AllocRing.h
new file mode 100644
index 00000000000..fc8b30c44d5
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Binomial.cc b/gnu/lib/libg++/libg++/src/Binomial.cc
new file mode 100644
index 00000000000..8e2b56d71ab
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Binomial.h b/gnu/lib/libg++/libg++/src/Binomial.h
new file mode 100644
index 00000000000..8ce241d6f4e
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/BitSet.cc b/gnu/lib/libg++/libg++/src/BitSet.cc
new file mode 100644
index 00000000000..dd1f6503990
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/BitSet.cc
@@ -0,0 +1,1101 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ 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>
+
+#undef OK
+
+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 ((_BS_word)(~0L))
+#define MAXBitSetRep_SIZE ((1U << (sizeof(unsigned short)*CHAR_BIT - 1)) - 1)
+#define MINBitSetRep_SIZE (sizeof(_BS_word)*CHAR_BIT)
+
+#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 _BS_word lmask(int p)
+{
+ return ONES << p;
+}
+
+// mask out high bits
+
+static inline _BS_word rmask(int p)
+{
+ return ONES >> (BITSETBITS - 1 - p);
+}
+
+
+inline static BitSetRep* BSnew(int newlen)
+{
+ unsigned int siz = sizeof(BitSetRep) + newlen * sizeof(_BS_word)
+ + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINBitSetRep_SIZE;;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXBitSetRep_SIZE * sizeof(_BS_word))
+ (*lib_error_handler)("BitSet", "Requested length out of range");
+
+ BitSetRep* rep = new (operator new (allocsiz)) BitSetRep;
+ memset(rep, 0, allocsiz);
+ rep->sz = (allocsiz - sizeof(BitSetRep) + sizeof(_BS_word)) / sizeof(_BS_word);
+ return rep;
+}
+
+BitSetRep* BitSetalloc(BitSetRep* old, const _BS_word* 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(_BS_word));
+ // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
+ if (rep->virt)
+ memset(&rep->s[srclen], ONES, (newlen - srclen) * sizeof(_BS_word));
+ 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(_BS_word));
+ 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(_BS_word));
+ delete old;
+ }
+ else
+ {
+ rep = old;
+ if (rep->len < newlen)
+ memset(&rep->s[rep->len],
+ rep->virt ? ONES : 0,
+ (newlen - rep->len) * sizeof(_BS_word));
+ }
+
+ 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(_BS_word));
+ rep->len = newlen;
+ rep->virt = src->virt;
+ }
+ return rep;
+}
+
+
+// remove unneeded top bits
+
+inline static void trim(BitSetRep* rep)
+{
+ int l = rep->len;
+ _BS_word* 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;
+
+ const _BS_word* xs = x.rep->s;
+ const _BS_word* ys = y.rep->s;
+ if (xl < yl) {
+ if (memcmp((void*)xs, (void*)ys, xl * sizeof(_BS_word)))
+ return 0;
+ ys+=xl;
+ const _BS_word* topy = &(ys[yl]);
+ while (ys<topy)
+ if (x.rep->virt?((*ys++)!=ONES):((*ys++)!=0))
+ return 0;
+ }
+ else {
+ if (memcmp((void*)xs, (void*)ys, yl * sizeof(_BS_word)))
+ return 0;
+ if (xl > yl) {
+ xs+=yl;
+ const _BS_word* topx = &(xs[xl]);
+ while (xs<topx)
+ if (y.rep->virt?((*xs++)!=ONES):((*xs++)!=0))
+ 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;
+
+ const _BS_word* xs = x.rep->s;
+ const _BS_word* ys = y.rep->s;
+ const _BS_word* topx = &(xs[xl]);
+ const _BS_word* topy = &(ys[yl]);
+
+ while (xs < topx && ys < topy)
+ {
+ _BS_word a = *xs++;
+ _BS_word b = *ys++;
+ if ((a | b) != b)
+ return 0;
+ }
+ if (xl < yl) {
+ if (x.rep->virt) {
+ while (ys<topy)
+ if ((*ys++)!=ONES)
+ return 0;
+ }
+ }
+ else if (xl > yl) {
+ if (!y.rep->virt) {
+ while (xs<topx)
+ if ((*xs++)!=0)
+ 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;
+
+ _BS_word* xs = x.rep->s;
+ _BS_word* ys = y.rep->s;
+ _BS_word* topx = &(xs[xl]);
+ _BS_word* topy = &(ys[yl]);
+ int one_diff = 0;
+ while (xs < topx && ys < topy)
+ {
+ _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 (xl < yl) {
+ if (x.rep->virt) {
+ if (!one_diff)
+ return 0;
+ while (ys<topy)
+ if ((*ys++)!=ONES)
+ return 0;
+ return 1;
+ }
+ else {
+ if (one_diff || y.rep->virt)
+ return 1;
+ while (ys<topy)
+ if ((*ys++)!=0)
+ return 1;
+ return 0;
+ }
+ }
+ else if (xl > yl) {
+ if (y.rep->virt) {
+ if (one_diff || !x.rep->virt)
+ return 1;
+ while (xs<topx)
+ if ((*xs++)!=ONES)
+ return 1;
+ return 0;
+ }
+ else {
+ if (!one_diff)
+ return 0;
+ while (xs<topx)
+ if ((*xs++)!=0)
+ return 0;
+ return 1;
+ }
+ }
+ else
+ return one_diff || x.rep->virt < y.rep->virt;
+}
+
+int lcompare(const BitSet& x, const BitSet& y)
+{
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ const _BS_word* xs = x.rep->s;
+ const _BS_word* ys = y.rep->s;
+ const _BS_word* topx = &(xs[xl]);
+ const _BS_word* topy = &(ys[yl]);
+
+ while (xs < topx && ys < topy)
+ {
+ _BS_word a = *xs++;
+ _BS_word b = *ys++;
+ if (a!=b) {
+#if 0
+ // Faster but opinable
+ return (a<b) ? -1 : 1;
+#else
+ _BS_word diff=(a^b); // one's where different
+ _BS_word mask=diff&~(diff-1); // first bit different
+ return (a&mask)?1:-1;
+#endif
+ }
+ if (a<b)
+ return -1;
+ if (a>b)
+ return 1;
+ }
+ if (xl < yl) {
+ if (x.rep->virt) {
+ while (ys<topy)
+ if ((*ys++)!=ONES)
+ return 1;
+ return 0;
+ }
+ else {
+ while (ys<topy)
+ if ((*ys++)!=0)
+ return -1;
+ return 0;
+ }
+ }
+ else if (xl > yl) {
+ if (y.rep->virt) {
+ while (xs<topx)
+ if ((*xs++)!=ONES)
+ return -1;
+ return 0;
+ }
+ else {
+ while (xs<topx)
+ if ((*xs++)!=0)
+ return 1;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+int BitSet::empty() const
+{
+ if (rep->virt == 1)
+ return 0;
+
+ _BS_word* bots = rep->s;
+ _BS_word* 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;
+ _BS_word* s = rep->s;
+ _BS_word* tops = &(s[rep->len]);
+ if (b == 1)
+ {
+ while (s < tops)
+ {
+ _BS_word a = *s++;
+ for (int i = 0; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ ++l;
+ a >>= 1;
+ }
+ }
+ }
+ else
+ {
+ _BS_word maxbit = 1U << (BITSETBITS - 1);
+ while (s < tops)
+ {
+ _BS_word 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;
+ _BS_word* rs = r->s;
+ _BS_word* topr = &(rs[r->len]);
+ if (r->len == 0)
+ *rs = ONES;
+ else
+ {
+ while (rs < topr)
+ {
+ _BS_word 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);
+ _BS_word* rs = r->s;
+ _BS_word* topr = &(rs[rl]);
+
+ int av, bv;
+ const _BS_word* as;
+ const _BS_word* topa;
+ const _BS_word* bs;
+ const _BS_word* 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] |= (1U << pos);
+}
+
+void BitSet::clear()
+{
+ if (rep->len > 0) memset(rep->s, 0, rep->sz * sizeof(_BS_word));
+ 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] &= ~(1U << 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] ^= (1U << 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);
+
+ _BS_word* s = &(rep->s[index1]);
+ _BS_word m1 = lmask(pos1);
+ _BS_word m2 = rmask(pos2);
+ if (index2 == index1)
+ *s |= m1 & m2;
+ else
+ {
+ *s++ |= m1;
+ _BS_word* 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);
+
+ _BS_word* s = &(rep->s[index1]);
+ _BS_word m1 = lmask(pos1);
+ _BS_word m2 = rmask(pos2);
+ if (index2 == index1)
+ *s &= ~(m1 & m2);
+ else
+ {
+ *s++ &= ~m1;
+ _BS_word* 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);
+
+ _BS_word* s = &(rep->s[index1]);
+ _BS_word m1 = lmask(pos1);
+ _BS_word m2 = rmask(pos2);
+ if (index2 == index1)
+ *s ^= m1 & m2;
+ else
+ {
+ *s++ ^= m1;
+ _BS_word* top = &(rep->s[index2]);
+ *top ^= m2;
+ while (s < top)
+ {
+ _BS_word 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;
+ }
+ }
+
+ _BS_word* s = &(rep->s[index1]);
+ _BS_word m1 = lmask(pos1);
+ _BS_word m2 = rmask(pos2);
+
+ if (index2 == index1)
+ return (*s & m1 & m2) != 0;
+ else
+ {
+ if (*s++ & m1)
+ return 1;
+ _BS_word* 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;
+ _BS_word* s = rep->s;
+ _BS_word 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);
+
+ _BS_word* 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;
+ _BS_word a = s[j];
+
+ int i = pos;
+ _BS_word maxbit = 1U << pos;
+
+ if (b == 1)
+ {
+ for (; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ maxbit = 1U << (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 = 1U << (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;
+}
+
+BitSet shorttoBitSet(unsigned short i)
+{
+ BitSet r;
+ _BS_word w = i;
+ r.rep = BitSetalloc(0, &w, 1, 0, 2); trim(r.rep);
+ return r;
+}
+
+BitSet longtoBitSet(unsigned long i)
+{
+ BitSet r;
+#if 1
+ _BS_word w = i;
+ r.rep = BitSetalloc(0, &w, 1, 0, 2);
+#else
+ _BS_word u[2];
+ u[0] = i & ((_BS_word)(~(0)));
+ u[1] = sizeof(long) <= sizeof(_BS_word) ? 0 : i >> BITSETBITS;
+ r.rep = BitSetalloc(0, &u[0], 2, 0, 3);
+#endif
+ trim(r.rep);
+ return r;
+}
+
+#if defined(__GNUG__) && !defined(_G_NO_NRV)
+
+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);
+ _BS_word* rs = r.rep->s;
+ _BS_word a = 0;
+ _BS_word 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 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);
+ _BS_word* rs = r.rep->s;
+ _BS_word a = 0;
+ _BS_word 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 _BS_word* s = rep->s;
+ const _BS_word* top = &(s[rep->len - 1]);
+
+ while (s < top)
+ {
+ _BS_word a = *s++;
+ for (int j = 0; j < BITSETBITS; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a >>= 1;
+ }
+ }
+
+ if (!rep->virt)
+ {
+ _BS_word 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
+ {
+ _BS_word a = *s;
+ _BS_word mask = ONES;
+ _BS_word himask = (1U << (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++/src/BitSet.h b/gnu/lib/libg++/libg++/src/BitSet.h
new file mode 100644
index 00000000000..491102d50e8
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/BitSet.h
@@ -0,0 +1,370 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _BitSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#define _BitSet_h 1
+
+#include <iostream.h>
+#include <limits.h>
+#include <bitprims.h>
+
+#undef OK
+
+#define BITSETBITS (sizeof(_BS_word) * CHAR_BIT)
+
+struct BitSetRep
+{
+ unsigned short len; // number of _BS_word in s
+ unsigned short sz; // allocated slots
+ unsigned short virt; // virtual 0 or 1
+ _BS_word s[1]; // bits start here
+};
+
+extern BitSetRep* BitSetalloc(BitSetRep*, const _BS_word*,
+ 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);
+ friend int lcompare(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;
+
+// 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++/libg++/src/BitString.cc b/gnu/lib/libg++/libg++/src/BitString.cc
new file mode 100644
index 00000000000..32568fa7ef2
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/BitString.cc
@@ -0,0 +1,1608 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ 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>
+
+#undef OK
+
+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 = new (operator new (allocsiz)) BitStrRep;
+ 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++/src/BitString.h b/gnu/lib/libg++/libg++/src/BitString.h
new file mode 100644
index 00000000000..f3f2d8c3111
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/BitString.h
@@ -0,0 +1,763 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _BitString_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#define _BitString_h 1
+
+#include <stream.h>
+#include <limits.h>
+
+#undef OK
+
+#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++/libg++/src/Complex.h b/gnu/lib/libg++/libg++/src/Complex.h
new file mode 100644
index 00000000000..242f06e1664
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Complex.h
@@ -0,0 +1,10 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef _Complex_h
+#define _Complex_h
+
+// Use the ANSI complex number template.
+#include <complex>
+typedef complex<double> Complex;
+
+#endif
diff --git a/gnu/lib/libg++/libg++/src/CursesW.cc b/gnu/lib/libg++/libg++/src/CursesW.cc
new file mode 100644
index 00000000000..c80f33d47da
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/CursesW.cc
@@ -0,0 +1,257 @@
+/*
+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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
+
+#ifndef OK
+#define OK (1)
+#endif
+
+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++/src/CursesW.h b/gnu/lib/libg++/libg++/src/CursesW.h
new file mode 100644
index 00000000000..5bff08df258
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/CursesW.h
@@ -0,0 +1,603 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _CursesWindow_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _CursesWindow_h
+
+#include <_G_config.h>
+
+#if defined(__bsdi__) || defined(__NetBSD__) || defined(__FreeBSD__)
+#define _begx begx
+#define _begy begy
+#define _maxx maxx
+#define _maxy maxy
+#endif
+
+#if _G_HAVE_CURSES
+// Even many system which mostly have C++-ready header files,
+// do not have C++-ready curses.h.
+extern "C" {
+#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 int _G_box(WINDOW* win, chtype v, chtype h) {return box(win, v, h); }
+#undef box
+inline int box(WINDOW* win, chtype v, chtype h) {return _G_box(win, v, h); }
+#endif
+#ifdef scroll
+inline int (scroll)(WINDOW* win) { return scroll(win); }
+#undef scroll
+#endif
+#ifdef touchwin
+inline int (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++/libg++/src/DLList.cc b/gnu/lib/libg++/libg++/src/DLList.cc
new file mode 100644
index 00000000000..6e15408d35b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) const
+{
+ (*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) const
+{
+ 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_node(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() const
+{
+ 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++/src/DLList.h b/gnu/lib/libg++/libg++/src/DLList.h
new file mode 100644
index 00000000000..3723c5c6506
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/DLList.h
@@ -0,0 +1,139 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _DLList_h
+#ifdef __GNUG__
+//#pragma interface
+#endif
+#define _DLList_h 1
+
+#undef OK
+
+#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) const;
+ int owns(Pix p) const;
+ int OK() const;
+ 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;
+ }
+ const T& front() const {
+ if (h == 0) error("front: empty list");
+ return ((DLNode<T>*)h)->hd; }
+ const T& rear() const {
+ 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;
+ }
+ const T& operator () (Pix p) const {
+ if (p == 0) error("null Pix");
+ return ((DLNode<T>*)p)->hd;
+ }
+ Pix first() const { return Pix(h); }
+ Pix last() const { return (h == 0) ? 0 : Pix(h->bk); }
+ void next(Pix& p) const
+ { p = (p == 0 || p == h->bk)? 0 : Pix(((DLNode<T>*)p)->fd); }
+ void prev(Pix& p) const
+ { 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++/libg++/src/DiscUnif.cc b/gnu/lib/libg++/libg++/src/DiscUnif.cc
new file mode 100644
index 00000000000..950d9f9409e
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/DiscUnif.h b/gnu/lib/libg++/libg++/src/DiscUnif.h
new file mode 100644
index 00000000000..8633db2c804
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Erlang.cc b/gnu/lib/libg++/libg++/src/Erlang.cc
new file mode 100644
index 00000000000..5a73021f10f
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Erlang.h b/gnu/lib/libg++/libg++/src/Erlang.h
new file mode 100644
index 00000000000..3f2b3ede71f
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Fix.cc b/gnu/lib/libg++/libg++/src/Fix.cc
new file mode 100644
index 00000000000..9f68f826c6c
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Fix.cc
@@ -0,0 +1,670 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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>
+#include <new.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 = new (operator new (allocsiz)) Fix::Rep;
+ 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);
+ int i;
+ for ( 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);
+ int i;
+ for ( 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);
+ int i;
+ for ( 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);
+ int i;
+ for ( 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 != (_G_int32_t)0xffff8000L && a != (_G_int32_t)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((_G_int32_t) 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;
+ int i;
+ for ( 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;
+ int i;
+ for ( 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);
+ _G_int32_t 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++/src/Fix.h b/gnu/lib/libg++/libg++/src/Fix.h
new file mode 100644
index 00000000000..ae9b9046e7b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Fix.h
@@ -0,0 +1,523 @@
+// -*- 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(_G_uint16_t);
+ 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;
+ int i;
+ for ( 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(_G_uint16_t len)
+{
+ if ( len < min_length || len > max_length )
+ error("illegal length in declaration");
+ rep = new_Fix(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++/libg++/src/Fix16.cc b/gnu/lib/libg++/libg++/src/Fix16.cc
new file mode 100644
index 00000000000..dddab2495d3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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);
+}
+
+_G_int32_t Fix32::assign(double d)
+{
+ if (d == 1.0)
+ return Fix32_m_max;
+ else if (d > Fix32_max)
+ {
+ _G_int32_t i = Fix32_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix32_min)
+ {
+ _G_int32_t 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);
+ _G_uint32_t ua = (apos)? a.m : - a.m;
+ ua <<= 1; // ua is biased so result will be 31 bit mantissa, not 30:
+ _G_uint32_t hi_a = (ua >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_a = ua & ((1 << 16) - 1);
+
+ int bpos = (b.m >= 0);
+ _G_uint32_t ub = (bpos)? b.m : -b.m;
+ _G_uint32_t hi_b = (ub >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_b = ub & ((1 << 16) - 1);
+
+ _G_uint32_t 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;
+ _G_int32_t p = (apos != bpos)? -r : r;
+ return Fix32(p);
+}
+
+Fix16 operator / (const Fix16& a, const Fix16& b)
+{
+ short q;
+ int apos = (a.m >= 0);
+ _G_int32_t la = (apos)? a.m : -a.m;
+ _G_int32_t 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)
+{
+ _G_int32_t q;
+ int apos = (a.m >= 0);
+ _G_uint32_t la = (apos)? a.m : -a.m;
+ int bpos = (b.m >= 0);
+ _G_uint32_t 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;
+ _G_int32_t 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(_G_int32_t& i) const
+{
+ (*Fix32_overflow_handler)(i);
+}
+
+void Fix16::range_error(short& i) const
+{
+ (*Fix16_range_error_handler)(i);
+}
+
+void Fix32::range_error(_G_int32_t& 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(_G_int32_t&) {}
+void Fix32_overflow_saturate(_G_int32_t& i)
+ { i = (i > 0 ? Fix32_m_min : Fix32_m_max); }
+void Fix32_warning(_G_int32_t&)
+ { cerr << "warning: Fix32 result out of range\n"; }
+void Fix32_overflow_warning_saturate(_G_int32_t& i)
+ { cerr << "warning: Fix32 result out of range\n";
+ Fix32_overflow_saturate(i); }
+void Fix32_abort(_G_int32_t&)
+ { cerr << "error: Fix32 result out of range\n"; abort(); }
+
diff --git a/gnu/lib/libg++/libg++/src/Fix16.h b/gnu/lib/libg++/libg++/src/Fix16.h
new file mode 100644
index 00000000000..7f1336b308c
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)((_G_uint32_t)(1 << 31)))
+
+#define Fix32_msb ((_G_uint32_t)(1 << 31))
+#define Fix32_m_max ((_G_int32_t)((1 << 31) - 1))
+#define Fix32_m_min ((_G_int32_t)(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;
+
+ _G_int32_t m;
+
+ _G_int32_t round(double d);
+ _G_int32_t assign(double d);
+
+ Fix32(_G_int32_t 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 _G_int32_t& mantissa(Fix32& f);
+ friend const _G_int32_t& 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(_G_int32_t& i) const;
+ void range_error(_G_int32_t& 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)(_G_int32_t&);
+
+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(_G_int32_t&),
+ Fix32_overflow_saturate(_G_int32_t&),
+ Fix32_overflow_warning_saturate(_G_int32_t&),
+ Fix32_warning(_G_int32_t&),
+ Fix32_abort(_G_int32_t&);
+
+
+inline Fix16::~Fix16() {}
+
+inline Fix32::~Fix32() {}
+
+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(_G_int32_t 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 = _G_int32_t(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 = _G_int32_t(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( _G_int32_t( _G_int32_t(f.m) * _G_int32_t(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 _G_int32_t Fix32::round(double d)
+{
+ return _G_int32_t( (d >= 0)? d + 0.5 : d - 0.5);
+}
+
+inline _G_int32_t& mantissa(Fix32& f)
+{
+ return f.m;
+}
+
+inline const _G_int32_t& 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)
+{
+ _G_int32_t 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)
+{
+ _G_int32_t 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(_G_int32_t(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++/libg++/src/Fix24.cc b/gnu/lib/libg++/libg++/src/Fix24.cc
new file mode 100644
index 00000000000..41878bb7c5e
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Fix24.cc
@@ -0,0 +1,329 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+//
+// Fix24.cc : fixed precision class support functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Fix24.h>
+
+// basic operators too large to be inline
+
+_G_int32_t Fix24::assign(double d)
+{
+ if (d == 1.0)
+ return Fix24_m_max;
+ else if (d > Fix24_max)
+ {
+ _G_int32_t i = Fix24_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix24_min)
+ {
+ _G_int32_t i = Fix24_m_min;
+ range_error(i);
+ return i;
+ }
+ else {
+ // Round to 24 bits
+ d = (_G_int32_t) (d * (1 << 24) + ((d >= 0)? 0.5 : -0.5));
+ /* Convert to integer format */
+ return ((_G_int32_t) d) << (Fix24_shift - 24);
+ }
+}
+
+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 = ((_G_int32_t)(d *= Fix24_mult)) & 0xffffff00;
+ i.l = ((_G_uint32_t)((d - i.u)* (Fix24_mult / (1 << 7)))) & 0xffffff00;
+
+/* Calculate the two's complement if d was negative */
+ if (sign) {
+ _G_uint32_t oldlower = i.l;
+ i.l = (~i.l + 1) & 0xffffff00;
+ i.u = (~i.u + (((oldlower ^ i.l) & Fix24_msb)? 0 : 1)) & ~0xffL;
+ }
+ 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);
+ _G_uint32_t ua = (apos)? a.m : - a.m;
+ ua <<= 1; // ua is biased so result will be 47 bit mantissa, not 46:
+ _G_uint32_t hi_a = (ua >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_a = ua & ((1 << 16) - 1);
+
+ int bpos = (b.m >= 0);
+ _G_uint32_t ub = (bpos)? b.m : -b.m;
+ _G_uint32_t hi_b = (ub >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_b = ub & ((1 << 16) - 1);
+
+ _G_uint32_t
+ 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 ) {
+ _G_uint32_t 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)
+{
+ _G_int32_t q;
+ int apos = (a.m >= 0);
+ _G_uint32_t la = (apos)? a.m : -a.m;
+ int bpos = (b.m >= 0);
+ _G_uint32_t 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;
+ _G_int32_t 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)
+{
+ _G_int32_t 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 {
+ _G_uint32_t
+ 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 ) {
+ _G_uint32_t l = r.l;
+ r.l = -r.l & 0xffffffff;
+ 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)) & 0xffffffffL) + ((a.m.l >> b) & 0xffffff00L);
+ r.u = (a.m.u >> b) & ~0xffL;
+ }
+ else if ( b < 48 ) {
+ r.l = (a.m.u >> (b - 24)) & 0xffffff00L;
+ r.u = (a.m.u >> 24) & ~0xffL;
+ }
+ else {
+ r.l = (a.m.u >> 24) & ~0xffL;
+ r.u = r.l;
+ }
+ return r;
+}
+
+// error handling
+
+void Fix24::overflow(_G_int32_t& i) const
+{
+ (*Fix24_overflow_handler)(i);
+}
+
+void Fix48::overflow(twolongs& i) const
+{
+ (*Fix48_overflow_handler)(i);
+}
+
+void Fix24::range_error(_G_int32_t& 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(_G_int32_t& i)
+ { i = (i > 0 ? Fix24_m_min : Fix24_m_max); }
+void Fix24_ignore(_G_int32_t&) {}
+void Fix24_warning(_G_int32_t&)
+ { cerr << "warning: Fix24 result out of range\n"; }
+void Fix24_overflow_warning_saturate(_G_int32_t& i)
+ { cerr << "warning: Fix24 result out of range\n";
+ Fix24_overflow_saturate(i); }
+void Fix24_abort(_G_int32_t&)
+ { 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++/src/Fix24.h b/gnu/lib/libg++/libg++/src/Fix24.h
new file mode 100644
index 00000000000..215ded96af0
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _Fix24_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Fix24_h 1
+
+#include <stream.h>
+#include <std.h>
+
+// extra type definitions
+
+typedef struct {
+ _G_int32_t u;
+ _G_uint32_t 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 _G_uint32_t
+ 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;
+
+ _G_int32_t m;
+
+ _G_int32_t 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 _G_int32_t& mantissa(Fix24& f);
+ friend const _G_int32_t& 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(_G_int32_t&) const;
+ void range_error(_G_int32_t&) 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)(_G_int32_t&);
+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(_G_int32_t&),
+ Fix24_overflow_saturate(_G_int32_t&),
+ Fix24_overflow_warning_saturate(_G_int32_t&),
+ Fix24_warning(_G_int32_t&),
+ Fix24_abort(_G_int32_t&);
+
+extern void
+ Fix48_ignore(twolongs&),
+ Fix48_overflow_saturate(twolongs&),
+ Fix48_overflow_warning_saturate(twolongs&),
+ Fix48_warning(twolongs&),
+ Fix48_abort(twolongs&);
+
+
+inline Fix24::~Fix24() {}
+
+inline Fix48::~Fix48() {}
+
+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 _G_int32_t& mantissa(Fix24& f)
+{
+ return f.m;
+}
+
+inline const _G_int32_t& 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)
+{
+ _G_int32_t 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)
+{
+ _G_int32_t 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) & ~0xff;
+}
+
+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(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 * ((_G_uint32_t)(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++/libg++/src/Geom.cc b/gnu/lib/libg++/libg++/src/Geom.cc
new file mode 100644
index 00000000000..3e6372e5978
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Geom.h b/gnu/lib/libg++/libg++/src/Geom.h
new file mode 100644
index 00000000000..064849ab8e6
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/GetOpt.cc b/gnu/lib/libg++/libg++/src/GetOpt.cc
new file mode 100644
index 00000000000..8dc54a1fe60
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/GetOpt.h b/gnu/lib/libg++/libg++/src/GetOpt.h
new file mode 100644
index 00000000000..c554cac8321
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/HypGeom.cc b/gnu/lib/libg++/libg++/src/HypGeom.cc
new file mode 100644
index 00000000000..a283caddbc1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/HypGeom.h b/gnu/lib/libg++/libg++/src/HypGeom.h
new file mode 100644
index 00000000000..0aeeb7d78ee
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Incremental.h b/gnu/lib/libg++/libg++/src/Incremental.h
new file mode 100644
index 00000000000..267970a8cfb
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Incremental.h
@@ -0,0 +1,12 @@
+#ifndef Incremental_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define Incremental_h
+#define DECLARE_INIT_FUNCTION(USER_INIT_FUNCTION) \
+static void USER_INIT_FUNCTION (); extern void (*_initfn)(); \
+static struct xyzzy { xyzzy () {_initfn = USER_INIT_FUNCTION;}; \
+~xyzzy () {};} __2xyzzy;
+#else
+#error Incremental.h was not the first file included in this module
+#endif
diff --git a/gnu/lib/libg++/libg++/src/Intdouble.cc b/gnu/lib/libg++/libg++/src/Intdouble.cc
new file mode 100644
index 00000000000..065175b967a
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Integer.cc b/gnu/lib/libg++/libg++/src/Integer.cc
new file mode 100644
index 00000000000..926b28ace68
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Integer.cc
@@ -0,0 +1,2282 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ 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"
+
+#undef OK
+
+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 = new (operator new (allocsiz)) IntRep;
+ 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 (int 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++/src/Integer.h b/gnu/lib/libg++/libg++/src/Integer.h
new file mode 100644
index 00000000000..f2e9b160a63
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Integer.h
@@ -0,0 +1,1121 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _Integer_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Integer_h 1
+
+#include <iostream.h>
+
+#undef OK
+
+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++/libg++/src/Integer.hP b/gnu/lib/libg++/libg++/src/Integer.hP
new file mode 100644
index 00000000000..b8a80394265
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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++/libg++/src/LogNorm.cc b/gnu/lib/libg++/libg++/src/LogNorm.cc
new file mode 100644
index 00000000000..446a9fe7f84
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/LogNorm.h b/gnu/lib/libg++/libg++/src/LogNorm.h
new file mode 100644
index 00000000000..18fc1f11d23
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/MLCG.cc b/gnu/lib/libg++/libg++/src/MLCG.cc
new file mode 100644
index 00000000000..8e624772f34
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
+}
+
+_G_uint32_t 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++/src/MLCG.h b/gnu/lib/libg++/libg++/src/MLCG.h
new file mode 100644
index 00000000000..0ae817cd777
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 _G_uint32_t 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++/libg++/src/Makefile b/gnu/lib/libg++/libg++/src/Makefile
new file mode 100644
index 00000000000..f0a7aba04f1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Makefile
@@ -0,0 +1,25 @@
+# $NetBSD: Makefile,v 1.1.1.1 1996/03/09 00:01:20 phil Exp $
+
+LIB= g++
+
+SRCS= ACG.cc AllocRing.cc Binomial.cc BitSet.cc BitString.cc CursesW.cc \
+DLList.cc DiscUnif.cc Erlang.cc Fix.cc Fix16.cc Fix24.cc \
+Geom.cc GetOpt.cc HypGeom.cc Intdouble.cc Integer.cc LogNorm.cc \
+MLCG.cc NegExp.cc Normal.cc Obstack.cc Poisson.cc RNG.cc \
+Random.cc Rational.cc Regex.cc RndInt.cc SLList.cc SmplHist.cc \
+SmplStat.cc String.cc Uniform.cc Weibull.cc bitand.c bitany.c \
+bitblt.c bitclear.c bitcopy.c bitcount.c bitinvert.c bitlcomp.c \
+bitset1.c bitxor.c builtin.cc chr.cc compare.cc error.cc \
+fmtq.cc gcd.cc hash.cc ioob.cc lg.cc pow.cc \
+sqrt.cc str.cc timer.c
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../../include \
+ -I$(.CURDIR)/../../libio -I$(.CURDIR)/../../libstdc++
+CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../../libio
+LDADD= ${DESTDIR}/usr/lib/c++rt0.o -lcurses
+DPADD= ${DESTDIR}/usr/lib/c++rt0.o ${LIBCURSES}
+NOMAN= noman
+LIBCURSES!= printf "xxx:\n\techo \$${LIBCURSES}\n.include <bsd.prog.mk>" |\
+ $(MAKE) -r -s -f - xxx | grep curses
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libg++/libg++/src/NegExp.cc b/gnu/lib/libg++/libg++/src/NegExp.cc
new file mode 100644
index 00000000000..f07769aff60
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/NegExp.h b/gnu/lib/libg++/libg++/src/NegExp.h
new file mode 100644
index 00000000000..08f17afde95
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Normal.cc b/gnu/lib/libg++/libg++/src/Normal.cc
new file mode 100644
index 00000000000..29219b4a730
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Normal.h b/gnu/lib/libg++/libg++/src/Normal.h
new file mode 100644
index 00000000000..5e19f7ae606
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Obstack.cc b/gnu/lib/libg++/libg++/src/Obstack.cc
new file mode 100644
index 00000000000..abef732979f
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Obstack.cc
@@ -0,0 +1,127 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <limits.h>
+#include <builtin.h>
+#include <Obstack.h>
+#include <new.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 = new (operator new (new_size)) _obstack_chunk;
+ 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
+{
+ _obstack_chunk* ch;
+ for (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++/src/Obstack.h b/gnu/lib/libg++/libg++/src/Obstack.h
new file mode 100644
index 00000000000..8dd9d09c91b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Obstack.h
@@ -0,0 +1,218 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _Obstack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Obstack_h 1
+
+#include <std.h>
+
+#undef OK
+
+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++/libg++/src/Pix.h b/gnu/lib/libg++/libg++/src/Pix.h
new file mode 100644
index 00000000000..be90525c631
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Pix.h
@@ -0,0 +1,5 @@
+
+#ifndef _Pix_h
+#define _Pix_h 1
+typedef void* Pix;
+#endif
diff --git a/gnu/lib/libg++/libg++/src/Poisson.cc b/gnu/lib/libg++/libg++/src/Poisson.cc
new file mode 100644
index 00000000000..b7fac8f5ca3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Poisson.h b/gnu/lib/libg++/libg++/src/Poisson.h
new file mode 100644
index 00000000000..2566de5aa50
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/RNG.cc b/gnu/lib/libg++/libg++/src/RNG.cc
new file mode 100644
index 00000000000..81f55a07f8c
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/RNG.h b/gnu/lib/libg++/libg++/src/RNG.h
new file mode 100644
index 00000000000..cb3fbfb1732
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 _G_uint32_t 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++/libg++/src/Random.cc b/gnu/lib/libg++/libg++/src/Random.cc
new file mode 100644
index 00000000000..572a602cf7a
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Random.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Random.h>
diff --git a/gnu/lib/libg++/libg++/src/Random.h b/gnu/lib/libg++/libg++/src/Random.h
new file mode 100644
index 00000000000..2a6d0ee54a3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Rational.cc b/gnu/lib/libg++/libg++/src/Rational.cc
new file mode 100644
index 00000000000..07bcd4f1d17
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Rational.cc
@@ -0,0 +1,416 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Rational.h>
+#include <std.h>
+#include <math.h>
+#include <builtin.h>
+#include <float.h>
+
+#undef OK
+
+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++/src/Rational.h b/gnu/lib/libg++/libg++/src/Rational.h
new file mode 100644
index 00000000000..6542c49f9e4
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Rational.h
@@ -0,0 +1,290 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _Rational_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Rational_h 1
+
+#include <Integer.h>
+#include <math.h>
+
+#undef OK
+
+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++/libg++/src/Regex.cc b/gnu/lib/libg++/libg++/src/Regex.cc
new file mode 100644
index 00000000000..1c27dd0e028
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Regex.cc
@@ -0,0 +1,140 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ Regex class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <ctype.h>
+#include <new.h>
+#include <builtin.h>
+
+extern "C" {
+#if 1
+#include <rx.h>
+#else
+#include <regex.h>
+#endif
+}
+
+#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;
+ memset (buf, 0, sizeof(re_pattern_buffer));
+ reg = new re_registers;
+ if (fast)
+ buf->fastmap = (char*)malloc(256);
+ else
+ buf->fastmap = 0;
+ buf->translate = (unsigned char*)transtable;
+ if (tlen > bufsize)
+ bufsize = tlen;
+ buf->allocated = bufsize;
+ buf->buffer = (char *)malloc(buf->allocated);
+ const 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++/src/Regex.h b/gnu/lib/libg++/libg++/src/Regex.h
new file mode 100644
index 00000000000..47f9a853a33
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/Regex.h
@@ -0,0 +1,78 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _Regex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Regex_h 1
+
+#undef OK
+
+#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++/libg++/src/RndInt.cc b/gnu/lib/libg++/libg++/src/RndInt.cc
new file mode 100644
index 00000000000..c09f1e504d3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/RndInt.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <RndInt.h>
diff --git a/gnu/lib/libg++/libg++/src/RndInt.h b/gnu/lib/libg++/libg++/src/RndInt.h
new file mode 100644
index 00000000000..7a73aee1c0b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/RndInt.h
@@ -0,0 +1,176 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
+ : pGenerator(gen),
+ pLow((low < high) ? low : high),
+ pHigh((low < high) ? high : low)
+
+{}
+
+inline RandomInteger::RandomInteger(long high, RNG *gen)
+ : pGenerator(gen),
+ pLow((0 < high) ? 0 : high),
+ pHigh((0 < high) ? high : 0)
+{}
+
+
+inline RandomInteger::RandomInteger(RNG *gen)
+ : pGenerator(gen),
+ pLow(0),
+ pHigh(1)
+{}
+
+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++/libg++/src/SLList.cc b/gnu/lib/libg++/libg++/src/SLList.cc
new file mode 100644
index 00000000000..564e5997bde
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) const
+{
+ (*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) const
+{
+ 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() const
+{
+ 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++/src/SLList.h b/gnu/lib/libg++/libg++/src/SLList.h
new file mode 100644
index 00000000000..072f249fe1d
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/SLList.h
@@ -0,0 +1,129 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _SLList_h
+#ifdef __GNUG__
+//#pragma interface
+#endif
+#define _SLList_h 1
+
+#undef OK
+
+#include <Pix.h>
+
+struct BaseSLNode
+{
+ union {
+ struct BaseSLNode *tl;
+ double dummy; /* To force correct alignment */
+ };
+ 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() const;
+ void error(const char* msg) const;
+ void del_after(Pix p);
+ int owns(Pix p) const;
+ 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; }
+ const T& operator () (Pix p) const {
+ if (p == 0) error("null Pix");
+ return ((SLNode<T>*)(p))->hd; }
+ inline Pix first() const { return (last == 0) ? 0 : Pix(last->tl); }
+ void next(Pix& p) const
+ { 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; }
+ const T& front() const {
+ if (last == 0) error("front: empty list");
+ return ((SLNode<T>*)last->tl)->hd; }
+ const T& rear() const {
+ 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++/libg++/src/SmplHist.cc b/gnu/lib/libg++/libg++/src/SmplHist.cc
new file mode 100644
index 00000000000..5dbe2c79327
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/SmplHist.h b/gnu/lib/libg++/libg++/src/SmplHist.h
new file mode 100644
index 00000000000..959d6d4bc7a
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/SmplStat.cc b/gnu/lib/libg++/libg++/src/SmplStat.cc
new file mode 100644
index 00000000000..9db3caa845d
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/SmplStat.h b/gnu/lib/libg++/libg++/src/SmplStat.h
new file mode 100644
index 00000000000..441692f8c7b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/SmplStat.h
@@ -0,0 +1,69 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#ifndef SampleStatistic_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define SampleStatistic_h 1
+
+#include <builtin.h>
+
+#undef min
+#undef max
+
+class SampleStatistic {
+protected:
+ int n;
+ double x;
+ double x2;
+ double minValue, maxValue;
+
+ public :
+
+ SampleStatistic();
+ inline 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++/libg++/src/String.cc b/gnu/lib/libg++/libg++/src/String.cc
new file mode 100644
index 00000000000..6ab515ca939
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/String.cc
@@ -0,0 +1,1307 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ 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>
+
+#undef OK
+
+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 = new (operator new (allocsiz)) StrRep;
+ 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
+
+static 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;
+}
+
+void
+String::alloc (int newsize)
+{
+ unsigned short old_len = rep->len;
+ rep = Sresize(rep, newsize);
+ rep->len = old_len;
+}
+
+// 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)
+#define RETURN(r) return
+#define RETURNS(r) return r;
+#define RETURN_OBJECT(TYPE, NAME) /* nothing */
+#else /* _G_NO_NRV */
+#define RETURN(r) return r
+#define RETURNS(r) /* nothing */
+#define RETURN_OBJECT(TYPE, NAME) TYPE NAME;
+#endif
+
+String join(String src[], int n, const String& separator) RETURNS(x)
+{
+ RETURN_OBJECT(String,x)
+ String sep = separator;
+ int xlen = 0;
+ int i;
+ for (i = 0; i < n; ++i)
+ xlen += src[i].length();
+ xlen += (n - 1) * sep.length();
+
+ x.rep = Sresize (x.rep, 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);
+}
+
+/*
+ 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()]);
+ int l;
+ for (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;
+ int l;
+ for (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()]);
+ int l;
+ for (int l; 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;
+ int l;
+ for (int l; 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++/src/String.h b/gnu/lib/libg++/libg++/src/String.h
new file mode 100644
index 00000000000..b3bfd707cf3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/String.h
@@ -0,0 +1,1284 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef _String_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _String_h 1
+
+#include <iostream.h>
+#include <Regex.h>
+
+#undef OK
+
+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* 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 inline void cat(const String&, const String&, String&);
+ friend inline void cat(const String&, const SubString&, String&);
+ friend inline void cat(const String&, const char*, String&);
+ friend inline void cat(const String&, char, String&);
+
+ friend inline void cat(const SubString&, const String&, String&);
+ friend inline void cat(const SubString&, const SubString&, String&);
+ friend inline void cat(const SubString&, const char*, String&);
+ friend inline void cat(const SubString&, char, String&);
+
+ friend inline void cat(const char*, const String&, String&);
+ friend inline void cat(const char*, const SubString&, String&);
+ friend inline void cat(const char*, const char*, String&);
+ friend inline 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 inline void cat(const String&,const String&, const String&,String&);
+ friend inline void cat(const String&,const String&,const SubString&,String&);
+ friend inline void cat(const String&,const String&, const char*, String&);
+ friend inline void cat(const String&,const String&, char, String&);
+ friend inline void cat(const String&,const SubString&,const String&,String&);
+ inline friend void cat(const String&,const SubString&,const SubString&,String&);
+ friend inline void cat(const String&,const SubString&, const char*, String&);
+ friend inline void cat(const String&,const SubString&, char, String&);
+ friend inline void cat(const String&,const char*, const String&, String&);
+ friend inline void cat(const String&,const char*, const SubString&, String&);
+ friend inline void cat(const String&,const char*, const char*, String&);
+ friend inline void cat(const String&,const char*, char, String&);
+
+ friend inline void cat(const char*, const String&, const String&,String&);
+ friend inline void cat(const char*,const String&,const SubString&,String&);
+ friend inline void cat(const char*,const String&, const char*, String&);
+ friend inline void cat(const char*,const String&, char, String&);
+ friend inline void cat(const char*,const SubString&,const String&,String&);
+ friend inline void cat(const char*,const SubString&,const SubString&,String&);
+ friend inline void cat(const char*,const SubString&, const char*, String&);
+ friend inline void cat(const char*,const SubString&, char, String&);
+ friend inline void cat(const char*,const char*, const String&, String&);
+ friend inline void cat(const char*,const char*, const SubString&, String&);
+ friend inline void cat(const char*,const char*, const char*, String&);
+ friend inline 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 inline String reverse(const String& x);
+ friend inline String upcase(const String& x);
+ friend inline String downcase(const String& x);
+ friend inline String capitalize(const String& x);
+
+// in-place versions of above
+
+ void reverse();
+ void upcase();
+ void downcase();
+ void capitalize();
+
+// element extraction
+
+ char& operator [] (int i);
+ const char& operator [] (int i) const;
+ char elem(int i) const;
+ char firstchar() const;
+ char lastchar() const;
+
+// conversion
+
+ operator const char*() const;
+ const char* chars() const;
+
+
+// IO
+
+ friend inline 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;
+
+// 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 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 const char& String::operator [] (int i) const
+{
+ 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++/libg++/src/Uniform.cc b/gnu/lib/libg++/libg++/src/Uniform.cc
new file mode 100644
index 00000000000..0592b6d9781
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Uniform.h b/gnu/lib/libg++/libg++/src/Uniform.h
new file mode 100644
index 00000000000..1a365b9a774
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/Weibull.cc b/gnu/lib/libg++/libg++/src/Weibull.cc
new file mode 100644
index 00000000000..d7987f5ece0
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/Weibull.h b/gnu/lib/libg++/libg++/src/Weibull.h
new file mode 100644
index 00000000000..fd064d5e619
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/bitand.c b/gnu/lib/libg++/libg++/src/bitand.c
new file mode 100644
index 00000000000..149a8ab7386
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include "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++/src/bitany.c b/gnu/lib/libg++/libg++/src/bitany.c
new file mode 100644
index 00000000000..5a978d030d9
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com) */
+
+#include "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++/src/bitblt.c b/gnu/lib/libg++/libg++/src/bitblt.c
new file mode 100644
index 00000000000..b38fd3d9eb1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com).
+ 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++/src/bitclear.c b/gnu/lib/libg++/libg++/src/bitclear.c
new file mode 100644
index 00000000000..6dd94059ad6
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com) */
+
+#include "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++/src/bitcopy.c b/gnu/lib/libg++/libg++/src/bitcopy.c
new file mode 100644
index 00000000000..aa48730e8d6
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include "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++/src/bitcount.c b/gnu/lib/libg++/libg++/src/bitcount.c
new file mode 100644
index 00000000000..9583a827e4a
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com) */
+
+#include "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++/src/bitdo1.h b/gnu/lib/libg++/libg++/src/bitdo1.h
new file mode 100644
index 00000000000..c234d41d406
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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++/libg++/src/bitdo2.h b/gnu/lib/libg++/libg++/src/bitdo2.h
new file mode 100644
index 00000000000..6e995235372
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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++/libg++/src/bitinvert.c b/gnu/lib/libg++/libg++/src/bitinvert.c
new file mode 100644
index 00000000000..558c397838c
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com) */
+
+#include "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++/src/bitlcomp.c b/gnu/lib/libg++/libg++/src/bitlcomp.c
new file mode 100644
index 00000000000..8b52943aa72
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/bitlcomp.c
@@ -0,0 +1,81 @@
+/* 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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com) */
+
+#include "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;
+ _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
+ {
+ _BS_word diff=(word0^word1); /* one's where different */
+ _BS_word mask=diff&~(diff-1); /* first bit different */
+ return (word0&mask)?1:-1;
+ }
+#endif
+ }
+ }
+ len0 -= nwords0 * _BS_BITS_PER_WORD;
+ len1 -= nwords1 * _BS_BITS_PER_WORD;
+ if (len0 == 0 || len1 == 0)
+ return (len1 == 0) - (len0 == 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
+ {
+ _BS_word diff=(word0^word1); /* one's where different */
+ _BS_word mask=diff&~(diff-1); /* first bit different */
+ return (word0&mask)?1:-1;
+ }
+#endif
+}
+
diff --git a/gnu/lib/libg++/libg++/src/bitprims.h b/gnu/lib/libg++/libg++/src/bitprims.h
new file mode 100644
index 00000000000..737562dce89
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/bitprims.h
@@ -0,0 +1,124 @@
+#ifndef _BS_PRIMS
+#define _BS_PRIMS
+
+/* A bitstring is an array of _BS_word. */
+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) ((_BS_word)1 << (_BS_BITS_PER_WORD - 1 - (BITNO)))
+#else
+#define _BS_BITMASK(BITNO) ((_BS_word)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
+#if __GNUC__ > 1
+#define _BS_size_t __SIZE_TYPE__
+#else
+#define _BS_size_t unsigned long
+#endif
+#endif
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(protos) protos
+#else
+#define __P(protos) ()
+#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++/libg++/src/bitset1.c b/gnu/lib/libg++/libg++/src/bitset1.c
new file mode 100644
index 00000000000..bf0dd8de1e1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com) */
+
+#include "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++/src/bitxor.c b/gnu/lib/libg++/libg++/src/bitxor.c
new file mode 100644
index 00000000000..7690419036e
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include "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++/src/bool.h b/gnu/lib/libg++/libg++/src/bool.h
new file mode 100644
index 00000000000..40a2956e6e5
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/bool.h
@@ -0,0 +1,24 @@
+// Defining TRUE and FALSE is usually a Bad Idea,
+// because you will probably be inconsistent with anyone
+// else who had the same clever idea.
+// Therefore: DON'T USE THIS FILE.
+
+#ifndef _bool_h
+#define _bool_h 1
+
+#include <_G_config.h>
+
+#if _G_HAVE_BOOL
+#undef TRUE
+#undef FALSE
+#define TRUE true
+#define FALSE false
+#else
+#undef FALSE
+#undef TRUE
+#undef true
+#undef false
+enum bool { FALSE = 0, false = 0, TRUE = 1, true = 1 };
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/libg++/src/builtin.cc b/gnu/lib/libg++/libg++/src/builtin.cc
new file mode 100644
index 00000000000..6b9abe5380c
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/builtin.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
diff --git a/gnu/lib/libg++/libg++/src/builtin.h b/gnu/lib/libg++/libg++/src/builtin.h
new file mode 100644
index 00000000000..8d380828d77
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/builtin.h
@@ -0,0 +1,125 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <cmath>
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#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 void default_one_arg_error_handler(const char*) __attribute__ ((noreturn));
+extern void default_two_arg_error_handler(const char*, const char*) __attribute__ ((noreturn));
+
+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);
+
+
+#if !defined(IV)
+
+inline short abs(short 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++/libg++/src/chr.cc b/gnu/lib/libg++/libg++/src/chr.cc
new file mode 100644
index 00000000000..5c112d8217f
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/compare.cc b/gnu/lib/libg++/libg++/src/compare.cc
new file mode 100644
index 00000000000..aae8409a2aa
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/compare.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <compare.h>
diff --git a/gnu/lib/libg++/libg++/src/compare.h b/gnu/lib/libg++/libg++/src/compare.h
new file mode 100644
index 00000000000..fb720749873
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/libg++/src/error.cc b/gnu/lib/libg++/libg++/src/error.cc
new file mode 100644
index 00000000000..7d163d67631
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/error.cc
@@ -0,0 +1,49 @@
+/*
+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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+void default_one_arg_error_handler(const char* msg)
+{
+ fputs("Error: ", stderr);
+ fputs(msg, stderr);
+ fputs("\n", stderr);
+ abort();
+}
+
+
+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++/src/fmtq.cc b/gnu/lib/libg++/libg++/src/fmtq.cc
new file mode 100644
index 00000000000..2a01073699b
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/gcd.cc b/gnu/lib/libg++/libg++/src/gcd.cc
new file mode 100644
index 00000000000..602b55f8796
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/generic.h b/gnu/lib/libg++/libg++/src/generic.h
new file mode 100644
index 00000000000..d49a924afd1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/generic.h
@@ -0,0 +1,54 @@
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef generic_h
+#define generic_h 1
+
+/*
+ * See the CPP manual, argument prescan section for explanation
+ */
+
+#define name2(a,b) gEnErIc2(a,b)
+#define gEnErIc2(a,b) a ## b
+
+#define name3(a,b,c) gEnErIc3(a,b,c)
+#define gEnErIc3(a,b,c) a ## b ## c
+
+#define name4(a,b,c,d) gEnErIc4(a,b,c,d)
+#define gEnErIc4(a,b,c,d) a ## b ## c ## d
+
+#define GENERIC_STRING(a) gEnErIcStRiNg(a)
+#define gEnErIcStRiNg(a) #a
+
+#define declare(clas,t) name2(clas,declare)(t)
+#define declare2(clas,t1,t2) name2(clas,declare2)(t1,t2)
+
+#define implement(clas,t) name2(clas,implement)(t)
+#define implement2(clas,t1,t2) name2(clas,implement2)(t1,t2)
+
+//extern genericerror(int,char*);
+typedef int (*GPT)(int,char*);
+
+#define set_handler(gen,type,x) name4(set_,type,gen,_handler)(x)
+
+#define errorhandler(gen,type) name3(type,gen,handler)
+
+#define callerror(gen,type,a,b) (*errorhandler(gen,type))(a,b)
+
+
+#endif /* generic_h */
diff --git a/gnu/lib/libg++/libg++/src/getpagesize.h b/gnu/lib/libg++/libg++/src/getpagesize.h
new file mode 100644
index 00000000000..17d84316bd5
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/getpagesize.h
@@ -0,0 +1,27 @@
+#if defined(BSD) || defined(DGUX)
+#ifndef BSD4_1
+#define HAVE_GETPAGESIZE
+#endif
+#endif
+
+#ifndef HAVE_GETPAGESIZE
+
+#include <sys/param.h>
+
+#ifdef EXEC_PAGESIZE
+#define getpagesize() EXEC_PAGESIZE
+#else
+#ifdef NBPG
+#define getpagesize() NBPG * CLSIZE
+#ifndef CLSIZE
+#define CLSIZE 1
+#endif /* no CLSIZE */
+#else /* no NBPG */
+#ifdef NBPC
+#define getpagesize() NBPC
+#endif /* NBPC */
+#endif /* no NBPG */
+#endif /* no EXEC_PAGESIZE */
+
+#endif /* not HAVE_GETPAGESIZE */
+
diff --git a/gnu/lib/libg++/libg++/src/hash.cc b/gnu/lib/libg++/libg++/src/hash.cc
new file mode 100644
index 00000000000..670e53f2bda
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/ioob.cc b/gnu/lib/libg++/libg++/src/ioob.cc
new file mode 100644
index 00000000000..08409a5d292
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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++/src/lg.cc b/gnu/lib/libg++/libg++/src/lg.cc
new file mode 100644
index 00000000000..0397dd43f01
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/libc.h b/gnu/lib/libg++/libg++/src/libc.h
new file mode 100644
index 00000000000..c8b49f26d17
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/libc.h
@@ -0,0 +1 @@
+#include <stdlib.h>
diff --git a/gnu/lib/libg++/libg++/src/minmax.h b/gnu/lib/libg++/libg++/src/minmax.h
new file mode 100644
index 00000000000..ec2bfa335a7
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/minmax.h
@@ -0,0 +1,65 @@
+/*
+Copyright (C) 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _minmax_h
+#ifdef _GNUG_
+#pragma interface
+#endif
+#define _minmax_h 1
+
+#include <_G_config.h>
+
+inline char min(char a, char b) { return (a < b)?a:b;}
+#ifndef _G_BROKEN_SIGNED_CHAR
+inline signed char min(signed char a, signed char b) { return (a < b)?a:b;}
+#endif
+inline unsigned char min(unsigned char a, unsigned char b) {return (a<b)?a:b;}
+
+inline short min(short a, short b) {return (a < b) ?a:b;}
+inline unsigned short min(unsigned short a, unsigned short b) {return (a < b)?a:b;}
+
+inline int min(int a, int b) {return (a < b)?a:b;}
+inline unsigned int min(unsigned int a, unsigned int b) {return (a < b)?a:b;}
+
+inline long min(long a, long b) {return (a < b)?a:b;}
+inline unsigned long min(unsigned long a, unsigned long b) {return (a<b)?a:b;}
+
+inline float min(float a, float b) {return (a < b)?a:b;}
+
+inline double min(double a, double b) {return (a < b)?a:b;}
+
+inline char max(char a, char b) { return (a > b)?a:b;}
+#ifndef _G_BROKEN_SIGNED_CHAR
+inline signed char max(signed char a, signed char b) {return (a > b)?a:b;}
+#endif
+inline unsigned char max(unsigned char a, unsigned char b) {return (a>b)?a:b;}
+
+inline short max(short a, short b) {return (a > b) ?a:b;}
+inline unsigned short max(unsigned short a, unsigned short b) {return (a > b)?a:b;}
+
+inline int max(int a, int b) {return (a > b)?a:b;}
+inline unsigned int max(unsigned int a, unsigned int b) {return (a > b)?a:b;}
+
+inline long max(long a, long b) {return (a > b)?a:b;}
+inline unsigned long max(unsigned long a, unsigned long b) {return (a>b)?a:b;}
+
+inline float max(float a, float b) {return (a > b)?a:b;}
+
+inline double max(double a, double b) {return (a > b)?a:b;}
+
+#endif
+
diff --git a/gnu/lib/libg++/libg++/src/osfcn.h b/gnu/lib/libg++/libg++/src/osfcn.h
new file mode 100644
index 00000000000..023b5c5b65d
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/osfcn.h
@@ -0,0 +1,17 @@
+
+#ifndef OSFCN_H
+#define OSFCN_H 1
+
+#include <std.h>
+#include <time.h>
+#include <sys/types.h>
+#if _G_HAVE_SYS_SOCKET
+#include <sys/socket.h>
+#endif
+#if _G_HAVE_SYS_RESOURCE
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+
+#endif
diff --git a/gnu/lib/libg++/libg++/src/pow.cc b/gnu/lib/libg++/libg++/src/pow.cc
new file mode 100644
index 00000000000..497cb5b8b70
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/rx.h b/gnu/lib/libg++/libg++/src/rx.h
new file mode 100644
index 00000000000..60f99e199e2
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/rx.h
@@ -0,0 +1,3732 @@
+#if !defined(RXH) || defined(RX_WANT_SE_DEFS)
+#define RXH
+
+/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of the librx library.
+
+Librx 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, or (at your option)
+any later version.
+
+Librx is distributed in the hope that 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 Library General Public
+License along with this software; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA
+02139, USA. */
+/* t. lord Wed Sep 23 18:20:57 1992 */
+
+
+
+
+
+
+
+
+#ifndef RX_WANT_SE_DEFS
+
+/* This page: Bitsets */
+
+#ifndef RX_subset
+typedef unsigned int RX_subset;
+#define RX_subset_bits (32)
+#define RX_subset_mask (RX_subset_bits - 1)
+#endif
+
+typedef RX_subset * rx_Bitset;
+
+#ifdef __STDC__
+typedef void (*rx_bitset_iterator) (void *, int member_index);
+#else
+typedef void (*rx_bitset_iterator) ();
+#endif
+
+#define rx_bitset_subset(N) ((N) / RX_subset_bits)
+#define rx_bitset_subset_val(B,N) ((B)[rx_bitset_subset(N)])
+#define RX_bitset_access(B,N,OP) \
+ ((B)[rx_bitset_subset(N)] OP rx_subset_singletons[(N) & RX_subset_mask])
+#define RX_bitset_member(B,N) RX_bitset_access(B, N, &)
+#define RX_bitset_enjoin(B,N) RX_bitset_access(B, N, |=)
+#define RX_bitset_remove(B,N) RX_bitset_access(B, N, &= ~)
+#define RX_bitset_toggle(B,N) RX_bitset_access(B, N, ^= )
+#define rx_bitset_numb_subsets(N) (((N) + RX_subset_bits - 1) / RX_subset_bits)
+#define rx_sizeof_bitset(N) (rx_bitset_numb_subsets(N) * sizeof(RX_subset))
+
+
+
+/* This page: Splay trees. */
+
+#ifdef __STDC__
+typedef int (*rx_sp_comparer) (void * a, void * b);
+#else
+typedef int (*rx_sp_comparer) ();
+#endif
+
+struct rx_sp_node
+{
+ void * key;
+ void * data;
+ struct rx_sp_node * kids[2];
+};
+
+#ifdef __STDC__
+typedef void (*rx_sp_key_data_freer) (struct rx_sp_node *);
+#else
+typedef void (*rx_sp_key_data_freer) ();
+#endif
+
+
+/* giant inflatable hash trees */
+
+struct rx_hash_item
+{
+ struct rx_hash_item * next_same_hash;
+ struct rx_hash * table;
+ unsigned long hash;
+ void * data;
+ void * binding;
+};
+
+struct rx_hash
+{
+ struct rx_hash * parent;
+ int refs;
+ struct rx_hash * children[13];
+ struct rx_hash_item * buckets [13];
+ int bucket_size [13];
+};
+
+struct rx_hash_rules;
+
+#ifdef __STDC__
+/* should return like == */
+typedef int (*rx_hash_eq)(void *, void *);
+typedef struct rx_hash * (*rx_alloc_hash)(struct rx_hash_rules *);
+typedef void (*rx_free_hash)(struct rx_hash *,
+ struct rx_hash_rules *);
+typedef struct rx_hash_item * (*rx_alloc_hash_item)(struct rx_hash_rules *,
+ void *);
+typedef void (*rx_free_hash_item)(struct rx_hash_item *,
+ struct rx_hash_rules *);
+#else
+typedef int (*rx_hash_eq)();
+typedef struct rx_hash * (*rx_alloc_hash)();
+typedef void (*rx_free_hash)();
+typedef struct rx_hash_item * (*rx_alloc_hash_item)();
+typedef void (*rx_free_hash_item)();
+#endif
+
+struct rx_hash_rules
+{
+ rx_hash_eq eq;
+ rx_alloc_hash hash_alloc;
+ rx_free_hash free_hash;
+ rx_alloc_hash_item hash_item_alloc;
+ rx_free_hash_item free_hash_item;
+};
+
+
+/* Forward declarations */
+
+struct rx_cache;
+struct rx_superset;
+struct rx;
+struct rx_se_list;
+
+
+
+/*
+ * GLOSSARY
+ *
+ * regexp
+ * regular expression
+ * expression
+ * pattern - a `regular' expression. The expression
+ * need not be formally regular -- it can contain
+ * constructs that don't correspond to purely regular
+ * expressions.
+ *
+ * buffer
+ * string - the string (or strings) being searched or matched.
+ *
+ * pattern buffer - a structure of type `struct re_pattern_buffer'
+ * This in turn contains a `struct rx', which holds the
+ * NFA compiled from a pattern, as well as some of the state
+ * of a matcher using the pattern.
+ *
+ * NFA - nondeterministic finite automata. Some people
+ * use this term to a member of the class of
+ * regular automata (those corresponding to a regular
+ * language). However, in this code, the meaning is
+ * more general. The automata used by Rx are comperable
+ * in power to what are usually called `push down automata'.
+ *
+ * Two NFA are built by rx for every pattern. One is built
+ * by the compiler. The other is built from the first, on
+ * the fly, by the matcher. The latter is called the `superstate
+ * NFA' because its states correspond to sets of states from
+ * the first NFA. (Joe Keane gets credit for the name
+ * `superstate NFA').
+ *
+ * NFA edges
+ * epsilon edges
+ * side-effect edges - The NFA compiled from a pattern can have three
+ * kinds of edges. Epsilon edges can be taken freely anytime
+ * their source state is reached. Character set edges can be
+ * taken when their source state is reached and when the next
+ * character in the buffer is a member of the set. Side effect
+ * edges imply a transition that can only be taken after the
+ * indicated side effect has been successfully accomplished.
+ * Some examples of side effects are:
+ *
+ * Storing the current match position to record the
+ * location of a parentesized subexpression.
+ *
+ * Advancing the matcher over N characters if they
+ * match the N characters previously matched by a
+ * parentesized subexpression.
+ *
+ * Both of those kinds of edges occur in the NFA generated
+ * by the pattern: \(.\)\1
+ *
+ * Epsilon and side effect edges are similar. Unfortunately,
+ * some of the code uses the name `epsilon edge' to mean
+ * both epsilon and side effect edges. For example, the
+ * function has_non_idempotent_epsilon_path computes the existance
+ * of a non-trivial path containing only a mix of epsilon and
+ * side effect edges. In that case `nonidempotent epsilon' is being
+ * used to mean `side effect'.
+ */
+
+
+
+
+
+/* LOW LEVEL PATTERN BUFFERS */
+
+/* Suppose that from some NFA state, more than one path through
+ * side-effect edges is possible. In what order should the paths
+ * be tried? A function of type rx_se_list_order answers that
+ * question. It compares two lists of side effects, and says
+ * which list comes first.
+ */
+
+#ifdef __STDC__
+typedef int (*rx_se_list_order) (struct rx *,
+ struct rx_se_list *,
+ struct rx_se_list *);
+#else
+typedef int (*rx_se_list_order) ();
+#endif
+
+
+
+/* Struct RX holds a compiled regular expression - that is, an nfa
+ * ready to be converted on demand to a more efficient superstate nfa.
+ * This is for the low level interface. The high-level interfaces enclose
+ * this in a `struct re_pattern_buffer'.
+ */
+struct rx
+{
+ /* The compiler assigns a unique id to every pattern.
+ * Like sequence numbers in X, there is a subtle bug here
+ * if you use Rx in a system that runs for a long time.
+ * But, because of the way the caches work out, it is almost
+ * impossible to trigger the Rx version of this bug.
+ *
+ * The id is used to validate superstates found in a cache
+ * of superstates. It isn't sufficient to let a superstate
+ * point back to the rx for which it was compiled -- the caller
+ * may be re-using a `struct rx' in which case the superstate
+ * is not really valid. So instead, superstates are validated
+ * by checking the sequence number of the pattern for which
+ * they were built.
+ */
+ int rx_id;
+
+ /* This is memory mgt. state for superstates. This may be
+ * shared by more than one struct rx.
+ */
+ struct rx_cache * cache;
+
+ /* Every regex defines the size of its own character set.
+ * A superstate has an array of this size, with each element
+ * a `struct rx_inx'. So, don't make this number too large.
+ * In particular, don't make it 2^16.
+ */
+ int local_cset_size;
+
+ /* After the NFA is built, it is copied into a contiguous region
+ * of memory (mostly for compatability with GNU regex).
+ * Here is that region, and it's size:
+ */
+ void * buffer;
+ unsigned long allocated;
+
+ /* Clients of RX can ask for some extra storage in the space pointed
+ * to by BUFFER. The field RESERVED is an input parameter to the
+ * compiler. After compilation, this much space will be available
+ * at (buffer + allocated - reserved)
+ */
+ unsigned long reserved;
+
+ /* --------- The remaining fields are for internal use only. --------- */
+ /* --------- But! they must be initialized to 0. --------- */
+
+ /* NODEC is the number of nodes in the NFA with non-epsilon
+ * transitions.
+ */
+ int nodec;
+
+ /* EPSNODEC is the number of nodes with only epsilon transitions. */
+ int epsnodec;
+
+ /* The sum (NODEC + EPSNODEC) is the total number of states in the
+ * compiled NFA.
+ */
+
+ /* Lists of side effects as stored in the NFA are `hash consed'..meaning
+ * that lists with the same elements are ==. During compilation,
+ * this table facilitates hash-consing.
+ */
+ struct rx_hash se_list_memo;
+
+ /* Lists of NFA states are also hashed.
+ */
+ struct rx_hash set_list_memo;
+
+
+
+
+ /* The compiler and matcher must build a number of instruction frames.
+ * The format of these frames is fixed (c.f. struct rx_inx). The values
+ * of the instructions is not fixed.
+ *
+ * An enumerated type (enum rx_opcode) defines the set of instructions
+ * that the compiler or matcher might generate. When filling an instruction
+ * frame, the INX field is found by indexing this instruction table
+ * with an opcode:
+ */
+ void ** instruction_table;
+
+ /* The list of all states in an NFA.
+ * During compilation, the NEXT field of NFA states links this list.
+ * After compilation, all the states are compacted into an array,
+ * ordered by state id numbers. At that time, this points to the base
+ * of that array.
+ */
+ struct rx_nfa_state *nfa_states;
+
+ /* Every nfa begins with one distinguished starting state:
+ */
+ struct rx_nfa_state *start;
+
+ /* This orders the search through super-nfa paths.
+ * See the comment near the typedef of rx_se_list_order.
+ */
+ rx_se_list_order se_list_cmp;
+
+ struct rx_superset * start_set;
+};
+
+
+
+
+/* SYNTAX TREES */
+
+/* Compilation is in stages.
+ *
+ * In the first stage, a pattern specified by a string is
+ * translated into a syntax tree. Later stages will convert
+ * the syntax tree into an NFA optimized for conversion to a
+ * superstate-NFA.
+ *
+ * This page is about syntax trees.
+ */
+
+enum rexp_node_type
+{
+ r_cset, /* Match from a character set. `a' or `[a-z]'*/
+ r_concat, /* Concat two subexpressions. `ab' */
+ r_alternate, /* Choose one of two subexpressions. `a\|b' */
+ r_opt, /* Optional subexpression. `a?' */
+ r_star, /* Repeated subexpression. `a*' */
+
+
+ /* A 2phase-star is a variation on a repeated subexpression.
+ * In this case, there are two subexpressions. The first, if matched,
+ * begins a repitition (otherwise, the whole expression is matches the
+ * empth string).
+ *
+ * After matching the first subexpression, a 2phase star either finishes,
+ * or matches the second subexpression. If the second subexpression is
+ * matched, then the whole construct repeats.
+ *
+ * 2phase stars are used in two circumstances. First, they
+ * are used as part of the implementation of POSIX intervals (counted
+ * repititions). Second, they are used to implement proper star
+ * semantics when the repeated subexpression contains paths of
+ * only side effects. See rx_compile for more information.
+ */
+ r_2phase_star,
+
+
+ /* c.f. "typedef void * rx_side_effect" */
+ r_side_effect,
+
+ /* This is an extension type: It is for transient use in source->source
+ * transformations (implemented over syntax trees).
+ */
+ r_data
+};
+
+/* A side effect is a matcher-specific action associated with
+ * transitions in the NFA. The details of side effects are up
+ * to the matcher. To the compiler and superstate constructors
+ * side effects are opaque:
+ */
+
+typedef void * rx_side_effect;
+
+/* Nodes in a syntax tree are of this type:
+ */
+struct rexp_node
+{
+ enum rexp_node_type type;
+ union
+ {
+ rx_Bitset cset;
+ rx_side_effect side_effect;
+ struct
+ {
+ struct rexp_node *left;
+ struct rexp_node *right;
+ } pair;
+ void * data;
+ } params;
+};
+
+
+
+/* NFA
+ *
+ * A syntax tree is compiled into an NFA. This page defines the structure
+ * of that NFA.
+ */
+
+struct rx_nfa_state
+{
+ /* These are kept in a list as the NFA is being built. */
+ struct rx_nfa_state *next;
+
+ /* After the NFA is built, states are given integer id's.
+ * States whose outgoing transitions are all either epsilon or
+ * side effect edges are given ids less than 0. Other states
+ * are given successive non-negative ids starting from 0.
+ */
+ int id;
+
+ /* The list of NFA edges that go from this state to some other. */
+ struct rx_nfa_edge *edges;
+
+ /* If you land in this state, then you implicitly land
+ * in all other states reachable by only epsilon translations.
+ * Call the set of maximal paths to such states the epsilon closure
+ * of this state.
+ *
+ * There may be other states that are reachable by a mixture of
+ * epsilon and side effect edges. Consider the set of maximal paths
+ * of that sort from this state. Call it the epsilon-side-effect
+ * closure of the state.
+ *
+ * The epsilon closure of the state is a subset of the epsilon-side-
+ * effect closure. It consists of all the paths that contain
+ * no side effects -- only epsilon edges.
+ *
+ * The paths in the epsilon-side-effect closure can be partitioned
+ * into equivalance sets. Two paths are equivalant if they have the
+ * same set of side effects, in the same order. The epsilon-closure
+ * is one of these equivalance sets. Let's call these equivalance
+ * sets: observably equivalant path sets. That name is chosen
+ * because equivalance of two paths means they cause the same side
+ * effects -- so they lead to the same subsequent observations other
+ * than that they may wind up in different target states.
+ *
+ * The superstate nfa, which is derived from this nfa, is based on
+ * the observation that all of the paths in an observably equivalant
+ * path set can be explored at the same time, provided that the
+ * matcher keeps track not of a single nfa state, but of a set of
+ * states. In particular, after following all the paths in an
+ * observably equivalant set, you wind up at a set of target states.
+ * That set of target states corresponds to one state in the
+ * superstate NFA.
+ *
+ * Staticly, before matching begins, it is convenient to analyze the
+ * nfa. Each state is labeled with a list of the observably
+ * equivalant path sets who's union covers all the
+ * epsilon-side-effect paths beginning in this state. This list is
+ * called the possible futures of the state.
+ *
+ * A trivial example is this NFA:
+ * s1
+ * A ---> B
+ *
+ * s2
+ * ---> C
+ *
+ * epsilon s1
+ * ---------> D ------> E
+ *
+ *
+ * In this example, A has two possible futures.
+ * One invokes the side effect `s1' and contains two paths,
+ * one ending in state B, the other in state E.
+ * The other invokes the side effect `s2' and contains only
+ * one path, landing in state C.
+ */
+ struct rx_possible_future *futures;
+
+
+ /* There are exactly two distinguished states in every NFA: */
+ unsigned int is_final:1;
+ unsigned int is_start:1;
+
+ /* These are used during NFA construction... */
+ unsigned int eclosure_needed:1;
+ unsigned int mark:1;
+};
+
+
+/* An edge in an NFA is typed: */
+enum rx_nfa_etype
+{
+ /* A cset edge is labled with a set of characters one of which
+ * must be matched for the edge to be taken.
+ */
+ ne_cset,
+
+ /* An epsilon edge is taken whenever its starting state is
+ * reached.
+ */
+ ne_epsilon,
+
+ /* A side effect edge is taken whenever its starting state is
+ * reached. Side effects may cause the match to fail or the
+ * position of the matcher to advance.
+ */
+ ne_side_effect /* A special kind of epsilon. */
+};
+
+struct rx_nfa_edge
+{
+ struct rx_nfa_edge *next;
+ enum rx_nfa_etype type;
+ struct rx_nfa_state *dest;
+ union
+ {
+ rx_Bitset cset;
+ rx_side_effect side_effect;
+ } params;
+};
+
+
+
+/* A possible future consists of a list of side effects
+ * and a set of destination states. Below are their
+ * representations. These structures are hash-consed which
+ * means that lists with the same elements share a representation
+ * (their addresses are ==).
+ */
+
+struct rx_nfa_state_set
+{
+ struct rx_nfa_state * car;
+ struct rx_nfa_state_set * cdr;
+};
+
+struct rx_se_list
+{
+ rx_side_effect car;
+ struct rx_se_list * cdr;
+};
+
+struct rx_possible_future
+{
+ struct rx_possible_future *next;
+ struct rx_se_list * effects;
+ struct rx_nfa_state_set * destset;
+};
+
+
+
+/* This begins the description of the superstate NFA.
+ *
+ * The superstate NFA corresponds to the NFA in these ways:
+ *
+ * Every superstate NFA states SUPER correspond to sets of NFA states,
+ * nfa_states(SUPER).
+ *
+ * Superstate edges correspond to NFA paths.
+ *
+ * The superstate has no epsilon transitions;
+ * every edge has a character label, and a (possibly empty) side
+ * effect label. The side effect label corresponds to a list of
+ * side effects that occur in the NFA. These parts are referred
+ * to as: superedge_character(EDGE) and superedge_sides(EDGE).
+ *
+ * For a superstate edge EDGE starting in some superstate SUPER,
+ * the following is true (in pseudo-notation :-):
+ *
+ * exists DEST in nfa_states s.t.
+ * exists nfaEDGE in nfa_edges s.t.
+ * origin (nfaEDGE) == DEST
+ * && origin (nfaEDGE) is a member of nfa_states(SUPER)
+ * && exists PF in possible_futures(dest(nfaEDGE)) s.t.
+ * sides_of_possible_future (PF) == superedge_sides (EDGE)
+ *
+ * also:
+ *
+ * let SUPER2 := superedge_destination(EDGE)
+ * nfa_states(SUPER2)
+ * == union of all nfa state sets S s.t.
+ * exists PF in possible_futures(dest(nfaEDGE)) s.t.
+ * sides_of_possible_future (PF) == superedge_sides (EDGE)
+ * && S == dests_of_possible_future (PF) }
+ *
+ * Or in english, every superstate is a set of nfa states. A given
+ * character and a superstate implies many transitions in the NFA --
+ * those that begin with an edge labeled with that character from a
+ * state in the set corresponding to the superstate.
+ *
+ * The destinations of those transitions each have a set of possible
+ * futures. A possible future is a list of side effects and a set of
+ * destination NFA states. Two sets of possible futures can be
+ * `merged' by combining all pairs of possible futures that have the
+ * same side effects. A pair is combined by creating a new future
+ * with the same side effect but the union of the two destination sets.
+ * In this way, all the possible futures suggested by a superstate
+ * and a character can be merged into a set of possible futures where
+ * no two elements of the set have the same set of side effects.
+ *
+ * The destination of a possible future, being a set of NFA states,
+ * corresponds to a supernfa state. So, the merged set of possible
+ * futures we just created can serve as a set of edges in the
+ * supernfa.
+ *
+ * The representation of the superstate nfa and the nfa is critical.
+ * The nfa has to be compact, but has to facilitate the rapid
+ * computation of missing superstates. The superstate nfa has to
+ * be fast to interpret, lazilly constructed, and bounded in space.
+ *
+ * To facilitate interpretation, the superstate data structures are
+ * peppered with `instruction frames'. There is an instruction set
+ * defined below which matchers using the supernfa must be able to
+ * interpret.
+ *
+ * We'd like to make it possible but not mandatory to use code
+ * addresses to represent instructions (c.f. gcc's computed goto).
+ * Therefore, we define an enumerated type of opcodes, and when
+ * writing one of these instructions into a data structure, use
+ * the opcode as an index into a table of instruction values.
+ *
+ * Here are the opcodes that occur in the superstate nfa:
+ */
+
+
+/* Every superstate contains a table of instruction frames indexed
+ * by characters. A normal `move' in a matcher is to fetch the next
+ * character and use it as an index into a superstates transition
+ * table.
+ *
+ * In the fasted case, only one edge follows from that character.
+ * In other cases there is more work to do.
+ *
+ * The descriptions of the opcodes refer to data structures that are
+ * described further below.
+ */
+
+enum rx_opcode
+{
+ /*
+ * BACKTRACK_POINT is invoked when a character transition in
+ * a superstate leads to more than one edge. In that case,
+ * the edges have to be explored independently using a backtracking
+ * strategy.
+ *
+ * A BACKTRACK_POINT instruction is stored in a superstate's
+ * transition table for some character when it is known that that
+ * character crosses more than one edge. On encountering this
+ * instruction, the matcher saves enough state to backtrack to this
+ * point in the match later.
+ */
+ rx_backtrack_point = 0, /* data is (struct transition_class *) */
+
+ /*
+ * RX_DO_SIDE_EFFECTS evaluates the side effects of an epsilon path.
+ * There is one occurence of this instruction per rx_distinct_future.
+ * This instruction is skipped if a rx_distinct_future has no side effects.
+ */
+ rx_do_side_effects = rx_backtrack_point + 1,
+
+ /* data is (struct rx_distinct_future *) */
+
+ /*
+ * RX_CACHE_MISS instructions are stored in rx_distinct_futures whose
+ * destination superstate has been reclaimed (or was never built).
+ * It recomputes the destination superstate.
+ * RX_CACHE_MISS is also stored in a superstate transition table before
+ * any of its edges have been built.
+ */
+ rx_cache_miss = rx_do_side_effects + 1,
+ /* data is (struct rx_distinct_future *) */
+
+ /*
+ * RX_NEXT_CHAR is called to consume the next character and take the
+ * corresponding transition. This is the only instruction that uses
+ * the DATA field of the instruction frame instead of DATA_2.
+ * (see EXPLORE_FUTURE in regex.c).
+ */
+ rx_next_char = rx_cache_miss + 1, /* data is (struct superstate *) */
+
+ /* RX_BACKTRACK indicates that a transition fails.
+ */
+ rx_backtrack = rx_next_char + 1, /* no data */
+
+ /*
+ * RX_ERROR_INX is stored only in places that should never be executed.
+ */
+ rx_error_inx = rx_backtrack + 1, /* Not supposed to occur. */
+
+ rx_num_instructions = rx_error_inx + 1
+};
+
+/* An id_instruction_table holds the values stored in instruction
+ * frames. The table is indexed by the enums declared above.
+ */
+extern void * rx_id_instruction_table[rx_num_instructions];
+
+/* The heart of the matcher is a `word-code-interpreter'
+ * (like a byte-code interpreter, except that instructions
+ * are a full word wide).
+ *
+ * Instructions are not stored in a vector of code, instead,
+ * they are scattered throughout the data structures built
+ * by the regexp compiler and the matcher. One word-code instruction,
+ * together with the arguments to that instruction, constitute
+ * an instruction frame (struct rx_inx).
+ *
+ * This structure type is padded by hand to a power of 2 because
+ * in one of the dominant cases, we dispatch by indexing a table
+ * of instruction frames. If that indexing can be accomplished
+ * by just a shift of the index, we're happy.
+ *
+ * Instructions take at most one argument, but there are two
+ * slots in an instruction frame that might hold that argument.
+ * These are called data and data_2. The data slot is only
+ * used for one instruction (RX_NEXT_CHAR). For all other
+ * instructions, data should be set to 0.
+ *
+ * RX_NEXT_CHAR is the most important instruction by far.
+ * By reserving the data field for its exclusive use,
+ * instruction dispatch is sped up in that case. There is
+ * no need to fetch both the instruction and the data,
+ * only the data is needed. In other words, a `cycle' begins
+ * by fetching the field data. If that is non-0, then it must
+ * be the destination state of a next_char transition, so
+ * make that value the current state, advance the match position
+ * by one character, and start a new cycle. On the other hand,
+ * if data is 0, fetch the instruction and do a more complicated
+ * dispatch on that.
+ */
+
+struct rx_inx
+{
+ void * data;
+ void * data_2;
+ void * inx;
+ void * fnord;
+};
+
+#ifndef RX_TAIL_ARRAY
+#define RX_TAIL_ARRAY 1
+#endif
+
+/* A superstate corresponds to a set of nfa states. Those sets are
+ * represented by STRUCT RX_SUPERSET. The constructors
+ * guarantee that only one (shared) structure is created for a given set.
+ */
+struct rx_superset
+{
+ int refs; /* This is a reference counted structure. */
+
+ /* We keep these sets in a cache because (in an unpredictable way),
+ * the same set is often created again and again. But that is also
+ * problematic -- compatibility with POSIX and GNU regex requires
+ * that we not be able to tell when a program discards a particular
+ * NFA (thus invalidating the supersets created from it).
+ *
+ * But when a cache hit appears to occur, we will have in hand the
+ * nfa for which it may have happened. That is why every nfa is given
+ * its own sequence number. On a cache hit, the cache is validated
+ * by comparing the nfa sequence number to this field:
+ */
+ int id;
+
+ struct rx_nfa_state * car; /* May or may not be a valid addr. */
+ struct rx_superset * cdr;
+
+ /* If the corresponding superstate exists: */
+ struct rx_superstate * superstate;
+
+
+ /* There is another bookkeeping problem. It is expensive to
+ * compute the starting nfa state set for an nfa. So, once computed,
+ * it is cached in the `struct rx'.
+ *
+ * But, the state set can be flushed from the superstate cache.
+ * When that happens, we can't know if the corresponding `struct rx'
+ * is still alive or if it has been freed or re-used by the program.
+ * So, the cached pointer to this set in a struct rx might be invalid
+ * and we need a way to validate it.
+ *
+ * Fortunately, even if this set is flushed from the cache, it is
+ * not freed. It just goes on the free-list of supersets.
+ * So we can still examine it.
+ *
+ * So to validate a starting set memo, check to see if the
+ * starts_for field still points back to the struct rx in question,
+ * and if the ID matches the rx sequence number.
+ */
+ struct rx * starts_for;
+
+ /* This is used to link into a hash bucket so these objects can
+ * be `hash-consed'.
+ */
+ struct rx_hash_item hash_item;
+};
+
+#define rx_protect_superset(RX,CON) (++(CON)->refs)
+
+/* The terminology may be confusing (rename this structure?).
+ * Every character occurs in at most one rx_super_edge per super-state.
+ * But, that structure might have more than one option, indicating a point
+ * of non-determinism.
+ *
+ * In other words, this structure holds a list of superstate edges
+ * sharing a common starting state and character label. The edges
+ * are in the field OPTIONS. All superstate edges sharing the same
+ * starting state and character are in this list.
+ */
+struct rx_super_edge
+{
+ struct rx_super_edge *next;
+ struct rx_inx rx_backtrack_frame;
+ int cset_size;
+ rx_Bitset cset;
+ struct rx_distinct_future *options;
+};
+
+/* A superstate is a set of nfa states (RX_SUPERSET) along
+ * with a transition table. Superstates are built on demand and reclaimed
+ * without warning. To protect a superstate from this ghastly fate,
+ * use LOCK_SUPERSTATE.
+ */
+struct rx_superstate
+{
+ int rx_id; /* c.f. the id field of rx_superset */
+ int locks; /* protection from reclamation */
+
+ /* Within a superstate cache, all the superstates are kept in a big
+ * queue. The tail of the queue is the state most likely to be
+ * reclaimed. The *recyclable fields hold the queue position of
+ * this state.
+ */
+ struct rx_superstate * next_recyclable;
+ struct rx_superstate * prev_recyclable;
+
+ /* The supernfa edges that exist in the cache and that have
+ * this state as their destination are kept in this list:
+ */
+ struct rx_distinct_future * transition_refs;
+
+ /* The list of nfa states corresponding to this superstate: */
+ struct rx_superset * contents;
+
+ /* The list of edges in the cache beginning from this state. */
+ struct rx_super_edge * edges;
+
+ /* A tail of the recyclable queue is marked as semifree. A semifree
+ * state has no incoming next_char transitions -- any transition
+ * into a semifree state causes a complex dispatch with the side
+ * effect of rescuing the state from its semifree state.
+ *
+ * An alternative to this might be to make next_char more expensive,
+ * and to move a state to the head of the recyclable queue whenever
+ * it is entered. That way, popular states would never be recycled.
+ *
+ * But unilaterally making next_char more expensive actually loses.
+ * So, incoming transitions are only made expensive for states near
+ * the tail of the recyclable queue. The more cache contention
+ * there is, the more frequently a state will have to prove itself
+ * and be moved back to the front of the queue. If there is less
+ * contention, then popular states just aggregate in the front of
+ * the queue and stay there.
+ */
+ int is_semifree;
+
+
+ /* This keeps track of the size of the transition table for this
+ * state. There is a half-hearted attempt to support variable sized
+ * superstates.
+ */
+ int trans_size;
+
+ /* Indexed by characters... */
+ struct rx_inx transitions[RX_TAIL_ARRAY];
+};
+
+
+/* A list of distinct futures define the edges that leave from a
+ * given superstate on a given character. c.f. rx_super_edge.
+ */
+
+struct rx_distinct_future
+{
+ struct rx_distinct_future * next_same_super_edge[2];
+ struct rx_distinct_future * next_same_dest;
+ struct rx_distinct_future * prev_same_dest;
+ struct rx_superstate * present; /* source state */
+ struct rx_superstate * future; /* destination state */
+ struct rx_super_edge * edge;
+
+
+ /* The future_frame holds the instruction that should be executed
+ * after all the side effects are done, when it is time to complete
+ * the transition to the next state.
+ *
+ * Normally this is a next_char instruction, but it may be a
+ * cache_miss instruction as well, depending on whether or not
+ * the superstate is in the cache and semifree.
+ *
+ * If this is the only future for a given superstate/char, and
+ * if there are no side effects to be performed, this frame is
+ * not used (directly) at all. Instead, its contents are copied
+ * into the transition table of the starting state of this dist. future.
+ */
+ struct rx_inx future_frame;
+
+ struct rx_inx side_effects_frame;
+ struct rx_se_list * effects;
+};
+
+#define rx_lock_superstate(R,S) ((S)->locks++)
+#define rx_unlock_superstate(R,S) (--(S)->locks)
+
+
+/* This page destined for rx.h */
+
+struct rx_blocklist
+{
+ struct rx_blocklist * next;
+ int bytes;
+};
+
+struct rx_freelist
+{
+ struct rx_freelist * next;
+};
+
+struct rx_cache;
+
+#ifdef __STDC__
+typedef void (*rx_morecore_fn)(struct rx_cache *);
+#else
+typedef void (*rx_morecore_fn)();
+#endif
+
+/* You use this to control the allocation of superstate data
+ * during matching. Most of it should be initialized to 0.
+ *
+ * A MORECORE function is necessary. It should allocate
+ * a new block of memory or return 0.
+ * A default that uses malloc is called `rx_morecore'.
+ *
+ * The number of SUPERSTATES_ALLOWED indirectly limits how much memory
+ * the system will try to allocate. The default is 128. Batch style
+ * applications that are very regexp intensive should use as high a number
+ * as possible without thrashing.
+ *
+ * The LOCAL_CSET_SIZE is the number of characters in a character set.
+ * It is therefore the number of entries in a superstate transition table.
+ * Generally, it should be 256. If your character set has 16 bits,
+ * it is better to translate your regexps into equivalent 8 bit patterns.
+ */
+
+struct rx_cache
+{
+ struct rx_hash_rules superset_hash_rules;
+
+ /* Objects are allocated by incrementing a pointer that
+ * scans across rx_blocklists.
+ */
+ struct rx_blocklist * memory;
+ struct rx_blocklist * memory_pos;
+ int bytes_left;
+ char * memory_addr;
+ rx_morecore_fn morecore;
+
+ /* Freelists. */
+ struct rx_freelist * free_superstates;
+ struct rx_freelist * free_transition_classes;
+ struct rx_freelist * free_discernable_futures;
+ struct rx_freelist * free_supersets;
+ struct rx_freelist * free_hash;
+
+ /* Two sets of superstates -- those that are semifreed, and those
+ * that are being used.
+ */
+ struct rx_superstate * lru_superstate;
+ struct rx_superstate * semifree_superstate;
+
+ struct rx_superset * empty_superset;
+
+ int superstates;
+ int semifree_superstates;
+ int hits;
+ int misses;
+ int superstates_allowed;
+
+ int local_cset_size;
+ void ** instruction_table;
+
+ struct rx_hash superset_table;
+};
+
+
+
+/* The lowest-level search function supports arbitrarily fragmented
+ * strings and (optionally) suspendable/resumable searches.
+ *
+ * Callers have to provide a few hooks.
+ */
+
+#ifndef __GNUC__
+#ifdef __STDC__
+#define __const__ const
+#else
+#define __const__
+#endif
+#endif
+
+/* This holds a matcher position */
+struct rx_string_position
+{
+ __const__ unsigned char * pos; /* The current pos. */
+ __const__ unsigned char * string; /* The current string burst. */
+ __const__ unsigned char * end; /* First invalid position >= POS. */
+ int offset; /* Integer address of the current burst. */
+ int size; /* Current string's size. */
+ int search_direction; /* 1 or -1 */
+ int search_end; /* First position to not try. */
+};
+
+
+enum rx_get_burst_return
+{
+ rx_get_burst_continuation,
+ rx_get_burst_error,
+ rx_get_burst_ok,
+ rx_get_burst_no_more
+};
+
+
+/* A call to get burst should make POS valid. It might be invalid
+ * if the STRING field doesn't point to a burst that actually
+ * contains POS.
+ *
+ * GET_BURST should take a clue from SEARCH_DIRECTION (1 or -1) as to
+ * whether or not to pad to the left. Padding to the right is always
+ * appropriate, but need not go past the point indicated by STOP.
+ *
+ * If a continuation is returned, then the reentering call to
+ * a search function will retry the get_burst.
+ */
+
+#ifdef __STDC__
+typedef enum rx_get_burst_return
+ (*rx_get_burst_fn) (struct rx_string_position * pos,
+ void * app_closure,
+ int stop);
+
+#else
+typedef enum rx_get_burst_return (*rx_get_burst_fn) ();
+#endif
+
+
+enum rx_back_check_return
+{
+ rx_back_check_continuation,
+ rx_back_check_error,
+ rx_back_check_pass,
+ rx_back_check_fail
+};
+
+/* Back_check should advance the position it is passed
+ * over rparen - lparen characters and return pass iff
+ * the characters starting at POS match those indexed
+ * by [LPAREN..RPAREN].
+ *
+ * If a continuation is returned, then the reentering call to
+ * a search function will retry the back_check.
+ */
+
+#ifdef __STDC__
+typedef enum rx_back_check_return
+ (*rx_back_check_fn) (struct rx_string_position * pos,
+ int lparen,
+ int rparen,
+ unsigned char * translate,
+ void * app_closure,
+ int stop);
+
+#else
+typedef enum rx_back_check_return (*rx_back_check_fn) ();
+#endif
+
+
+
+
+/* A call to fetch_char should return the character at POS or POS + 1.
+ * Returning continuations here isn't supported. OFFSET is either 0 or 1
+ * and indicates which characters is desired.
+ */
+
+#ifdef __STDC__
+typedef int (*rx_fetch_char_fn) (struct rx_string_position * pos,
+ int offset,
+ void * app_closure,
+ int stop);
+#else
+typedef int (*rx_fetch_char_fn) ();
+#endif
+
+
+enum rx_search_return
+{
+ rx_search_continuation = -4,
+ rx_search_error = -3,
+ rx_search_soft_fail = -2, /* failed by running out of string */
+ rx_search_fail = -1 /* failed only by reaching failure states */
+ /* return values >= 0 indicate the position of a successful match */
+};
+
+
+
+
+
+
+/* regex.h
+ *
+ * The remaining declarations replace regex.h.
+ */
+
+/* This is an array of error messages corresponding to the error codes.
+ */
+extern __const__ char *re_error_msg[];
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* The regex.c support, as a client of rx, defines a set of possible
+ * side effects that can be added to the edge lables of nfa edges.
+ * Here is the list of sidef effects in use.
+ */
+
+enum re_side_effects
+{
+#define RX_WANT_SE_DEFS 1
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#define RX_DEF_SE(IDEM, NAME, VALUE) NAME VALUE,
+#define RX_DEF_CPLX_SE(IDEM, NAME, VALUE) NAME VALUE,
+#include "rx.h"
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#undef RX_WANT_SE_DEFS
+ re_floogle_flap = 65533
+};
+
+/* These hold paramaters for the kinds of side effects that are possible
+ * in the supported pattern languages. These include things like the
+ * numeric bounds of {} operators and the index of paren registers for
+ * subexpression measurement or backreferencing.
+ */
+struct re_se_params
+{
+ enum re_side_effects se;
+ int op1;
+ int op2;
+};
+
+typedef unsigned reg_syntax_t;
+
+struct re_pattern_buffer
+{
+ struct rx rx;
+ reg_syntax_t syntax; /* See below for syntax bit definitions. */
+
+ unsigned int no_sub:1; /* If set, don't return register offsets. */
+ unsigned int not_bol:1; /* If set, the anchors ('^' and '$') don't */
+ unsigned int not_eol:1; /* match at the ends of the string. */
+ unsigned int newline_anchor:1;/* If true, an anchor at a newline matches.*/
+ unsigned int least_subs:1; /* If set, and returning registers, return
+ * as few values as possible. Only
+ * backreferenced groups and group 0 (the whole
+ * match) will be returned.
+ */
+
+ /* If true, this says that the matcher should keep registers on its
+ * backtracking stack. For many patterns, we can easily determine that
+ * this isn't necessary.
+ */
+ unsigned int match_regs_on_stack:1;
+ unsigned int search_regs_on_stack:1;
+
+ /* is_anchored and begbuf_only are filled in by rx_compile. */
+ unsigned int is_anchored:1; /* Anchorded by ^? */
+ unsigned int begbuf_only:1; /* Anchored to char position 0? */
+
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ * for `max (RE_NREGS, re_nsub + 1)' groups.
+ * If REGS_REALLOCATE, reallocate space if necessary.
+ * If REGS_FIXED, use what's there.
+ */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned int regs_allocated:2;
+
+
+ /* Either a translate table to apply to all characters before
+ * comparing them, or zero for no translation. The translation
+ * is applied to a pattern when it is compiled and to a string
+ * when it is matched.
+ */
+ unsigned char * translate;
+
+ /* If this is a valid pointer, it tells rx not to store the extents of
+ * certain subexpressions (those corresponding to non-zero entries).
+ * Passing 0x1 is the same as passing an array of all ones. Passing 0x0
+ * is the same as passing an array of all zeros.
+ * The array should contain as many entries as their are subexps in the
+ * regexp.
+ *
+ * For POSIX compatability, when using regcomp and regexec this field
+ * is zeroed and ignored.
+ */
+ char * syntax_parens;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ void * buffer; /* Malloced memory for the nfa. */
+ unsigned long allocated; /* Size of that memory. */
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ * the fastmap, if there is one, to skip over impossible
+ * starting points for matches. */
+ char *fastmap;
+
+ unsigned int fastmap_accurate:1; /* These three are internal. */
+ unsigned int can_match_empty:1;
+ struct rx_nfa_state * start; /* The nfa starting state. */
+
+ /* This is the list of iterator bounds for {lo,hi} constructs.
+ * The memory pointed to is part of the rx->buffer.
+ */
+ struct re_se_params *se_params;
+
+ /* This is a bitset representation of the fastmap.
+ * This is a true fastmap that already takes the translate
+ * table into account.
+ */
+ rx_Bitset fastset;
+};
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* 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 (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1)
+
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ * `re_match_2' returns information about at least this many registers
+ * the first time a `regs' structure is passed.
+ *
+ * Also, this is the greatest number of backreferenced subexpressions
+ * allowed in a pattern being matched without caller-supplied registers.
+ */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+extern int rx_cache_bound;
+extern char rx_version_string[];
+
+
+
+#ifdef RX_WANT_RX_DEFS
+
+/* This is decls to the interesting subsystems and lower layers
+ * of rx. Everything which doesn't have a public counterpart in
+ * regex.c is declared here.
+ */
+
+
+#ifdef __STDC__
+typedef void (*rx_hash_freefn) (struct rx_hash_item * it);
+#else /* ndef __STDC__ */
+typedef void (*rx_hash_freefn) ();
+#endif /* ndef __STDC__ */
+
+
+
+
+#ifdef __STDC__
+RX_DECL int rx_bitset_is_equal (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL int rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL int rx_bitset_empty (int size, rx_Bitset set);
+RX_DECL void rx_bitset_null (int size, rx_Bitset b);
+RX_DECL void rx_bitset_universe (int size, rx_Bitset b);
+RX_DECL void rx_bitset_complement (int size, rx_Bitset b);
+RX_DECL void rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_union (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_intersection (int size,
+ rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_revdifference (int size,
+ rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_xor (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL unsigned long rx_bitset_hash (int size, rx_Bitset b);
+RX_DECL struct rx_hash_item * rx_hash_find (struct rx_hash * table,
+ unsigned long hash,
+ void * value,
+ struct rx_hash_rules * rules);
+RX_DECL struct rx_hash_item * rx_hash_store (struct rx_hash * table,
+ unsigned long hash,
+ void * value,
+ struct rx_hash_rules * rules);
+RX_DECL void rx_hash_free (struct rx_hash_item * it, struct rx_hash_rules * rules);
+RX_DECL void rx_free_hash_table (struct rx_hash * tab, rx_hash_freefn freefn,
+ struct rx_hash_rules * rules);
+RX_DECL rx_Bitset rx_cset (struct rx *rx);
+RX_DECL rx_Bitset rx_copy_cset (struct rx *rx, rx_Bitset a);
+RX_DECL void rx_free_cset (struct rx * rx, rx_Bitset c);
+RX_DECL struct rexp_node * rexp_node (struct rx *rx,
+ enum rexp_node_type type);
+RX_DECL struct rexp_node * rx_mk_r_cset (struct rx * rx,
+ rx_Bitset b);
+RX_DECL struct rexp_node * rx_mk_r_concat (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b);
+RX_DECL struct rexp_node * rx_mk_r_alternate (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b);
+RX_DECL struct rexp_node * rx_mk_r_opt (struct rx * rx,
+ struct rexp_node * a);
+RX_DECL struct rexp_node * rx_mk_r_star (struct rx * rx,
+ struct rexp_node * a);
+RX_DECL struct rexp_node * rx_mk_r_2phase_star (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b);
+RX_DECL struct rexp_node * rx_mk_r_side_effect (struct rx * rx,
+ rx_side_effect a);
+RX_DECL struct rexp_node * rx_mk_r_data (struct rx * rx,
+ void * a);
+RX_DECL void rx_free_rexp (struct rx * rx, struct rexp_node * node);
+RX_DECL struct rexp_node * rx_copy_rexp (struct rx *rx,
+ struct rexp_node *node);
+RX_DECL struct rx_nfa_state * rx_nfa_state (struct rx *rx);
+RX_DECL void rx_free_nfa_state (struct rx_nfa_state * n);
+RX_DECL struct rx_nfa_state * rx_id_to_nfa_state (struct rx * rx,
+ int id);
+RX_DECL struct rx_nfa_edge * rx_nfa_edge (struct rx *rx,
+ enum rx_nfa_etype type,
+ struct rx_nfa_state *start,
+ struct rx_nfa_state *dest);
+RX_DECL void rx_free_nfa_edge (struct rx_nfa_edge * e);
+RX_DECL void rx_free_nfa (struct rx *rx);
+RX_DECL int rx_build_nfa (struct rx *rx,
+ struct rexp_node *rexp,
+ struct rx_nfa_state **start,
+ struct rx_nfa_state **end);
+RX_DECL void rx_name_nfa_states (struct rx *rx);
+RX_DECL int rx_eclose_nfa (struct rx *rx);
+RX_DECL void rx_delete_epsilon_transitions (struct rx *rx);
+RX_DECL int rx_compactify_nfa (struct rx *rx,
+ void **mem, unsigned long *size);
+RX_DECL void rx_release_superset (struct rx *rx,
+ struct rx_superset *set);
+RX_DECL struct rx_superset * rx_superset_cons (struct rx * rx,
+ struct rx_nfa_state *car, struct rx_superset *cdr);
+RX_DECL struct rx_superset * rx_superstate_eclosure_union
+ (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl);
+RX_DECL struct rx_superstate * rx_superstate (struct rx *rx,
+ struct rx_superset *set);
+RX_DECL struct rx_inx * rx_handle_cache_miss
+ (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data);
+RX_DECL reg_errcode_t rx_compile (__const__ char *pattern, int size,
+ reg_syntax_t syntax,
+ struct re_pattern_buffer * rxb);
+RX_DECL void rx_blow_up_fastmap (struct re_pattern_buffer * rxb);
+#else /* STDC */
+RX_DECL int rx_bitset_is_equal ();
+RX_DECL int rx_bitset_is_subset ();
+RX_DECL int rx_bitset_empty ();
+RX_DECL void rx_bitset_null ();
+RX_DECL void rx_bitset_universe ();
+RX_DECL void rx_bitset_complement ();
+RX_DECL void rx_bitset_assign ();
+RX_DECL void rx_bitset_union ();
+RX_DECL void rx_bitset_intersection ();
+RX_DECL void rx_bitset_difference ();
+RX_DECL void rx_bitset_revdifference ();
+RX_DECL void rx_bitset_xor ();
+RX_DECL unsigned long rx_bitset_hash ();
+RX_DECL struct rx_hash_item * rx_hash_find ();
+RX_DECL struct rx_hash_item * rx_hash_store ();
+RX_DECL void rx_hash_free ();
+RX_DECL void rx_free_hash_table ();
+RX_DECL rx_Bitset rx_cset ();
+RX_DECL rx_Bitset rx_copy_cset ();
+RX_DECL void rx_free_cset ();
+RX_DECL struct rexp_node * rexp_node ();
+RX_DECL struct rexp_node * rx_mk_r_cset ();
+RX_DECL struct rexp_node * rx_mk_r_concat ();
+RX_DECL struct rexp_node * rx_mk_r_alternate ();
+RX_DECL struct rexp_node * rx_mk_r_opt ();
+RX_DECL struct rexp_node * rx_mk_r_star ();
+RX_DECL struct rexp_node * rx_mk_r_2phase_star ();
+RX_DECL struct rexp_node * rx_mk_r_side_effect ();
+RX_DECL struct rexp_node * rx_mk_r_data ();
+RX_DECL void rx_free_rexp ();
+RX_DECL struct rexp_node * rx_copy_rexp ();
+RX_DECL struct rx_nfa_state * rx_nfa_state ();
+RX_DECL void rx_free_nfa_state ();
+RX_DECL struct rx_nfa_state * rx_id_to_nfa_state ();
+RX_DECL struct rx_nfa_edge * rx_nfa_edge ();
+RX_DECL void rx_free_nfa_edge ();
+RX_DECL void rx_free_nfa ();
+RX_DECL int rx_build_nfa ();
+RX_DECL void rx_name_nfa_states ();
+RX_DECL int rx_eclose_nfa ();
+RX_DECL void rx_delete_epsilon_transitions ();
+RX_DECL int rx_compactify_nfa ();
+RX_DECL void rx_release_superset ();
+RX_DECL struct rx_superset * rx_superset_cons ();
+RX_DECL struct rx_superset * rx_superstate_eclosure_union ();
+RX_DECL struct rx_superstate * rx_superstate ();
+RX_DECL struct rx_inx * rx_handle_cache_miss ();
+RX_DECL reg_errcode_t rx_compile ();
+RX_DECL void rx_blow_up_fastmap ();
+#endif /* STDC */
+
+
+#endif /* RX_WANT_RX_DEFS */
+
+
+
+#ifdef __STDC__
+extern int re_search_2 (struct re_pattern_buffer *rxb,
+ __const__ char * string1, int size1,
+ __const__ char * string2, int size2,
+ int startpos, int range,
+ struct re_registers *regs,
+ int stop);
+extern int re_search (struct re_pattern_buffer * rxb, __const__ char *string,
+ int size, int startpos, int range,
+ struct re_registers *regs);
+extern int re_match_2 (struct re_pattern_buffer * rxb,
+ __const__ char * string1, int size1,
+ __const__ char * string2, int size2,
+ int pos, struct re_registers *regs, int stop);
+extern int re_match (struct re_pattern_buffer * rxb,
+ __const__ char * string,
+ int size, int pos,
+ struct re_registers *regs);
+extern reg_syntax_t re_set_syntax (reg_syntax_t syntax);
+extern void re_set_registers (struct re_pattern_buffer *bufp,
+ struct re_registers *regs,
+ unsigned num_regs,
+ regoff_t * starts, regoff_t * ends);
+extern __const__ char * re_compile_pattern (__const__ char *pattern,
+ int length,
+ struct re_pattern_buffer * rxb);
+extern int re_compile_fastmap (struct re_pattern_buffer * rxb);
+extern char * re_comp (__const__ char *s);
+extern int re_exec (__const__ char *s);
+extern int regcomp (regex_t * preg, __const__ char * pattern, int cflags);
+extern int regexec (__const__ regex_t *preg, __const__ char *string,
+ size_t nmatch, regmatch_t pmatch[],
+ int eflags);
+extern size_t regerror (int errcode, __const__ regex_t *preg,
+ char *errbuf, size_t errbuf_size);
+extern void regfree (regex_t *preg);
+
+#else /* STDC */
+extern int re_search_2 ();
+extern int re_search ();
+extern int re_match_2 ();
+extern int re_match ();
+extern reg_syntax_t re_set_syntax ();
+extern void re_set_registers ();
+extern __const__ char * re_compile_pattern ();
+extern int re_compile_fastmap ();
+extern char * re_comp ();
+extern int re_exec ();
+extern int regcomp ();
+extern int regexec ();
+extern size_t regerror ();
+extern void regfree ();
+
+#endif /* STDC */
+
+
+
+#ifdef RX_WANT_RX_DEFS
+
+struct rx_counter_frame
+{
+ int tag;
+ int val;
+ struct rx_counter_frame * inherited_from; /* If this is a copy. */
+ struct rx_counter_frame * cdr;
+};
+
+struct rx_backtrack_frame
+{
+ char * counter_stack_sp;
+
+ /* A frame is used to save the matchers state when it crosses a
+ * backtracking point. The `stk_' fields correspond to variables
+ * in re_search_2 (just strip off thes `stk_'). They are documented
+ * tere.
+ */
+ struct rx_superstate * stk_super;
+ unsigned int stk_c;
+ struct rx_string_position stk_test_pos;
+ int stk_last_l;
+ int stk_last_r;
+ int stk_test_ret;
+
+ /* This is the list of options left to explore at the backtrack
+ * point for which this frame was created.
+ */
+ struct rx_distinct_future * df;
+ struct rx_distinct_future * first_df;
+
+#ifdef RX_DEBUG
+ int stk_line_no;
+#endif
+};
+
+struct rx_stack_chunk
+{
+ struct rx_stack_chunk * next_chunk;
+ int bytes_left;
+ char * sp;
+};
+
+enum rx_outer_entry
+{
+ rx_outer_start,
+ rx_outer_fastmap,
+ rx_outer_test,
+ rx_outer_restore_pos
+};
+
+enum rx_fastmap_return
+{
+ rx_fastmap_continuation,
+ rx_fastmap_error,
+ rx_fastmap_ok,
+ rx_fastmap_fail
+};
+
+enum rx_fastmap_entry
+{
+ rx_fastmap_start,
+ rx_fastmap_string_break
+};
+
+enum rx_test_return
+{
+ rx_test_continuation,
+ rx_test_error,
+ rx_test_fail,
+ rx_test_ok
+};
+
+enum rx_test_internal_return
+{
+ rx_test_internal_error,
+ rx_test_found_first,
+ rx_test_line_finished
+};
+
+enum rx_test_match_entry
+{
+ rx_test_start,
+ rx_test_cache_hit_loop,
+ rx_test_backreference_check,
+ rx_test_backtrack_return
+};
+
+struct rx_search_state
+{
+ /* Two groups of registers are kept. The group with the register state
+ * of the current test match, and the group that holds the state at the end
+ * of the best known match, if any.
+ *
+ * For some patterns, there may also be registers saved on the stack.
+ */
+ unsigned num_regs; /* Includes an element for register zero. */
+ regoff_t * lparen; /* scratch space for register returns */
+ regoff_t * rparen;
+ regoff_t * best_lpspace; /* in case the user doesn't want these */
+ regoff_t * best_rpspace; /* values, we still need space to store
+ * them. Normally, this memoryis unused
+ * and the space pointed to by REGS is
+ * used instead.
+ */
+
+ int last_l; /* Highest index of a valid lparen. */
+ int last_r; /* It's dual. */
+
+ int * best_lparen; /* This contains the best known register */
+ int * best_rparen; /* assignments.
+ * This may point to the same mem as
+ * best_lpspace, or it might point to memory
+ * passed by the caller.
+ */
+ int best_last_l; /* best_last_l:best_lparen::last_l:lparen */
+ int best_last_r;
+
+
+ unsigned char * translate;
+
+ struct rx_string_position outer_pos;
+
+ struct rx_superstate * start_super;
+ int nfa_choice;
+ int first_found; /* If true, return after finding any match. */
+ int ret_val;
+
+ /* For continuations... */
+ enum rx_outer_entry outer_search_resume_pt;
+ struct re_pattern_buffer * saved_rxb;
+ int saved_startpos;
+ int saved_range;
+ int saved_stop;
+ int saved_total_size;
+ rx_get_burst_fn saved_get_burst;
+ rx_back_check_fn saved_back_check;
+ struct re_registers * saved_regs;
+
+ /**
+ ** state for fastmap
+ **/
+ char * fastmap;
+ int fastmap_chr;
+ int fastmap_val;
+
+ /* for continuations in the fastmap procedure: */
+ enum rx_fastmap_entry fastmap_resume_pt;
+
+ /**
+ ** state for test_match
+ **/
+
+ /* The current superNFA position of the matcher. */
+ struct rx_superstate * super;
+
+ /* The matcher interprets a series of instruction frames.
+ * This is the `instruction counter' for the interpretation.
+ */
+ struct rx_inx * ifr;
+
+ /* We insert a ghost character in the string to prime
+ * the nfa. test_pos.pos, test_pos.str_half, and test_pos.end_half
+ * keep track of the test-match position and string-half.
+ */
+ unsigned char c;
+
+ /* Position within the string. */
+ struct rx_string_position test_pos;
+
+ struct rx_stack_chunk * counter_stack;
+ struct rx_stack_chunk * backtrack_stack;
+ int backtrack_frame_bytes;
+ int chunk_bytes;
+ struct rx_stack_chunk * free_chunks;
+
+ /* To return from this function, set test_ret and
+ * `goto test_do_return'.
+ *
+ * Possible return values are:
+ * 1 --- end of string while the superNFA is still going
+ * 0 --- internal error (out of memory)
+ * -1 --- search completed by reaching the superNFA fail state
+ * -2 --- a match was found, maybe not the longest.
+ *
+ * When the search is complete (-1), best_last_r indicates whether
+ * a match was found.
+ *
+ * -2 is return only if search_state.first_found is non-zero.
+ *
+ * if search_state.first_found is non-zero, a return of -1 indicates no match,
+ * otherwise, best_last_r has to be checked.
+ */
+ int test_ret;
+
+ int could_have_continued;
+
+#ifdef RX_DEBUG
+ int backtrack_depth;
+ /* There is a search tree with every node as set of deterministic
+ * transitions in the super nfa. For every branch of a
+ * backtrack point is an edge in the tree.
+ * This counts up a pre-order of nodes in that tree.
+ * It's saved on the search stack and printed when debugging.
+ */
+ int line_no;
+ int lines_found;
+#endif
+
+
+ /* For continuations within the match tester */
+ enum rx_test_match_entry test_match_resume_pt;
+ struct rx_inx * saved_next_tr_table;
+ struct rx_inx * saved_this_tr_table;
+ int saved_reg;
+ struct rx_backtrack_frame * saved_bf;
+
+};
+
+
+extern char rx_slowmap[];
+extern unsigned char rx_id_translation[];
+
+static __inline__ void
+init_fastmap (rxb, search_state)
+ struct re_pattern_buffer * rxb;
+ struct rx_search_state * search_state;
+{
+ search_state->fastmap = (rxb->fastmap
+ ? (char *)rxb->fastmap
+ : (char *)rx_slowmap);
+ /* Update the fastmap now if not correct already.
+ * When the regexp was compiled, the fastmap was computed
+ * and stored in a bitset. This expands the bitset into a
+ * character array containing 1s and 0s.
+ */
+ if ((search_state->fastmap == rxb->fastmap) && !rxb->fastmap_accurate)
+ rx_blow_up_fastmap (rxb);
+ search_state->fastmap_chr = -1;
+ search_state->fastmap_val = 0;
+ search_state->fastmap_resume_pt = rx_fastmap_start;
+}
+
+static __inline__ void
+uninit_fastmap (rxb, search_state)
+ struct re_pattern_buffer * rxb;
+ struct rx_search_state * search_state;
+{
+ /* Unset the fastmap sentinel */
+ if (search_state->fastmap_chr >= 0)
+ search_state->fastmap[search_state->fastmap_chr]
+ = search_state->fastmap_val;
+}
+
+static __inline__ int
+fastmap_search (rxb, stop, get_burst, app_closure, search_state)
+ struct re_pattern_buffer * rxb;
+ int stop;
+ rx_get_burst_fn get_burst;
+ void * app_closure;
+ struct rx_search_state * search_state;
+{
+ enum rx_fastmap_entry pc;
+
+ if (0)
+ {
+ return_continuation:
+ search_state->fastmap_resume_pt = pc;
+ return rx_fastmap_continuation;
+ }
+
+ pc = search_state->fastmap_resume_pt;
+
+ switch (pc)
+ {
+ default:
+ return rx_fastmap_error;
+ case rx_fastmap_start:
+ init_fastmap_sentinal:
+ /* For the sake of fast fastmapping, set a sentinal in the fastmap.
+ * This sentinal will trap the fastmap loop when it reaches the last
+ * valid character in a string half.
+ *
+ * This must be reset when the fastmap/search loop crosses a string
+ * boundry, and before returning to the caller. So sometimes,
+ * the fastmap loop is restarted with `continue', othertimes by
+ * `goto init_fastmap_sentinal'.
+ */
+ if (search_state->outer_pos.size)
+ {
+ search_state->fastmap_chr = ((search_state->outer_pos.search_direction == 1)
+ ? *(search_state->outer_pos.end - 1)
+ : *search_state->outer_pos.string);
+ search_state->fastmap_val
+ = search_state->fastmap[search_state->fastmap_chr];
+ search_state->fastmap[search_state->fastmap_chr] = 1;
+ }
+ else
+ {
+ search_state->fastmap_chr = -1;
+ search_state->fastmap_val = 0;
+ }
+
+ if (search_state->outer_pos.pos >= search_state->outer_pos.end)
+ goto fastmap_hit_bound;
+ else
+ {
+ if (search_state->outer_pos.search_direction == 1)
+ {
+ if (search_state->fastmap_val)
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ ++search_state->outer_pos.pos;
+ return rx_fastmap_ok;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ ++search_state->outer_pos.pos;
+ if (*search_state->outer_pos.pos != search_state->fastmap_chr)
+ return rx_fastmap_ok;
+ else
+ {
+ ++search_state->outer_pos.pos;
+ if (search_state->outer_pos.pos == search_state->outer_pos.end)
+ goto fastmap_hit_bound;
+ }
+ }
+ }
+ }
+ else
+ {
+ __const__ unsigned char * bound;
+ bound = search_state->outer_pos.string - 1;
+ if (search_state->fastmap_val)
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ --search_state->outer_pos.pos;
+ return rx_fastmap_ok;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ --search_state->outer_pos.pos;
+ if ((*search_state->outer_pos.pos != search_state->fastmap_chr) || search_state->fastmap_val)
+ return rx_fastmap_ok;
+ else
+ {
+ --search_state->outer_pos.pos;
+ if (search_state->outer_pos.pos == bound)
+ goto fastmap_hit_bound;
+ }
+ }
+ }
+ }
+ }
+
+ case rx_fastmap_string_break:
+ fastmap_hit_bound:
+ {
+ /* If we hit a bound, it may be time to fetch another burst
+ * of string, or it may be time to return a continuation to
+ * the caller, or it might be time to fail.
+ */
+
+ int burst_state;
+ burst_state = get_burst (&search_state->outer_pos, app_closure, stop);
+ switch (burst_state)
+ {
+ default:
+ case rx_get_burst_error:
+ return rx_fastmap_error;
+ case rx_get_burst_continuation:
+ {
+ pc = rx_fastmap_string_break;
+ goto return_continuation;
+ }
+ case rx_get_burst_ok:
+ goto init_fastmap_sentinal;
+ case rx_get_burst_no_more:
+ /* ...not a string split, simply no more string.
+ *
+ * When searching backward, running out of string
+ * is reason to quit.
+ *
+ * When searching forward, we allow the possibility
+ * of an (empty) match after the last character in the
+ * virtual string. So, fall through to the matcher
+ */
+ return ( (search_state->outer_pos.search_direction == 1)
+ ? rx_fastmap_ok
+ : rx_fastmap_fail);
+ }
+ }
+ }
+
+}
+
+
+
+#ifdef emacs
+/* The `emacs' switch turns on certain matching commands
+ * that make sense only in Emacs.
+ */
+#include "config.h"
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+#endif /* emacs */
+
+/* Setting RX_MEMDBUG is useful if you have dbmalloc. Maybe with similar
+ * packages too.
+ */
+#ifdef RX_MEMDBUG
+#include <malloc.h>
+#endif /* RX_RX_MEMDBUG */
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+ * `BSTRING', as far as I know, and neither of them use this code.
+ */
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+
+#ifndef bcmp
+#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
+#endif
+
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+
+#ifndef bzero
+#define bzero(s, n) memset ((s), 0, (n))
+#endif
+
+#else /* HAVE_STRING_H || STDC_HEADERS */
+#include <strings.h>
+#endif /* not (HAVE_STRING_H || STDC_HEADERS) */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else /* not STDC_HEADERS */
+char *malloc ();
+char *realloc ();
+#endif /* not STDC_HEADERS */
+
+
+
+
+/* How many characters in the character set. */
+#define CHAR_SET_SIZE (1 << CHARBITS)
+
+#ifndef emacs
+/* Define the syntax basics for \<, \>, 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]
+RX_DECL char re_syntax_table[CHAR_SET_SIZE];
+#endif /* not emacs */
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ * of `string1' and `string2'. If only one string, it's `string2'.
+ */
+
+#define AT_STRINGS_BEG() \
+ ( -1 \
+ == ((search_state.test_pos.pos - search_state.test_pos.string) \
+ + search_state.test_pos.offset))
+
+#define AT_STRINGS_END() \
+ ( (total_size - 1) \
+ == ((search_state.test_pos.pos - search_state.test_pos.string) \
+ + search_state.test_pos.offset))
+
+
+/* Test if POS + 1 points to a character which is word-constituent. We have
+ * two special cases to check for: if past the end of string1, look at
+ * the first character in string2; and if before the beginning of
+ * string2, look at the last character in string1.
+ *
+ * Assumes `string1' exists, so use in conjunction with AT_STRINGS_BEG ().
+ */
+#define LETTER_P(POS,OFF) \
+ ( SYNTAX (fetch_char(POS, OFF, app_closure, stop)) \
+ == Sword)
+
+/* Test if the character at D and the one after D differ with respect
+ * to being word-constituent.
+ */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG () || AT_STRINGS_END () || LETTER_P (d,0) != LETTER_P (d, 1))
+
+
+#ifdef RX_SUPPORT_CONTINUATIONS
+#define RX_STACK_ALLOC(BYTES) malloc(BYTES)
+#define RX_STACK_FREE(MEM) free(MEM)
+#else
+#define RX_STACK_ALLOC(BYTES) alloca(BYTES)
+#define RX_STACK_FREE(MEM) \
+ ((struct rx_stack_chunk *)MEM)->next_chunk = search_state.free_chunks; \
+ search_state.free_chunks = ((struct rx_stack_chunk *)MEM);
+
+#endif
+
+#define PUSH(CHUNK_VAR,BYTES) \
+ if (!CHUNK_VAR || (CHUNK_VAR->bytes_left < (BYTES))) \
+ { \
+ struct rx_stack_chunk * new_chunk; \
+ if (search_state.free_chunks) \
+ { \
+ new_chunk = search_state.free_chunks; \
+ search_state.free_chunks = search_state.free_chunks->next_chunk; \
+ } \
+ else \
+ { \
+ new_chunk = (struct rx_stack_chunk *)RX_STACK_ALLOC(search_state.chunk_bytes); \
+ if (!new_chunk) \
+ { \
+ search_state.ret_val = 0; \
+ goto test_do_return; \
+ } \
+ } \
+ new_chunk->sp = (char *)new_chunk + sizeof (struct rx_stack_chunk); \
+ new_chunk->bytes_left = (search_state.chunk_bytes \
+ - (BYTES) \
+ - sizeof (struct rx_stack_chunk)); \
+ new_chunk->next_chunk = CHUNK_VAR; \
+ CHUNK_VAR = new_chunk; \
+ } \
+ else \
+ (CHUNK_VAR->sp += (BYTES)), (CHUNK_VAR->bytes_left -= (BYTES))
+
+#define POP(CHUNK_VAR,BYTES) \
+ if (CHUNK_VAR->sp == ((char *)CHUNK_VAR + sizeof(*CHUNK_VAR))) \
+ { \
+ struct rx_stack_chunk * new_chunk = CHUNK_VAR->next_chunk; \
+ RX_STACK_FREE(CHUNK_VAR); \
+ CHUNK_VAR = new_chunk; \
+ } \
+ else \
+ (CHUNK_VAR->sp -= BYTES), (CHUNK_VAR->bytes_left += BYTES)
+
+
+
+#define SRCH_TRANSLATE(C) search_state.translate[(unsigned char) (C)]
+
+
+
+
+#ifdef __STDC__
+RX_DECL __inline__ int
+rx_search (struct re_pattern_buffer * rxb,
+ int startpos,
+ int range,
+ int stop,
+ int total_size,
+ rx_get_burst_fn get_burst,
+ rx_back_check_fn back_check,
+ rx_fetch_char_fn fetch_char,
+ void * app_closure,
+ struct re_registers * regs,
+ struct rx_search_state * resume_state,
+ struct rx_search_state * save_state)
+#else
+RX_DECL __inline__ int
+rx_search (rxb, startpos, range, stop, total_size,
+ get_burst, back_check, fetch_char,
+ app_closure, regs, resume_state, save_state)
+ struct re_pattern_buffer * rxb;
+ int startpos;
+ int range;
+ int stop;
+ int total_size;
+ rx_get_burst_fn get_burst;
+ rx_back_check_fn back_check;
+ rx_fetch_char_fn fetch_char;
+ void * app_closure;
+ struct re_registers * regs;
+ struct rx_search_state * resume_state;
+ struct rx_search_state * save_state;
+#endif
+{
+ int pc;
+ int test_state;
+ struct rx_search_state search_state;
+
+ search_state.free_chunks = 0;
+ if (!resume_state)
+ pc = rx_outer_start;
+ else
+ {
+ search_state = *resume_state;
+ regs = search_state.saved_regs;
+ rxb = search_state.saved_rxb;
+ startpos = search_state.saved_startpos;
+ range = search_state.saved_range;
+ stop = search_state.saved_stop;
+ total_size = search_state.saved_total_size;
+ get_burst = search_state.saved_get_burst;
+ back_check = search_state.saved_back_check;
+ pc = search_state.outer_search_resume_pt;
+ if (0)
+ {
+ return_continuation:
+ if (save_state)
+ {
+ *save_state = search_state;
+ save_state->saved_regs = regs;
+ save_state->saved_rxb = rxb;
+ save_state->saved_startpos = startpos;
+ save_state->saved_range = range;
+ save_state->saved_stop = stop;
+ save_state->saved_total_size = total_size;
+ save_state->saved_get_burst = get_burst;
+ save_state->saved_back_check = back_check;
+ save_state->outer_search_resume_pt = pc;
+ }
+ return rx_search_continuation;
+ }
+ }
+
+ switch (pc)
+ {
+ case rx_outer_start:
+ search_state.ret_val = rx_search_fail;
+ ( search_state.lparen
+ = search_state.rparen
+ = search_state.best_lpspace
+ = search_state.best_rpspace
+ = 0);
+
+ /* figure the number of registers we may need for use in backreferences.
+ * the number here includes an element for register zero.
+ */
+ search_state.num_regs = rxb->re_nsub + 1;
+
+
+ /* check for out-of-range startpos. */
+ if ((startpos < 0) || (startpos > total_size))
+ return rx_search_fail;
+
+ /* fix up range if it might eventually take us outside the string. */
+ {
+ int endpos;
+ endpos = startpos + range;
+ if (endpos < -1)
+ range = (-1 - startpos);
+ else if (endpos > (total_size + 1))
+ range = total_size - startpos;
+ }
+
+ /* 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 (rxb->begbuf_only && (range > 0))
+ {
+ if (startpos > 0)
+ return rx_search_fail;
+ else
+ range = 1;
+ }
+
+ /* decide whether to use internal or user-provided reg buffers. */
+ if (!regs || rxb->no_sub)
+ {
+ search_state.best_lpspace =
+ (regoff_t *)REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+ search_state.best_rpspace =
+ (regoff_t *)REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+ search_state.best_lparen = search_state.best_lpspace;
+ search_state.best_rparen = search_state.best_rpspace;
+ }
+ else
+ {
+ /* have the register data arrays been allocated? */
+ if (rxb->regs_allocated == REGS_UNALLOCATED)
+ { /* no. so allocate them with malloc. we need one
+ extra element beyond `search_state.num_regs' for the `-1' marker
+ gnu code uses. */
+ regs->num_regs = MAX (RE_NREGS, rxb->re_nsub + 1);
+ regs->start = ((regoff_t *)
+ malloc (regs->num_regs * sizeof ( regoff_t)));
+ regs->end = ((regoff_t *)
+ malloc (regs->num_regs * sizeof ( regoff_t)));
+ if (regs->start == 0 || regs->end == 0)
+ return rx_search_error;
+ rxb->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (rxb->regs_allocated == REGS_REALLOCATE)
+ { /* yes. if we need more elements than were already
+ allocated, reallocate them. if we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < search_state.num_regs + 1)
+ {
+ regs->num_regs = search_state.num_regs + 1;
+ regs->start = ((regoff_t *)
+ realloc (regs->start,
+ regs->num_regs * sizeof (regoff_t)));
+ regs->end = ((regoff_t *)
+ realloc (regs->end,
+ regs->num_regs * sizeof ( regoff_t)));
+ if (regs->start == 0 || regs->end == 0)
+ return rx_search_error;
+ }
+ }
+ else if (rxb->regs_allocated != REGS_FIXED)
+ return rx_search_error;
+
+ if (regs->num_regs < search_state.num_regs + 1)
+ {
+ search_state.best_lpspace =
+ ((regoff_t *)
+ REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t)));
+ search_state.best_rpspace =
+ ((regoff_t *)
+ REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t)));
+ search_state.best_lparen = search_state.best_lpspace;
+ search_state.best_rparen = search_state.best_rpspace;
+ }
+ else
+ {
+ search_state.best_lparen = regs->start;
+ search_state.best_rparen = regs->end;
+ }
+ }
+
+ search_state.lparen =
+ (regoff_t *) REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+ search_state.rparen =
+ (regoff_t *) REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+
+ if (! ( search_state.best_rparen
+ && search_state.best_lparen
+ && search_state.lparen && search_state.rparen))
+ return rx_search_error;
+
+ search_state.best_last_l = search_state.best_last_r = -1;
+
+ search_state.translate = (rxb->translate
+ ? rxb->translate
+ : rx_id_translation);
+
+
+
+ /*
+ * two nfa's were compiled.
+ * `0' is complete.
+ * `1' faster but gets registers wrong and ends too soon.
+ */
+ search_state.nfa_choice = (regs && !rxb->least_subs) ? '\0' : '\1';
+
+ /* we have the option to look for the best match or the first
+ * one we can find. if the user isn't asking for register information,
+ * we don't need to find the best match.
+ */
+ search_state.first_found = !regs;
+
+ if (range >= 0)
+ {
+ search_state.outer_pos.search_end = startpos + range;
+ search_state.outer_pos.search_direction = 1;
+ }
+ else
+ {
+ search_state.outer_pos.search_end = startpos + range;
+ search_state.outer_pos.search_direction = -1;
+ }
+
+ /* the vacuous search always turns up nothing. */
+ if ((search_state.outer_pos.search_direction == 1)
+ ? (startpos > search_state.outer_pos.search_end)
+ : (startpos < search_state.outer_pos.search_end))
+ return rx_search_fail;
+
+ /* now we build the starting state of the supernfa. */
+ {
+ struct rx_superset * start_contents;
+ struct rx_nfa_state_set * start_nfa_set;
+
+ /* we presume here that the nfa start state has only one
+ * possible future with no side effects.
+ */
+ start_nfa_set = rxb->start->futures->destset;
+ if ( rxb->rx.start_set
+ && (rxb->rx.start_set->starts_for == &rxb->rx))
+ start_contents = rxb->rx.start_set;
+ else
+ {
+ start_contents =
+ rx_superstate_eclosure_union (&rxb->rx,
+ rx_superset_cons (&rxb->rx, 0, 0),
+ start_nfa_set);
+
+ if (!start_contents)
+ return rx_search_fail;
+
+ start_contents->starts_for = &rxb->rx;
+ rxb->rx.start_set = start_contents;
+ }
+ if ( start_contents->superstate
+ && (start_contents->superstate->rx_id == rxb->rx.rx_id))
+ {
+ search_state.start_super = start_contents->superstate;
+ rx_lock_superstate (&rxb->rx, search_state.start_super);
+ }
+ else
+ {
+ rx_protect_superset (&rxb->rx, start_contents);
+
+ search_state.start_super = rx_superstate (&rxb->rx, start_contents);
+ if (!search_state.start_super)
+ return rx_search_fail;
+ rx_lock_superstate (&rxb->rx, search_state.start_super);
+ rx_release_superset (&rxb->rx, start_contents);
+ }
+ }
+
+
+ /* The outer_pos tracks the position within the strings
+ * as seen by loop that calls fastmap_search.
+ *
+ * The caller supplied get_burst function actually
+ * gives us pointers to chars.
+ *
+ * Communication with the get_burst function is through an
+ * rx_string_position structure. Here, the structure for
+ * outer_pos is initialized. It is set to point to the
+ * NULL string, at an offset of STARTPOS. STARTPOS is out
+ * of range of the NULL string, so the first call to
+ * getburst will patch up the rx_string_position to point
+ * to valid characters.
+ */
+
+ ( search_state.outer_pos.string
+ = search_state.outer_pos.end
+ = 0);
+
+ search_state.outer_pos.offset = 0;
+ search_state.outer_pos.size = 0;
+ search_state.outer_pos.pos = (unsigned char *)startpos;
+ init_fastmap (rxb, &search_state);
+
+ search_state.fastmap_resume_pt = rx_fastmap_start;
+ case rx_outer_fastmap:
+ /* do { */
+ pseudo_do:
+ {
+ {
+ int fastmap_state;
+ fastmap_state = fastmap_search (rxb, stop, get_burst, app_closure,
+ &search_state);
+ switch (fastmap_state)
+ {
+ case rx_fastmap_continuation:
+ pc = rx_outer_fastmap;
+ goto return_continuation;
+ case rx_fastmap_fail:
+ goto finish;
+ case rx_fastmap_ok:
+ break;
+ }
+ }
+
+ /* now the fastmap loop has brought us to a plausible
+ * starting point for a match. so, it's time to run the
+ * nfa and see if a match occured.
+ */
+ startpos = ( search_state.outer_pos.pos
+ - search_state.outer_pos.string
+ + search_state.outer_pos.offset);
+#if 0
+/*|*/ if ((range > 0) && (startpos == search_state.outer_pos.search_end))
+/*|*/ goto finish;
+#endif
+ }
+
+ search_state.test_match_resume_pt = rx_test_start;
+ /* do interrupted for entry point... */
+ case rx_outer_test:
+ /* ...do continued */
+ {
+ goto test_match;
+ test_returns_to_search:
+ switch (test_state)
+ {
+ case rx_test_continuation:
+ pc = rx_outer_test;
+ goto return_continuation;
+ case rx_test_error:
+ search_state.ret_val = rx_search_error;
+ goto finish;
+ case rx_test_fail:
+ break;
+ case rx_test_ok:
+ goto finish;
+ }
+ search_state.outer_pos.pos += search_state.outer_pos.search_direction;
+ startpos += search_state.outer_pos.search_direction;
+#if 0
+/*|*/ if (search_state.test_pos.pos < search_state.test_pos.end)
+/*|*/ break;
+#endif
+ }
+ /* do interrupted for entry point... */
+ case rx_outer_restore_pos:
+ {
+ int x;
+ x = get_burst (&search_state.outer_pos, app_closure, stop);
+ switch (x)
+ {
+ case rx_get_burst_continuation:
+ pc = rx_outer_restore_pos;
+ goto return_continuation;
+ case rx_get_burst_error:
+ search_state.ret_val = rx_search_error;
+ goto finish;
+ case rx_get_burst_no_more:
+ if (rxb->can_match_empty)
+ break;
+ goto finish;
+ case rx_get_burst_ok:
+ break;
+ }
+ } /* } while (...see below...) */
+
+ if ((search_state.outer_pos.search_direction == 1)
+ ? (startpos <= search_state.outer_pos.search_end)
+ : (startpos > search_state.outer_pos.search_end))
+ goto pseudo_do;
+
+
+ finish:
+ uninit_fastmap (rxb, &search_state);
+ if (search_state.start_super)
+ rx_unlock_superstate (&rxb->rx, search_state.start_super);
+
+#ifdef regex_malloc
+ if (search_state.lparen) free (search_state.lparen);
+ if (search_state.rparen) free (search_state.rparen);
+ if (search_state.best_lpspace) free (search_state.best_lpspace);
+ if (search_state.best_rpspace) free (search_state.best_rpspace);
+#endif
+ return search_state.ret_val;
+ }
+
+
+ test_match:
+ {
+ enum rx_test_match_entry test_pc;
+ int inx;
+ test_pc = search_state.test_match_resume_pt;
+ if (test_pc == rx_test_start)
+ {
+#ifdef RX_DEBUG
+ search_state.backtrack_depth = 0;
+#endif
+ search_state.last_l = search_state.last_r = 0;
+ search_state.lparen[0] = startpos;
+ search_state.super = search_state.start_super;
+ search_state.c = search_state.nfa_choice;
+ search_state.test_pos.pos = search_state.outer_pos.pos - 1;
+ search_state.test_pos.string = search_state.outer_pos.string;
+ search_state.test_pos.end = search_state.outer_pos.end;
+ search_state.test_pos.offset = search_state.outer_pos.offset;
+ search_state.test_pos.size = search_state.outer_pos.size;
+ search_state.test_pos.search_direction = 1;
+ search_state.counter_stack = 0;
+ search_state.backtrack_stack = 0;
+ search_state.backtrack_frame_bytes =
+ (sizeof (struct rx_backtrack_frame)
+ + (rxb->match_regs_on_stack
+ ? sizeof (regoff_t) * (search_state.num_regs + 1) * 2
+ : 0));
+ search_state.chunk_bytes = search_state.backtrack_frame_bytes * 64;
+ search_state.test_ret = rx_test_line_finished;
+ search_state.could_have_continued = 0;
+ }
+ /* This is while (1)...except that the body of the loop is interrupted
+ * by some alternative entry points.
+ */
+ pseudo_while_1:
+ switch (test_pc)
+ {
+ case rx_test_cache_hit_loop:
+ goto resume_continuation_1;
+ case rx_test_backreference_check:
+ goto resume_continuation_2;
+ case rx_test_backtrack_return:
+ goto resume_continuation_3;
+ case rx_test_start:
+#ifdef RX_DEBUG
+ /* There is a search tree with every node as set of deterministic
+ * transitions in the super nfa. For every branch of a
+ * backtrack point is an edge in the tree.
+ * This counts up a pre-order of nodes in that tree.
+ * It's saved on the search stack and printed when debugging.
+ */
+ search_state.line_no = 0;
+ search_state.lines_found = 0;
+#endif
+
+ top_of_cycle:
+ /* A superstate is basicly a transition table, indexed by
+ * characters from the string being tested, and containing
+ * RX_INX (`instruction frame') structures.
+ */
+ search_state.ifr = &search_state.super->transitions [search_state.c];
+
+ recurse_test_match:
+ /* This is the point to which control is sent when the
+ * test matcher `recurses'. Before jumping here, some variables
+ * need to be saved on the stack and the next instruction frame
+ * has to be computed.
+ */
+
+ restart:
+ /* Some instructions don't advance the matcher, but just
+ * carry out some side effects and fetch a new instruction.
+ * To dispatch that new instruction, `goto restart'.
+ */
+
+ {
+ struct rx_inx * next_tr_table;
+ struct rx_inx * this_tr_table;
+ /* The fastest route through the loop is when the instruction
+ * is RX_NEXT_CHAR. This case is detected when SEARCH_STATE.IFR->DATA
+ * is non-zero. In that case, it points to the next
+ * superstate.
+ *
+ * This allows us to not bother fetching the bytecode.
+ */
+ next_tr_table = (struct rx_inx *)search_state.ifr->data;
+ this_tr_table = search_state.super->transitions;
+ while (next_tr_table)
+ {
+#ifdef RX_DEBUG_0
+ if (rx_debug_trace)
+ {
+ struct rx_superset * setp;
+
+ fprintf (stderr, "%d %d>> re_next_char @ %d (%d)",
+ search_state.line_no,
+ search_state.backtrack_depth,
+ (search_state.test_pos.pos - search_state.test_pos.string
+ + search_state.test_pos.offset), search_state.c);
+
+ search_state.super =
+ ((struct rx_superstate *)
+ ((char *)this_tr_table
+ - ((unsigned long)
+ ((struct rx_superstate *)0)->transitions)));
+
+ setp = search_state.super->contents;
+ fprintf (stderr, " superstet (rx=%d, &=%x: ",
+ rxb->rx.rx_id, setp);
+ while (setp)
+ {
+ fprintf (stderr, "%d ", setp->id);
+ setp = setp->cdr;
+ }
+ fprintf (stderr, "\n");
+ }
+#endif
+ this_tr_table = next_tr_table;
+ ++search_state.test_pos.pos;
+ if (search_state.test_pos.pos == search_state.test_pos.end)
+ {
+ int burst_state;
+ try_burst_1:
+ burst_state = get_burst (&search_state.test_pos,
+ app_closure, stop);
+ switch (burst_state)
+ {
+ case rx_get_burst_continuation:
+ search_state.saved_this_tr_table = this_tr_table;
+ search_state.saved_next_tr_table = next_tr_table;
+ test_pc = rx_test_cache_hit_loop;
+ goto test_return_continuation;
+
+ resume_continuation_1:
+ /* Continuation one jumps here to do its work: */
+ search_state.saved_this_tr_table = this_tr_table;
+ search_state.saved_next_tr_table = next_tr_table;
+ goto try_burst_1;
+
+ case rx_get_burst_ok:
+ /* get_burst succeeded...keep going */
+ break;
+
+ case rx_get_burst_no_more:
+ search_state.test_ret = rx_test_line_finished;
+ search_state.could_have_continued = 1;
+ goto test_do_return;
+
+ case rx_get_burst_error:
+ /* An error... */
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+ }
+ search_state.c = *search_state.test_pos.pos;
+ search_state.ifr = this_tr_table + search_state.c;
+ next_tr_table = (struct rx_inx *)search_state.ifr->data;
+ } /* Fast loop through cached transition tables */
+
+ /* Here when we ran out of cached next-char transitions.
+ * So, it will be necessary to do a more expensive
+ * dispatch on the current instruction. The superstate
+ * pointer is allowed to become invalid during next-char
+ * transitions -- now we must bring it up to date.
+ */
+ search_state.super =
+ ((struct rx_superstate *)
+ ((char *)this_tr_table
+ - ((unsigned long)
+ ((struct rx_superstate *)0)->transitions)));
+ }
+
+ /* We've encountered an instruction other than next-char.
+ * Dispatch that instruction:
+ */
+ inx = (int)search_state.ifr->inx;
+#ifdef RX_DEBUG_0
+ if (rx_debug_trace)
+ {
+ struct rx_superset * setp = search_state.super->contents;
+
+ fprintf (stderr, "%d %d>> %s @ %d (%d)", search_state.line_no,
+ search_state.backtrack_depth,
+ inx_names[inx],
+ (search_state.test_pos.pos - search_state.test_pos.string
+ + (test_pos.half == 0 ? 0 : size1)), search_state.c);
+
+ fprintf (stderr, " superstet (rx=%d, &=%x: ",
+ rxb->rx.rx_id, setp);
+ while (setp)
+ {
+ fprintf (stderr, "%d ", setp->id);
+ setp = setp->cdr;
+ }
+ fprintf (stderr, "\n");
+ }
+#endif
+ switch ((enum rx_opcode)inx)
+ {
+ case rx_do_side_effects:
+
+ /* RX_DO_SIDE_EFFECTS occurs when we cross epsilon
+ * edges associated with parentheses, backreferencing, etc.
+ */
+ {
+ struct rx_distinct_future * df =
+ (struct rx_distinct_future *)search_state.ifr->data_2;
+ struct rx_se_list * el = df->effects;
+ /* Side effects come in lists. This walks down
+ * a list, dispatching.
+ */
+ while (el)
+ {
+ long effect;
+ effect = (long)el->car;
+ if (effect < 0)
+ {
+#ifdef RX_DEBUG_0
+ if (rx_debug_trace)
+ {
+ struct rx_superset * setp = search_state.super->contents;
+
+ fprintf (stderr, "....%d %d>> %s\n", search_state.line_no,
+ search_state.backtrack_depth,
+ efnames[-effect]);
+ }
+#endif
+ switch ((enum re_side_effects) effect)
+
+ {
+ case re_se_pushback:
+ search_state.ifr = &df->future_frame;
+ if (!search_state.ifr->data)
+ {
+ struct rx_superstate * sup;
+ sup = search_state.super;
+ rx_lock_superstate (rx, sup);
+ if (!rx_handle_cache_miss (&rxb->rx,
+ search_state.super,
+ search_state.c,
+ (search_state.ifr
+ ->data_2)))
+ {
+ rx_unlock_superstate (rx, sup);
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+ rx_unlock_superstate (rx, sup);
+ }
+ /* --search_state.test_pos.pos; */
+ search_state.c = 't';
+ search_state.super
+ = ((struct rx_superstate *)
+ ((char *)search_state.ifr->data
+ - (long)(((struct rx_superstate *)0)
+ ->transitions)));
+ goto top_of_cycle;
+ break;
+ case re_se_push0:
+ {
+ struct rx_counter_frame * old_cf
+ = (search_state.counter_stack
+ ? ((struct rx_counter_frame *)
+ search_state.counter_stack->sp)
+ : 0);
+ struct rx_counter_frame * cf;
+ PUSH (search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ cf = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ cf->tag = re_se_iter;
+ cf->val = 0;
+ cf->inherited_from = 0;
+ cf->cdr = old_cf;
+ break;
+ }
+ case re_se_fail:
+ goto test_do_return;
+ case re_se_begbuf:
+ if (!AT_STRINGS_BEG ())
+ goto test_do_return;
+ break;
+ case re_se_endbuf:
+ if (!AT_STRINGS_END ())
+ goto test_do_return;
+ break;
+ case re_se_wordbeg:
+ if ( LETTER_P (&search_state.test_pos, 1)
+ && ( AT_STRINGS_BEG()
+ || !LETTER_P (&search_state.test_pos, 0)))
+ break;
+ else
+ goto test_do_return;
+ case re_se_wordend:
+ if ( !AT_STRINGS_BEG ()
+ && LETTER_P (&search_state.test_pos, 0)
+ && (AT_STRINGS_END ()
+ || !LETTER_P (&search_state.test_pos, 1)))
+ break;
+ else
+ goto test_do_return;
+ case re_se_wordbound:
+ if (AT_WORD_BOUNDARY (&search_state.test_pos))
+ break;
+ else
+ goto test_do_return;
+ case re_se_notwordbound:
+ if (!AT_WORD_BOUNDARY (&search_state.test_pos))
+ break;
+ else
+ goto test_do_return;
+ case re_se_hat:
+ if (AT_STRINGS_BEG ())
+ {
+ if (rxb->not_bol)
+ goto test_do_return;
+ else
+ break;
+ }
+ else
+ {
+ char pos_c = *search_state.test_pos.pos;
+ if ( (SRCH_TRANSLATE (pos_c)
+ == SRCH_TRANSLATE('\n'))
+ && rxb->newline_anchor)
+ break;
+ else
+ goto test_do_return;
+ }
+ case re_se_dollar:
+ if (AT_STRINGS_END ())
+ {
+ if (rxb->not_eol)
+ goto test_do_return;
+ else
+ break;
+ }
+ else
+ {
+ if ( ( SRCH_TRANSLATE (fetch_char
+ (&search_state.test_pos, 1,
+ app_closure, stop))
+ == SRCH_TRANSLATE ('\n'))
+ && rxb->newline_anchor)
+ break;
+ else
+ goto test_do_return;
+ }
+
+ case re_se_try:
+ /* This is the first side effect in every
+ * expression.
+ *
+ * FOR NO GOOD REASON...get rid of it...
+ */
+ break;
+
+ case re_se_pushpos:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+ struct rx_counter_frame * old_cf
+ = (search_state.counter_stack
+ ? ((struct rx_counter_frame *)
+ search_state.counter_stack->sp)
+ : 0);
+ struct rx_counter_frame * cf;
+ PUSH(search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ cf = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ cf->tag = re_se_pushpos;
+ cf->val = urhere;
+ cf->inherited_from = 0;
+ cf->cdr = old_cf;
+ break;
+ }
+
+ case re_se_chkpos:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+ struct rx_counter_frame * cf
+ = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ if (cf->val == urhere)
+ goto test_do_return;
+ cf->val = urhere;
+ break;
+ }
+ break;
+
+ case re_se_poppos:
+ POP(search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ break;
+
+
+ case re_se_at_dot:
+ case re_se_syntax:
+ case re_se_not_syntax:
+#ifdef emacs
+ /*
+ * this release lacks emacs support
+ */
+#endif
+ break;
+ case re_se_win:
+ case re_se_lparen:
+ case re_se_rparen:
+ case re_se_backref:
+ case re_se_iter:
+ case re_se_end_iter:
+ case re_se_tv:
+ case re_floogle_flap:
+ search_state.ret_val = 0;
+ goto test_do_return;
+ }
+ }
+ else
+ {
+#ifdef RX_DEBUG_0
+ if (rx_debug_trace)
+ fprintf (stderr, "....%d %d>> %s %d %d\n", search_state.line_no,
+ search_state.backtrack_depth,
+ efnames2[rxb->se_params [effect].se],
+ rxb->se_params [effect].op1,
+ rxb->se_params [effect].op2);
+#endif
+ switch (rxb->se_params [effect].se)
+ {
+ case re_se_win:
+ /* This side effect indicates that we've
+ * found a match, though not necessarily the
+ * best match. This is a fancy assignment to
+ * register 0 unless the caller didn't
+ * care about registers. In which case,
+ * this stops the match.
+ */
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+
+ if ( (search_state.best_last_r < 0)
+ || (urhere + 1 > search_state.best_rparen[0]))
+ {
+ /* Record the best known and keep
+ * looking.
+ */
+ int x;
+ for (x = 0; x <= search_state.last_l; ++x)
+ search_state.best_lparen[x] = search_state.lparen[x];
+ search_state.best_last_l = search_state.last_l;
+ for (x = 0; x <= search_state.last_r; ++x)
+ search_state.best_rparen[x] = search_state.rparen[x];
+ search_state.best_rparen[0] = urhere + 1;
+ search_state.best_last_r = search_state.last_r;
+ }
+ /* If we're not reporting the match-length
+ * or other register info, we need look no
+ * further.
+ */
+ if (search_state.first_found)
+ {
+ search_state.test_ret = rx_test_found_first;
+ goto test_do_return;
+ }
+ }
+ break;
+ case re_se_lparen:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+
+ int reg = rxb->se_params [effect].op1;
+#if 0
+ if (reg > search_state.last_l)
+#endif
+ {
+ search_state.lparen[reg] = urhere + 1;
+ /* In addition to making this assignment,
+ * we now know that lower numbered regs
+ * that haven't already been assigned,
+ * won't be. We make sure they're
+ * filled with -1, so they can be
+ * recognized as unassigned.
+ */
+ if (search_state.last_l < reg)
+ while (++search_state.last_l < reg)
+ search_state.lparen[search_state.last_l] = -1;
+ }
+ break;
+ }
+
+ case re_se_rparen:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+ int reg = rxb->se_params [effect].op1;
+ search_state.rparen[reg] = urhere + 1;
+ if (search_state.last_r < reg)
+ {
+ while (++search_state.last_r < reg)
+ search_state.rparen[search_state.last_r]
+ = -1;
+ }
+ break;
+ }
+
+ case re_se_backref:
+ {
+ int reg = rxb->se_params [effect].op1;
+ if ( reg > search_state.last_r
+ || search_state.rparen[reg] < 0)
+ goto test_do_return;
+
+ {
+ int backref_status;
+ check_backreference:
+ backref_status
+ = back_check (&search_state.test_pos,
+ search_state.lparen[reg],
+ search_state.rparen[reg],
+ search_state.translate,
+ app_closure,
+ stop);
+ switch (backref_status)
+ {
+ case rx_back_check_continuation:
+ search_state.saved_reg = reg;
+ test_pc = rx_test_backreference_check;
+ goto test_return_continuation;
+ resume_continuation_2:
+ reg = search_state.saved_reg;
+ goto check_backreference;
+ case rx_back_check_fail:
+ /* Fail */
+ goto test_do_return;
+ case rx_back_check_pass:
+ /* pass --
+ * test_pos now advanced to last
+ * char matched by backref
+ */
+ break;
+ }
+ }
+ break;
+ }
+ case re_se_iter:
+ {
+ struct rx_counter_frame * csp
+ = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ if (csp->val == rxb->se_params[effect].op2)
+ goto test_do_return;
+ else
+ ++csp->val;
+ break;
+ }
+ case re_se_end_iter:
+ {
+ struct rx_counter_frame * csp
+ = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ if (csp->val < rxb->se_params[effect].op1)
+ goto test_do_return;
+ else
+ {
+ struct rx_counter_frame * source = csp;
+ while (source->inherited_from)
+ source = source->inherited_from;
+ if (!source || !source->cdr)
+ {
+ POP(search_state.counter_stack,
+ sizeof(struct rx_counter_frame));
+ }
+ else
+ {
+ source = source->cdr;
+ csp->val = source->val;
+ csp->tag = source->tag;
+ csp->cdr = 0;
+ csp->inherited_from = source;
+ }
+ }
+ break;
+ }
+ case re_se_tv:
+ /* is a noop */
+ break;
+ case re_se_try:
+ case re_se_pushback:
+ case re_se_push0:
+ case re_se_pushpos:
+ case re_se_chkpos:
+ case re_se_poppos:
+ case re_se_at_dot:
+ case re_se_syntax:
+ case re_se_not_syntax:
+ case re_se_begbuf:
+ case re_se_hat:
+ case re_se_wordbeg:
+ case re_se_wordbound:
+ case re_se_notwordbound:
+ case re_se_wordend:
+ case re_se_endbuf:
+ case re_se_dollar:
+ case re_se_fail:
+ case re_floogle_flap:
+ search_state.ret_val = 0;
+ goto test_do_return;
+ }
+ }
+ el = el->cdr;
+ }
+ /* Now the side effects are done,
+ * so get the next instruction.
+ * and move on.
+ */
+ search_state.ifr = &df->future_frame;
+ goto restart;
+ }
+
+ case rx_backtrack_point:
+ {
+ /* A backtrack point indicates that we've reached a
+ * non-determinism in the superstate NFA. This is a
+ * loop that exhaustively searches the possibilities.
+ *
+ * A backtracking strategy is used. We keep track of what
+ * registers are valid so we can erase side effects.
+ *
+ * First, make sure there is some stack space to hold
+ * our state.
+ */
+
+ struct rx_backtrack_frame * bf;
+
+ PUSH(search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+#ifdef RX_DEBUG_0
+ ++search_state.backtrack_depth;
+#endif
+
+ bf = ((struct rx_backtrack_frame *)
+ search_state.backtrack_stack->sp);
+ {
+ bf->stk_super = search_state.super;
+ /* We prevent the current superstate from being
+ * deleted from the superstate cache.
+ */
+ rx_lock_superstate (&rxb->rx, search_state.super);
+#ifdef RX_DEBUG_0
+ bf->stk_search_state.line_no = search_state.line_no;
+#endif
+ bf->stk_c = search_state.c;
+ bf->stk_test_pos = search_state.test_pos;
+ bf->stk_last_l = search_state.last_l;
+ bf->stk_last_r = search_state.last_r;
+ bf->df = ((struct rx_super_edge *)
+ search_state.ifr->data_2)->options;
+ bf->first_df = bf->df;
+ bf->counter_stack_sp = (search_state.counter_stack
+ ? search_state.counter_stack->sp
+ : 0);
+ bf->stk_test_ret = search_state.test_ret;
+ if (rxb->match_regs_on_stack)
+ {
+ int x;
+ regoff_t * stk =
+ (regoff_t *)((char *)bf + sizeof (*bf));
+ for (x = 0; x <= search_state.last_l; ++x)
+ stk[x] = search_state.lparen[x];
+ stk += x;
+ for (x = 0; x <= search_state.last_r; ++x)
+ stk[x] = search_state.rparen[x];
+ }
+ }
+
+ /* Here is a while loop whose body is mainly a function
+ * call and some code to handle a return from that
+ * function.
+ *
+ * From here on for the rest of `case backtrack_point' it
+ * is unsafe to assume that the search_state copies of
+ * variables saved on the backtracking stack are valid
+ * -- so read their values from the backtracking stack.
+ *
+ * This lets us use one generation fewer stack saves in
+ * the call-graph of a search.
+ */
+
+ while_non_det_options:
+#ifdef RX_DEBUG_0
+ ++search_state.lines_found;
+ if (rx_debug_trace)
+ fprintf (stderr, "@@@ %d calls %d @@@\n",
+ search_state.line_no, search_state.lines_found);
+
+ search_state.line_no = search_state.lines_found;
+#endif
+
+ if (bf->df->next_same_super_edge[0] == bf->first_df)
+ {
+ /* This is a tail-call optimization -- we don't recurse
+ * for the last of the possible futures.
+ */
+ search_state.ifr = (bf->df->effects
+ ? &bf->df->side_effects_frame
+ : &bf->df->future_frame);
+
+ rx_unlock_superstate (&rxb->rx, search_state.super);
+ POP(search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+#ifdef RX_DEBUG
+ --search_state.backtrack_depth;
+#endif
+ goto restart;
+ }
+ else
+ {
+ if (search_state.counter_stack)
+ {
+ struct rx_counter_frame * old_cf
+ = ((struct rx_counter_frame *)search_state.counter_stack->sp);
+ struct rx_counter_frame * cf;
+ PUSH(search_state.counter_stack, sizeof (struct rx_counter_frame));
+ cf = ((struct rx_counter_frame *)search_state.counter_stack->sp);
+ cf->tag = old_cf->tag;
+ cf->val = old_cf->val;
+ cf->inherited_from = old_cf;
+ cf->cdr = 0;
+ }
+ /* `Call' this test-match block */
+ search_state.ifr = (bf->df->effects
+ ? &bf->df->side_effects_frame
+ : &bf->df->future_frame);
+ goto recurse_test_match;
+ }
+
+ /* Returns in this block are accomplished by
+ * goto test_do_return. There are two cases.
+ * If there is some search-stack left,
+ * then it is a return from a `recursive' call.
+ * If there is no search-stack left, then
+ * we should return to the fastmap/search loop.
+ */
+
+ test_do_return:
+
+ if (!search_state.backtrack_stack)
+ {
+#ifdef RX_DEBUG_0
+ if (rx_debug_trace)
+ fprintf (stderr, "!!! %d bails returning %d !!!\n",
+ search_state.line_no, search_state.test_ret);
+#endif
+
+ /* No more search-stack -- this test is done. */
+ if (search_state.test_ret != rx_test_internal_error)
+ goto return_from_test_match;
+ else
+ goto error_in_testing_match;
+ }
+
+ /* Returning from a recursive call to
+ * the test match block:
+ */
+
+ bf = ((struct rx_backtrack_frame *)
+ search_state.backtrack_stack->sp);
+#ifdef RX_DEBUG_0
+ if (rx_debug_trace)
+ fprintf (stderr, "+++ %d returns %d (to %d)+++\n",
+ search_state.line_no,
+ search_state.test_ret,
+ bf->stk_search_state.line_no);
+#endif
+
+ while (search_state.counter_stack
+ && (!bf->counter_stack_sp
+ || (bf->counter_stack_sp
+ != search_state.counter_stack->sp)))
+ {
+ POP(search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ }
+
+ if (search_state.test_ret == rx_test_internal_error)
+ {
+ POP (search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+
+ /* If a non-longest match was found and that is good
+ * enough, return immediately.
+ */
+ if ( (search_state.test_ret == rx_test_found_first)
+ && search_state.first_found)
+ {
+ rx_unlock_superstate (&rxb->rx, bf->stk_super);
+ POP (search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+ goto test_do_return;
+ }
+
+ search_state.test_ret = bf->stk_test_ret;
+ search_state.last_l = bf->stk_last_l;
+ search_state.last_r = bf->stk_last_r;
+ bf->df = bf->df->next_same_super_edge[0];
+ search_state.super = bf->stk_super;
+ search_state.c = bf->stk_c;
+#ifdef RX_DEBUG_0
+ search_state.line_no = bf->stk_search_state.line_no;
+#endif
+
+ if (rxb->match_regs_on_stack)
+ {
+ int x;
+ regoff_t * stk =
+ (regoff_t *)((char *)bf + sizeof (*bf));
+ for (x = 0; x <= search_state.last_l; ++x)
+ search_state.lparen[x] = stk[x];
+ stk += x;
+ for (x = 0; x <= search_state.last_r; ++x)
+ search_state.rparen[x] = stk[x];
+ }
+
+ {
+ int x;
+ try_burst_2:
+ x = get_burst (&bf->stk_test_pos, app_closure, stop);
+ switch (x)
+ {
+ case rx_get_burst_continuation:
+ search_state.saved_bf = bf;
+ test_pc = rx_test_backtrack_return;
+ goto test_return_continuation;
+ resume_continuation_3:
+ bf = search_state.saved_bf;
+ goto try_burst_2;
+ case rx_get_burst_no_more:
+ /* Since we've been here before, it is some kind of
+ * error that we can't return.
+ */
+ case rx_get_burst_error:
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ case rx_get_burst_ok:
+ break;
+ }
+ }
+ search_state.test_pos = bf->stk_test_pos;
+ goto while_non_det_options;
+ }
+
+
+ case rx_cache_miss:
+ /* Because the superstate NFA is lazily constructed,
+ * and in fact may erode from underneath us, we sometimes
+ * have to construct the next instruction from the hard way.
+ * This invokes one step in the lazy-conversion.
+ */
+ search_state.ifr = rx_handle_cache_miss (&rxb->rx,
+ search_state.super,
+ search_state.c,
+ search_state.ifr->data_2);
+ if (!search_state.ifr)
+ {
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+ goto restart;
+
+ case rx_backtrack:
+ /* RX_BACKTRACK means that we've reached the empty
+ * superstate, indicating that match can't succeed
+ * from this point.
+ */
+ goto test_do_return;
+
+ case rx_next_char:
+ case rx_error_inx:
+ case rx_num_instructions:
+ search_state.ret_val = 0;
+ goto test_do_return;
+ }
+ goto pseudo_while_1;
+ }
+
+ /* Healthy exits from the test-match loop do a
+ * `goto return_from_test_match' On the other hand,
+ * we might end up here.
+ */
+ error_in_testing_match:
+ test_state = rx_test_error;
+ goto test_returns_to_search;
+
+ /***** fastmap/search loop body
+ * considering the results testing for a match
+ */
+
+ return_from_test_match:
+
+ if (search_state.best_last_l >= 0)
+ {
+ if (regs && (regs->start != search_state.best_lparen))
+ {
+ bcopy (search_state.best_lparen, regs->start,
+ regs->num_regs * sizeof (int));
+ bcopy (search_state.best_rparen, regs->end,
+ regs->num_regs * sizeof (int));
+ }
+ if (regs && !rxb->no_sub)
+ {
+ int q;
+ int bound = (regs->num_regs > search_state.num_regs
+ ? regs->num_regs
+ : search_state.num_regs);
+ regoff_t * s = regs->start;
+ regoff_t * e = regs->end;
+ for (q = search_state.best_last_l + 1; q < bound; ++q)
+ s[q] = e[q] = -1;
+ }
+ search_state.ret_val = search_state.best_lparen[0];
+ test_state = rx_test_ok;
+ goto test_returns_to_search;
+ }
+ else
+ {
+ test_state = rx_test_fail;
+ goto test_returns_to_search;
+ }
+
+ test_return_continuation:
+ search_state.test_match_resume_pt = test_pc;
+ test_state = rx_test_continuation;
+ goto test_returns_to_search;
+ }
+}
+
+
+
+#endif /* RX_WANT_RX_DEFS */
+
+
+
+#else /* RX_WANT_SE_DEFS */
+ /* Integers are used to represent side effects.
+ *
+ * Simple side effects are given negative integer names by these enums.
+ *
+ * Non-negative names are reserved for complex effects.
+ *
+ * Complex effects are those that take arguments. For example,
+ * a register assignment associated with a group is complex because
+ * it requires an argument to tell which group is being matched.
+ *
+ * The integer name of a complex effect is an index into rxb->se_params.
+ */
+
+ RX_DEF_SE(1, re_se_try, = -1) /* Epsilon from start state */
+
+ RX_DEF_SE(0, re_se_pushback, = re_se_try - 1)
+ RX_DEF_SE(0, re_se_push0, = re_se_pushback -1)
+ RX_DEF_SE(0, re_se_pushpos, = re_se_push0 - 1)
+ RX_DEF_SE(0, re_se_chkpos, = re_se_pushpos -1)
+ RX_DEF_SE(0, re_se_poppos, = re_se_chkpos - 1)
+
+ RX_DEF_SE(1, re_se_at_dot, = re_se_poppos - 1) /* Emacs only */
+ RX_DEF_SE(0, re_se_syntax, = re_se_at_dot - 1) /* Emacs only */
+ RX_DEF_SE(0, re_se_not_syntax, = re_se_syntax - 1) /* Emacs only */
+
+ RX_DEF_SE(1, re_se_begbuf, = re_se_not_syntax - 1) /* match beginning of buffer */
+ RX_DEF_SE(1, re_se_hat, = re_se_begbuf - 1) /* match beginning of line */
+
+ RX_DEF_SE(1, re_se_wordbeg, = re_se_hat - 1)
+ RX_DEF_SE(1, re_se_wordbound, = re_se_wordbeg - 1)
+ RX_DEF_SE(1, re_se_notwordbound, = re_se_wordbound - 1)
+
+ RX_DEF_SE(1, re_se_wordend, = re_se_notwordbound - 1)
+ RX_DEF_SE(1, re_se_endbuf, = re_se_wordend - 1)
+
+ /* This fails except at the end of a line.
+ * It deserves to go here since it is typicly one of the last steps
+ * in a match.
+ */
+ RX_DEF_SE(1, re_se_dollar, = re_se_endbuf - 1)
+
+ /* Simple effects: */
+ RX_DEF_SE(1, re_se_fail, = re_se_dollar - 1)
+
+ /* Complex effects. These are used in the 'se' field of
+ * a struct re_se_params. Indexes into the se array
+ * are stored as instructions on nfa edges.
+ */
+ RX_DEF_CPLX_SE(1, re_se_win, = 0)
+ RX_DEF_CPLX_SE(1, re_se_lparen, = re_se_win + 1)
+ RX_DEF_CPLX_SE(1, re_se_rparen, = re_se_lparen + 1)
+ RX_DEF_CPLX_SE(0, re_se_backref, = re_se_rparen + 1)
+ RX_DEF_CPLX_SE(0, re_se_iter, = re_se_backref + 1)
+ RX_DEF_CPLX_SE(0, re_se_end_iter, = re_se_iter + 1)
+ RX_DEF_CPLX_SE(0, re_se_tv, = re_se_end_iter + 1)
+
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/libg++/src/shlib_version b/gnu/lib/libg++/libg++/src/shlib_version
new file mode 100644
index 00000000000..012c14171d3
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/shlib_version
@@ -0,0 +1,2 @@
+major=3
+minor=0
diff --git a/gnu/lib/libg++/libg++/src/sqrt.cc b/gnu/lib/libg++/libg++/src/sqrt.cc
new file mode 100644
index 00000000000..622895eed45
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/std.h b/gnu/lib/libg++/libg++/src/std.h
new file mode 100644
index 00000000000..2cd73f24386
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _std_h
+#define _std_h 1
+
+#include <_G_config.h>
+#include <stddef>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include <cstdio>
+#include <cerrno>
+#include <fcntl.h>
+
+extern "C" {
+int strcasecmp _G_ARGS((const char*, const char*));
+}
+
+#endif
diff --git a/gnu/lib/libg++/libg++/src/str.cc b/gnu/lib/libg++/libg++/src/str.cc
new file mode 100644
index 00000000000..bd8bc8a28d1
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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++/src/strclass.h b/gnu/lib/libg++/libg++/src/strclass.h
new file mode 100644
index 00000000000..57dbcc8cf90
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/strclass.h
@@ -0,0 +1,5 @@
+#ifndef _strclass_h
+#define _strclass_h
+#include <String.h>
+typedef class String string;
+#endif
diff --git a/gnu/lib/libg++/libg++/src/swap.h b/gnu/lib/libg++/libg++/src/swap.h
new file mode 100644
index 00000000000..005cb0e4648
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/swap.h
@@ -0,0 +1,3 @@
+/* From Ron Guillmette; apparently needed for Hansen's code */
+
+#define swap(a,b) ({ typeof(a) temp = (a); (a) = (b); (b) = temp; })
diff --git a/gnu/lib/libg++/libg++/src/sysent.h b/gnu/lib/libg++/libg++/src/sysent.h
new file mode 100644
index 00000000000..0535f38e934
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/sysent.h
@@ -0,0 +1,2 @@
+/* Provided for compatibity with other C++ compilers ONLY! */
+#include <std.h>
diff --git a/gnu/lib/libg++/libg++/src/timer.c b/gnu/lib/libg++/libg++/src/timer.c
new file mode 100644
index 00000000000..a7e2242d529
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/timer.c
@@ -0,0 +1,165 @@
+/*
+Copyright (C) 1990, 1992, 1995 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+/* 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>
+#include <sys/types.h>
+#if _G_HAVE_SYS_RESOURCE
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#if !_G_HAVE_SYS_RESOURCE || !defined(RUSAGE_SELF)
+#if _G_HAVE_SYS_TIMES
+#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 /* ! _G_HAVE_SYS_TIMES */
+#define USE_CLOCK
+#include <time.h>
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1
+#endif
+clock_t Old_Time;
+clock_t New_Time;
+#endif /* ! _G_HAVE_SYS_TIMES */
+#else /* _G_HAVE_SYS_RESOURCE && defined(RUSAGE_SELF) */
+static struct rusage Old_Time;
+static struct rusage New_Time;
+#endif
+static int Timer_Set = 0;
+
+double
+start_timer()
+{
+ Timer_Set = 1;
+#ifdef USE_CLOCK
+ Old_Time = clock() / CLOCKS_PER_SEC;
+ return((double) Old_Time);
+#else
+#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
+#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_CLOCK
+ New_Time = clock();
+#else
+#ifdef USE_TIMES
+ times(&New_Time);
+#else
+ getrusage(RUSAGE_SELF,&New_Time);
+#endif
+#endif
+ if (Last_Time == 0.0) {
+#ifdef USE_CLOCK
+ return((double) (New_Time - Old_Time) / CLOCKS_PER_SEC);
+#else
+#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
+#endif
+ }
+ else {
+#ifdef USE_CLOCK
+ return((double) New_Time / CLOCKS_PER_SEC - Last_Time);
+#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
+#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(Last_Time)
+ double Last_Time;
+{
+ return TIMER_ERROR_VALUE;
+}
+
+#endif /* timing stuff */
+
+
diff --git a/gnu/lib/libg++/libg++/src/typemacros.h b/gnu/lib/libg++/libg++/src/typemacros.h
new file mode 100644
index 00000000000..f2bd7877e36
--- /dev/null
+++ b/gnu/lib/libg++/libg++/src/typemacros.h
@@ -0,0 +1,8 @@
+#define _T(type) typeof(type)
+#define pointer_to(type) _T(_T(type)*)
+#define member_of(cls,type) _T(_T(type) cls::)
+#define function(res, args) _T(_T(res) args)
+
+#define _xq_yq(x,y) x ## _ ## y
+#define _x_y(x,y) _xq_yq(x,y)
+#define _gensym(stem) _x_y(stem, __LINE__)
diff --git a/gnu/lib/libg++/libg++2netbsd b/gnu/lib/libg++/libg++2netbsd
new file mode 100644
index 00000000000..cac2fe4c8f0
--- /dev/null
+++ b/gnu/lib/libg++/libg++2netbsd
@@ -0,0 +1,643 @@
+#!/usr/gnu/bin/perl
+#
+# $NetBSD: libg++2netbsd,v 1.1.1.1 1996/03/09 00:00:57 phil Exp $
+#
+# Perl script to convert a standard distribution directory for libg++ into
+# a NetBSD source tree.
+#
+# This is done as a script so that as each distribution is released,
+# only changes from the previous one need to be dealt with as
+# modifications to this script and related files. This should
+# reduce the cost of updating from a new release of gcc by an
+# order of magnitude (or more?)
+#
+# Written by Phil Nelson, December 13, 1995. (for libg++-2.7.1)
+#
+
+$version = "2.7.1";
+$srcdir = $ENV{'SRCDIR'};
+if (!$srcdir) { $srcdir = "libg++-$version" };
+$targetdir = "libg++";
+
+# definitions ...
+
+@subdirs = ("include", "include/gen", "libg++", "libg++/genclass",
+ "libg++/src", "libio", "libiostream", "libstdc++",
+ "libstdc++/std", "libstdc++/stl");
+
+@gf = ("ACG.cc", "AllocRing.cc", "Binomial.cc", "BitSet.cc",
+ "BitString.cc", "CursesW.cc", "DLList.cc", "DiscUnif.cc",
+ "Erlang.cc", "Fix.cc", "Fix16.cc", "Fix24.cc", "Geom.cc",
+ "GetOpt.cc", "HypGeom.cc", "Intdouble.cc", "Integer.cc",
+ "LogNorm.cc", "MLCG.cc", "NegExp.cc", "Normal.cc",
+ "Obstack.cc", "Poisson.cc", "RNG.cc", "Random.cc",
+ "Rational.cc", "Regex.cc", "RndInt.cc", "SLList.cc",
+ "SmplHist.cc", "SmplStat.cc", "String.cc", "Uniform.cc",
+ "Weibull.cc", "bitand.c", "bitany.c", "bitblt.c", "bitclear.c",
+ "bitcopy.c", "bitcount.c", "bitinvert.c", "bitlcomp.c",
+ "bitset1.c", "bitxor.c", "builtin.cc", "chr.cc", "compare.cc",
+ "error.cc", "fmtq.cc", "gcd.cc", "hash.cc", "ioob.cc", "lg.cc",
+ "pow.cc", "sqrt.cc", "str.cc", "timer.c");
+
+@gh = ("ACG.h", "AllocRing.h", "Binomial.h", "BitSet.h",
+ "BitString.h", "Complex.h", "CursesW.h", "DLList.h",
+ "DiscUnif.h", "Erlang.h", "Fix.h", "Fix16.h", "Fix24.h",
+ "Geom.h", "GetOpt.h", "HypGeom.h", "Incremental.h",
+ "Integer.h", "Integer.hP", "LogNorm.h", "MLCG.h", "NegExp.h",
+ "Normal.h", "Obstack.h", "Pix.h", "Poisson.h", "RNG.h",
+ "Random.h", "Rational.h", "Regex.h", "RndInt.h", "SLList.h",
+ "SmplHist.h", "SmplStat.h", "String.h", "Uniform.h",
+ "Weibull.h", "bitdo1.h", "bitdo2.h", "bitprims.h", "bool.h",
+ "builtin.h", "compare.h", "generic.h", "getpagesize.h",
+ "libc.h", "minmax.h", "osfcn.h", "std.h", "strclass.h",
+ "swap.h", "sysent.h", "typemacros.h" );
+
+@iosf = ("PlotFile.cc", "SFile.cc", "builtinbuf.cc", "editbuf.cc",
+ "filebuf.cc", "fstream.cc", "indstream.cc", "ioassign.cc",
+ "ioextend.cc", "iomanip.cc", "iostream.cc", "isgetline.cc",
+ "isgetsb.cc", "isscan.cc", "osform.cc", "parsestream.cc",
+ "pfstream.cc", "procbuf.cc", "sbform.cc", "sbgetline.cc",
+ "sbscan.cc", "stdiostream.cc", "stdstrbufs.cc",
+ "stdstreams.cc", "stream.cc", "streambuf.cc", "strstream.cc",
+ "cleanup.c", "filedoalloc.c", "fileops.c", "floatconv.c",
+ "genops.c", "iofclose.c", "iofgetpos.c", "iofread.c",
+ "iofscanf.c", "iofsetpos.c", "iogetdelim.c", "iogetline.c",
+ "ioignore.c", "iopadn.c", "iopopen.c", "ioprims.c",
+ "ioprintf.c", "ioseekoff.c", "ioseekpos.c", "iostrerror.c",
+ "ioungetc.c", "iovfprintf.c", "iovfscanf.c", "outfloat.c",
+ "strops.c", );
+
+@iosh = ("PlotFile.h", "SFile.h", "builtinbuf.h",
+ "editbuf.h", "floatio.h", "fstream.h", "indstream.h",
+ "iolibio.h", "iomanip.h", "iostdio.h", "iostream.h",
+ "iostreamP.h", "istream.h", "libio.h", "libioP.h",
+ "ostream.h", "parsestream.h", "pfstream.h", "procbuf.h",
+ "stdiostream.h", "stream.h", "streambuf.h", "strfile.h",
+ "strstream.h" );
+
+@iof = ("cleanup.c", "filedoalloc.c", "fileops.c", "floatconv.c",
+ "genops.c", "iofclose.c", "iofdopen.c", "iofflush.c",
+ "iofgetpos.c", "iofgets.c", "iofopen.c", "iofprintf.c",
+ "iofputs.c", "iofread.c", "iofscanf.c", "iofsetpos.c",
+ "ioftell.c", "iofwrite.c", "iogetdelim.c", "iogetline.c",
+ "iogets.c", "ioignore.c", "iopadn.c", "ioperror.c",
+ "iopopen.c", "ioprims.c", "ioprintf.c", "ioputs.c",
+ "ioscanf.c", "ioseekoff.c", "ioseekpos.c", "iosetbuffer.c",
+ "iosetvbuf.c", "iosprintf.c", "iosscanf.c", "iostrerror.c",
+ "ioungetc.c", "iovfprintf.c", "iovfscanf.c", "iovsprintf.c",
+ "iovsscanf.c", "outfloat.c", "stdfiles.c", "strops.c");
+
+@iocf = ("iofdopen.c", "iofflush.c", "iofgets.c", "iofopen.c",
+ "iofprintf.c", "iofputs.c", "ioftell.c", "iofwrite.c",
+ "iogets.c", "ioperror.c", "ioputs.c", "ioscanf.c",
+ "iosetbuffer.c", "iosetvbuf.c", "iosprintf.c", "iosscanf.c",
+ "iovsprintf.c", "iovsscanf.c", "stdfiles.c");
+
+@genclf = ("genclass.sh");
+
+@genf = ("AVLMap.ccP", "AVLMap.hP", "AVLSet.ccP", "AVLSet.hP",
+ "AVec.ccP", "AVec.hP", "BSTSet.ccP", "BSTSet.hP", "Bag.ccP",
+ "Bag.hP", "CHBag.ccP", "CHBag.hP", "CHMap.ccP", "CHMap.hP",
+ "CHNode.ccP", "CHNode.hP", "CHSet.ccP", "CHSet.hP",
+ "DLDeque.ccP", "DLDeque.hP", "DLList.ccP", "DLList.hP",
+ "Deque.ccP", "Deque.hP", "FPQueue.ccP", "FPQueue.hP",
+ "FPStack.ccP", "FPStack.hP", "FPlex.ccP", "FPlex.hP",
+ "List.ccP", "List.hP", "MPlex.ccP", "MPlex.hP", "Map.ccP",
+ "Map.hP", "OSLBag.ccP", "OSLBag.hP", "OSLSet.ccP",
+ "OSLSet.hP", "OXPBag.ccP", "OXPBag.hP", "OXPSet.ccP",
+ "OXPSet.hP", "PHPQ.ccP", "PHPQ.hP", "PQ.ccP", "PQ.hP",
+ "PSList.hP", "PVec.hP", "Plex.ccP", "Plex.hP", "Queue.ccP",
+ "Queue.hP", "RAVLMap.ccP", "RAVLMap.hP", "RPlex.ccP",
+ "RPlex.hP", "SLBag.ccP", "SLBag.hP", "SLList.ccP",
+ "SLList.hP", "SLQueue.ccP", "SLQueue.hP", "SLSet.ccP",
+ "SLSet.hP", "SLStack.ccP", "SLStack.hP", "Set.ccP", "Set.hP",
+ "SkipBag.ccP", "SkipBag.hP", "SkipMap.ccP", "SkipMap.hP",
+ "SkipSet.ccP", "SkipSet.hP", "SplayBag.ccP", "SplayBag.hP",
+ "SplayMap.ccP", "SplayMap.hP", "SplayNode.ccP",
+ "SplayNode.hP", "SplayPQ.ccP", "SplayPQ.hP", "SplaySet.ccP",
+ "SplaySet.hP", "Stack.ccP", "Stack.hP", "VHBag.ccP",
+ "VHBag.hP", "VHMap.ccP", "VHMap.hP", "VHSet.ccP", "VHSet.hP",
+ "VOHSet.ccP", "VOHSet.hP", "VQueue.ccP", "VQueue.hP",
+ "VStack.ccP", "VStack.hP", "Vec.ccP", "Vec.hP", "XPBag.ccP",
+ "XPBag.hP", "XPDeque.ccP", "XPDeque.hP", "XPPQ.ccP",
+ "XPPQ.hP", "XPQueue.ccP", "XPQueue.hP", "XPSet.ccP",
+ "XPSet.hP", "XPStack.ccP", "XPStack.hP", "XPlex.ccP",
+ "XPlex.hP", "defs.hP", "intSList.hP", "intVec.hP" );
+
+@lstdcf =("cmathi.cc", "cstdlibi.cc", "cstringi.cc", "exceptioni.cc",
+ "newi.cc", "stddefi.cc", "stdexcepti.cc", "typeinfoi.cc");
+
+@lstdcf2 = ("cstrmain.cc", "cstrio.cc", "fcomplex.cc", "fcomio.cc",
+ "dcomplex.cc", "dcomio.cc", "ldcomplex.cc", "ldcomio.cc");
+
+@lstdcof =("algorithm", "cassert", "cctype", "cerrno", "cfloat",
+ "ciso646", "climits", "clocale", "cmath", "complex",
+ "complex.h", "csetjmp", "csignal", "cstdarg", "cstddef",
+ "cstdio", "cstdlib", "cstring", "ctime", "cwchar",
+ "cwctype", "deque", "exception", "functional", "iterator",
+ "list", "map", "memory", "new", "new.h", "numeric",
+ "queue", "set", "stack", "stddef", "stdexcept", "stl.h",
+ "string", "typeinfo", "utility", "vector", "cinst.cc",
+ "sinst.cc" );
+
+@stdf = ("bastring.cc", "complext.cc");
+
+@stdof = ("bastring.h", "cassert.h", "cctype.h", "cerrno.h",
+ "cfloat.h", "cinst.h", "ciso646.h", "climits.h",
+ "clocale.h", "cmath.h", "complex.h", "complext.h",
+ "csetjmp.h", "csignal.h", "cstdarg.h", "cstddef.h",
+ "cstdio.h", "cstdlib.h", "cstring.h", "ctime.h", "cwchar.h",
+ "cwctype.h", "dcomplex.h", "exception.h", "fcomplex.h",
+ "ldcomplex.h", "new.h", "sinst.h", "stddef.h",
+ "stdexcept.h", "straits.h", "string.h", "typeinfo.h" );
+
+@stlf = ("random.cc", "tempbuf.cc", "tree.cc");
+
+@stlof = ("algo.h", "algobase.h", "bvector.h", "defalloc.h",
+ "deque.h", "faralloc.h", "fdeque.h", "flist.h", "fmap.h",
+ "fmultmap.h", "fmultset.h", "fset.h", "function.h", "hdeque.h",
+ "heap.h", "hlist.h", "hmap.h", "hmultmap.h", "hmultset.h",
+ "hset.h", "hugalloc.h", "hvector.h", "iterator.h", "lbvector.h",
+ "ldeque.h", "list.h", "llist.h", "lmap.h", "lmultmap.h",
+ "lmultset.h", "lngalloc.h", "lset.h", "map.h", "multimap.h",
+ "multiset.h", "neralloc.h", "nmap.h", "nmultmap.h", "nmultset.h",
+ "nset.h", "pair.h", "projectn.h", "set.h", "stack.h", "tempbuf.h",
+ "tree.h", "vector.h");
+
+# sed edit list: file, sed-program
+@sedlist = (
+ "libg++/genclass/genclass.sh", "'s/<VERSION>/$version/g'",
+ "libg++/genclass/genclass.sh",
+ "'s/^PROTODIR=.*\$/PROTODIR=\\/usr\\/include\\/g++\\/gen/g'");
+
+#
+# Utility Subroutines
+#
+
+# &copyfiles (fromdir, todir, list of files);
+sub copyfiles {
+ local ($fdir, $tdir, @list) = @_;
+ local ($f);
+
+ foreach $f (@list) {
+ print " $fdir/$f --> $tdir/$f\n";
+ system ("cp -p $fdir/$f $tdir/$f");
+ }
+}
+
+sub dumpsrcs {
+ local (@names) = @_;
+ local ($count);
+
+ print ODATA "SRCS=\t";
+ $count = 0;
+ foreach $f (@names) {
+ print ODATA "$f ";
+ if ($count == 5) {
+ print ODATA "\\\n";
+ $count = 0;
+ } else {
+ $count += 1;
+ }
+ }
+ if ($count != 0) {
+ print ODATA "\n";
+ }
+}
+
+# Following functions ritten by Christos Zoulas, January 15, 1996.
+
+sub dumparray {
+ local (@names) = @_;
+
+ foreach $f (@names) {
+ print ODATA "$f ";
+ }
+}
+
+sub dumpfrag {
+ @cstrmain = ("REP", "MAIN", "TRAITS", "ADDSS", "ADDPS", "ADDCS", "ADDSP",
+ "ADDSC", "EQSS", "EQPS", "EQSP", "NESS", "NEPS", "NESP",
+ "LTSS", "LTPS", "LTSP", "GTSS", "GTPS", "GTSP", "LESS",
+ "LEPS", "LESP", "GESS", "GEPS", "GESP");
+
+ @complex = ("MAIN", "ADDCC", "ADDCF", "ADDFC", "SUBCC", "SUBCF", "SUBFC",
+ "MULCC", "MULCF", "MULFC", "DIVCC", "DIVCF", "DIVFC", "PLUS",
+ "MINUS", "EQCC", "EQCF", "EQFC", "NECC", "NECF", "NEFC", "ABS",
+ "ARG", "POLAR", "CONJ", "NORM", "COS", "COSH", "EXP", "LOG",
+ "POWCC", "POWCF", "POWCI", "POWFC", "SIN", "SINH", "SQRT");
+
+ @cstrio = ("EXTRACT", "INSERT", "GETLINE");
+
+ @comio = ("EXTRACT", "INSERT");
+
+ %prefix = ("ld", "LD", "d", "D", "f", "F");
+
+ print " Dumping frags\n";
+
+ foreach $f (@lstdcf2) {
+ print ODATA "$f: Makefile\n";
+ print ODATA "\t\@echo Creating $f\n";
+ print ODATA "\t@(for i in ";
+ if ($f eq "cstrmain.cc") {
+ &dumparray(@cstrmain);
+ $inc = "sinst.cc";
+ $fl = "C";
+ }
+ elsif ($f eq "cstrio.cc") {
+ &dumparray(@cstrio);
+ $inc = "sinst.cc";
+ $fl = "C";
+ }
+ elsif ($f =~ /(.*)complex\.cc/) {
+ $fl = $prefix{$1};
+ &dumparray(@complex);
+ $inc = "cinst.cc";
+ }
+ elsif ($f =~ /(.*)comio\.cc/) {
+ $fl = $prefix{$1};
+ &dumparray(@comio);
+ $inc = "cinst.cc";
+ }
+ else {
+ die "Unknown target type $f";
+ }
+ print ODATA "; do \\\n";
+ print ODATA "\t\techo \"#define \$\$i\"; \\\n";
+ print ODATA "\t\tdone;\\\n";
+ print ODATA "\techo '#define $fl';\\\n";
+ print ODATA "\tcat \$(.CURDIR)/$inc) > \$(.TARGET)";
+ print ODATA "\nCLEANFILES+=$f\n\n";
+ }
+}
+
+sub dumprtti {
+ local (@name) = @_;
+
+ print " Dumping rtti for @name\n";
+
+ print ODATA "@name.o: @name.cc\n";
+ print ODATA "\t\@echo \"\$(COMPILE.cc) -frtti \$(.ALLSRC)\"\n";
+ print ODATA "\t\@\$(COMPILE.cc) -frtti \$(.ALLSRC) -o \$(.TARGET).o\n";
+ print ODATA "\t\@\$(LD) -x -r \$(.TARGET).o -o \$(.TARGET)\n";
+ print ODATA "\t\@rm -f \$(.TARGET).o\n";
+ print ODATA "\n";
+
+ print ODATA "@name.po: @name.cc\n";
+ print ODATA "\t\@echo \"\$(COMPILE.cc) -p -frtti \$(.ALLSRC) -o \$(.TARGET)\"\n";
+ print ODATA "\t\@\$(COMPILE.cc) -p -frtti \$(.ALLSRC) -o \$(.TARGET).o\n";
+ print ODATA "\t\@\$(LD) -X -r \$(.TARGET).o -o \$(.TARGET)\n";
+ print ODATA "\t\@rm -f \$(.TARGET).o\n";
+ print ODATA "\n";
+
+ print ODATA "@name.so: @name.cc\n";
+ print ODATA "\t\@echo \"\$(COMPILE.cc) \$(PICFLAG) -frtti \$(.ALLSRC) -o \$(.TARGET)\"\n";
+ print ODATA "\t\@\$(COMPILE.cc) \$(PICFLAG) -frtti \$(.ALLSRC) -o \$(.TARGET).o\n";
+ print ODATA "\t\@\$(LD) -x -r \$(.TARGET).o -o \$(.TARGET)\n";
+ print ODATA "\t\@rm -f \$(.TARGET).o\n";
+ print ODATA "\n";
+}
+
+#
+# Main progarm.
+#
+
+if (!$srcdir) {
+ die "You must define the environment variables SRCDIR.\n"
+}
+print "Making the NetBSD directory tree.\n";
+mkdir ($targetdir,0777);
+foreach $f (@subdirs) {
+ print " -->$f\n";
+ mkdir ("$targetdir/$f",0777);
+}
+
+print "Populating $targetdir.\n";
+&copyfiles ($srcdir, $targetdir, "COPYING");
+
+print "Populating $targetdir/libg++/src\n";
+&copyfiles ("$srcdir/libg++/src", "$targetdir/libg++/src", @gf, @gh);
+# Special file needed.
+&copyfiles ("$srcdir/librx", "$targetdir/libg++/src", "rx.h");
+
+print "Populating $targetdir/libg++/genclass\n";
+&copyfiles ("$srcdir/libg++/genclass", "$targetdir/libg++/genclass", @genclf);
+
+print "Populating $targetdir/libio\n";
+&copyfiles ("$srcdir/libio", "$targetdir/libio", @iocf, @iosf, @iosh);
+
+print "Populating $targetdir/include/gen\n";
+&copyfiles ("$srcdir/libg++/src/gen", "$targetdir/include/gen", @genf);
+
+print "Populating $targetdir/libstdc++\n";
+&copyfiles ("$srcdir/libstdc++", "$targetdir/libstdc++", @lstdcf, @lstdcof);
+
+print "Populating $targetdir/libstdc++/std\n";
+&copyfiles ("$srcdir/libstdc++/std", "$targetdir/libstdc++/std",
+ @stdf, @stdof);
+
+print "Populating $targetdir/libstdc++/stl\n";
+&copyfiles ("$srcdir/libstdc++/stl", "$targetdir/libstdc++/stl",
+ @stlf, @stlof);
+
+#
+# Build makefiles
+#
+
+$first = "True";
+while ($line = <DATA>) {
+ chop ($line);
+ if (substr($line,0,2) eq "%%") {
+ @cmd = split (/ /,$line);
+ if ($cmd[1] eq "file") {
+ print "Building $targetdir/$cmd[2]\n";
+ if ($first eq "") {
+ close (ODATA);
+ } else {
+ $first = "";
+ }
+ open (ODATA, ">$targetdir/$cmd[2]") ||
+ die "Could now create $targetdir/$cmd[2]";
+ } elsif ($cmd[1] eq "srcs") {
+ print " Defining SRCS for $cmd[2]\n";
+ if ($first) {
+ die "Data section must start with a %% file!";
+ }
+ if ($cmd[2] eq "libg++") {
+ &dumpsrcs (@gf);
+ } elsif ($cmd[2] eq "genclass") {
+ &dumpsrcs (@genclf);
+ } elsif ($cmd[2] eq "iostream") {
+ &dumpsrcs (@iosf);
+ } elsif ($cmd[2] eq "io") {
+ &dumpsrcs (@iof);
+ } elsif ($cmd[2] eq "stdc++") {
+ &dumpsrcs (@iosf, @lstdcf, @lstdcf2, @stlf);
+ } else {
+ die "Unknown SRCS command";
+ }
+ } elsif ($cmd[1] eq "rtti") {
+ &dumprtti($cmd[2]);
+ } elsif ($cmd[1] eq "frag") {
+ &dumpfrag();
+ } elsif ($cmd[1] eq "NetBSD") {
+ if ($first) {
+ die "Data section must start with a %% file!";
+ }
+ print ODATA "# \$"."NetBSD".": \$\n";
+ }
+ } else {
+ if ($first) {
+ die "Data section must start with a %% file!";
+ }
+ print ODATA "$line\n";
+ }
+}
+close (ODATA);
+
+#
+# Sed transformations of files
+#
+
+for ($i=0; $i<@sedlist; $i+=2) {
+ $f = $sedlist[$i];
+ $p = $sedlist[$i+1];
+ print "Modifying $f\n";
+ system ("cd $targetdir; sed $p $f > tmp; mv -f tmp $f");
+}
+
+#
+# end of the script
+#
+
+# what follows is the data for makefiles and other special files
+# that need to be created.
+
+__END__
+%% file Makefile
+%% NetBSD
+
+SUBDIR= libg++ libstdc++ # libio libiostream
+
+INCLUDEDIRS= include libg++/src
+
+beforeinstall:
+ install -d -o ${BINOWN} -g ${BINGRP} -m 755 \
+ ${DESTDIR}/usr/include/g++
+ install -d -o ${BINOWN} -g ${BINGRP} -m 755 \
+ ${DESTDIR}/usr/include/g++/gen
+ install -d -o ${BINOWN} -g ${BINGRP} -m 755 \
+ ${DESTDIR}/usr/include/g++/std
+ install -d -o ${BINOWN} -g ${BINGRP} -m 755 \
+ ${DESTDIR}/usr/include/g++/stl
+ @-for i in ${INCLUDEDIRS}; do \
+ echo installing includes from $$i ; \
+ (cd $$i; for j in *.[ih]; do \
+ cmp -s $$j ${DESTDIR}/usr/include/g++/$$j || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 644 $$j \
+ ${DESTDIR}/usr/include/g++/$$j; \
+ done); \
+ done
+ @echo installing includes from include/gen
+ @(cd include/gen ; for j in *.*P; do \
+ cmp -s $$j ${DESTDIR}/usr/include/g++/gen/$$j || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
+ ${DESTDIR}/usr/include/g++/gen/$$j; \
+ done)
+ @echo installing includes from libstdc++/std
+ @(cd libstdc++/std ; for j in *.h; do \
+ cmp -s $$j ${DESTDIR}/usr/libstdc++/g++/std/$$j || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
+ ${DESTDIR}/usr/libstdc++/g++/std/$$j; \
+ done)
+ @echo installing includes from libstdc++/stl
+ @(cd libstdc++/stl ; for j in *.h; do \
+ cmp -s $$j ${DESTDIR}/usr/libstdc++/g++/stl/$$j || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 $$j \
+ ${DESTDIR}/usr/libstdc++/g++/stl/$$j; \
+ done)
+
+.include <bsd.subdir.mk>
+%% file libg++/Makefile
+%% NetBSD
+SUBDIR = src genclass
+
+.include <bsd.subdir.mk>
+%% file libg++/genclass/Makefile
+%% NetBSD
+# Makefile for g++ library genclass
+
+PROG= genclass
+%% srcs genclass
+NOMAN=
+STRIP=
+
+SRCDIR=${.CURDIR}
+
+BINDIR ?= /usr/bin
+
+genclass: genclass.sh
+ cp $(SRCDIR)/genclass.sh genclass
+
+.include <bsd.prog.mk>
+
+%% file libg++/src/Makefile
+%% NetBSD
+
+LIB= g++
+
+%% srcs libg++
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../../include \
+ -I$(.CURDIR)/../../libio -I$(.CURDIR)/../../libstdc++
+CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../../libio
+LDADD= ${DESTDIR}/usr/lib/c++rt0.o -lcurses
+DPADD= ${DESTDIR}/usr/lib/c++rt0.o ${LIBCURSES}
+NOMAN= noman
+LIBCURSES!= printf "xxx:\n\techo \$${LIBCURSES}\n.include <bsd.prog.mk>" |\
+ $(MAKE) -r -s -f - xxx | grep curses
+
+.include <bsd.lib.mk>
+%% file libio/Makefile
+%% NetBSD
+
+LIB= io
+
+%% srcs io
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../include
+CFLAGS+= -I$(.CURDIR)
+NOMAN= noman
+
+.include <bsd.lib.mk>
+%% file libiostream/Makefile
+%% NetBSD
+
+LIB= iostream
+
+%% srcs iostream
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../include \
+ -I$(.CURDIR)/../libio
+CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../libio
+NOMAN= noman
+
+.PATH: $(.CURDIR)/../libio
+
+.include <bsd.lib.mk>
+%% file libstdc++/Makefile
+%% NetBSD
+
+LIB= stdc++
+
+%% srcs stdc++
+
+CXXFLAGS+= -nostdinc++
+CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../libio -I$(.CURDIR)/stl
+NOMAN= noman
+
+.PATH: $(.CURDIR)/../libio $(.CURDIR)/stl
+
+.include <bsd.lib.mk>
+
+%% frag
+%% rtti typeinfoi
+%% rtti stdexcepti
+
+%% file libio/_G_config.h
+/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
+#ifndef _G_config_h
+#define _G_config_h
+#define _G_LIB_VERSION "2.7.1"
+#define _G_NAMES_HAVE_UNDERSCORE 1
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+#define _G_VTABLE_LABEL_PREFIX "__vt$"
+#define _G_HAVE_ST_BLKSIZE 1
+typedef unsigned long _G_clock_t;
+typedef int _G_dev_t;
+typedef long long _G_fpos_t;
+typedef unsigned int _G_gid_t;
+typedef unsigned int _G_ino_t;
+typedef unsigned short _G_mode_t;
+typedef unsigned short _G_nlink_t;
+typedef long long _G_off_t;
+typedef int _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 int _G_uid_t;
+typedef int _G_wchar_t;
+typedef int _G_ssize_t;
+typedef int /* default */ _G_wint_t;
+typedef char * _G_va_list;
+#define _G_signal_return_type void
+#define _G_sprintf_return_type int
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+typedef int _G_int8_t __attribute__((__mode__(__QI__)));
+typedef unsigned int _G_uint8_t __attribute__((__mode__(__QI__)));
+typedef int _G_int16_t __attribute__((__mode__(__HI__)));
+typedef unsigned int _G_uint16_t __attribute__((__mode__(__HI__)));
+typedef int _G_int32_t __attribute__((__mode__(__SI__)));
+typedef unsigned int _G_uint32_t __attribute__((__mode__(__SI__)));
+typedef int _G_int64_t __attribute__((__mode__(__DI__)));
+typedef unsigned int _G_uint64_t __attribute__((__mode__(__DI__)));
+#else
+typedef short _G_int16_t;
+typedef unsigned short _G_uint16_t;
+typedef int _G_int32_t;
+typedef unsigned int _G_uint32_t;
+#endif
+
+#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
+#if !defined (__GNUG__)
+#define _G_NO_EXTERN_TEMPLATES
+#endif
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_RESOURCE 1
+#define _G_HAVE_SYS_TIMES 1
+#define _G_HAVE_SYS_SOCKET 1
+#define _G_HAVE_SYS_CDEFS 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 1
+#endif /* !_G_config_h */
+%% file libg++/src/shlib_version
+major=3
+minor=0
+%% file libiostream/shlib_version
+major=0
+minor=0
+%% file libio/shlib_version
+major=0
+minor=0
+%% file libstdc++/shlib_version
+major=0
+minor=0
+%% file VERSION
+This is libg++ 2.7.1 from the Free Software Foundation.
+
+Complete, unmodified libg++ sources are available from
+prep.ai.mit.edu and prep's mirrors.
+
diff --git a/gnu/lib/libg++/libio/Makefile b/gnu/lib/libg++/libio/Makefile
new file mode 100644
index 00000000000..158971bbbfc
--- /dev/null
+++ b/gnu/lib/libg++/libio/Makefile
@@ -0,0 +1,18 @@
+# $NetBSD: Makefile,v 1.1.1.1 1996/03/09 00:01:31 phil Exp $
+
+LIB= io
+
+SRCS= cleanup.c filedoalloc.c fileops.c floatconv.c genops.c iofclose.c \
+iofdopen.c iofflush.c iofgetpos.c iofgets.c iofopen.c iofprintf.c \
+iofputs.c iofread.c iofscanf.c iofsetpos.c ioftell.c iofwrite.c \
+iogetdelim.c iogetline.c iogets.c ioignore.c iopadn.c ioperror.c \
+iopopen.c ioprims.c ioprintf.c ioputs.c ioscanf.c ioseekoff.c \
+ioseekpos.c iosetbuffer.c iosetvbuf.c iosprintf.c iosscanf.c iostrerror.c \
+ioungetc.c iovfprintf.c iovfscanf.c iovsprintf.c iovsscanf.c outfloat.c \
+stdfiles.c strops.c
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../include
+CFLAGS+= -I$(.CURDIR)
+NOMAN= noman
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libg++/libio/PlotFile.cc b/gnu/lib/libg++/libio/PlotFile.cc
new file mode 100644
index 00000000000..98b2d839555
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992, 1993 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+ converted to use iostream library by Per Bothner (bothner@cygnus.com)
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with GCC to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <PlotFile.h>
+
+/*
+ PlotFile implementation module
+*/
+
+
+PlotFile& PlotFile:: cmd(char c)
+{
+ ofstream::put(c);
+ return *this;
+}
+
+PlotFile& PlotFile:: operator<<(const int x)
+{
+#if defined(convex)
+ ofstream::put((char)(x>>8));
+ ofstream::put((char)(x&0377));
+#else
+ ofstream::put((char)(x&0377));
+ ofstream::put((char)(x>>8));
+#endif
+ return *this;
+}
+
+PlotFile& PlotFile:: operator<<(const char *s)
+{
+ *(ofstream*)this << s;
+ return *this;
+}
+
+
+PlotFile& PlotFile:: arc(const int xi, const int yi,
+ const int x0, const int y0,
+ const int x1, const int y1)
+{
+ return cmd('a') << xi << yi << x0 << y0 << x1 << y1;
+}
+
+
+PlotFile& PlotFile:: box(const int x0, const int y0,
+ const int x1, const int y1)
+{
+ line(x0, y0, x0, y1);
+ line(x0, y1, x1, y1);
+ line(x1, y1, x1, y0);
+ return line(x1, y0, x0, y0);
+}
+
+PlotFile& PlotFile:: circle(const int x, const int y, const int r)
+{
+ return cmd('c') << x << y << r;
+}
+
+PlotFile& PlotFile:: cont(const int xi, const int yi)
+{
+ return cmd('n') << xi << yi;
+}
+
+PlotFile& PlotFile:: dot(const int xi, const int yi, const int dx,
+ int n, const int* pat)
+{
+ cmd('d') << xi << yi << dx << n;
+ while (n-- > 0) *this << *pat++;
+ return *this;
+}
+
+PlotFile& PlotFile:: erase()
+{
+ return cmd('e');
+}
+
+PlotFile& PlotFile:: label(const char* s)
+{
+ return cmd('t') << s << "\n";
+}
+
+PlotFile& PlotFile:: line(const int x0, const int y0,
+ const int x1, const int y1)
+{
+ return cmd('l') << x0 << y0 << x1 << y1;
+}
+
+PlotFile& PlotFile:: linemod(const char* s)
+{
+ return cmd('f') << s << "\n";
+}
+
+PlotFile& PlotFile:: move(const int xi, const int yi)
+{
+ return cmd('m') << xi << yi;
+}
+
+PlotFile& PlotFile:: point(const int xi, const int yi)
+{
+ return cmd('p') << xi << yi;
+}
+
+PlotFile& PlotFile:: space(const int x0, const int y0,
+ const int x1, const int y1)
+{
+ return cmd('s') << x0 << y0 << x1 << y1;
+}
diff --git a/gnu/lib/libg++/libio/PlotFile.h b/gnu/lib/libg++/libio/PlotFile.h
new file mode 100644
index 00000000000..82b08bc4681
--- /dev/null
+++ b/gnu/lib/libg++/libio/PlotFile.h
@@ -0,0 +1,89 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ a very simple implementation of a class to output unix "plot"
+ format plotter files. See corresponding unix man pages for
+ more details.
+
+ written by Doug Lea (dl@rocky.oswego.edu)
+ converted to use iostream library by Per Bothner (bothner@cygnus.com)
+*/
+
+#ifndef _PlotFile_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _PlotFile_h
+
+#include <fstream.h>
+
+/*
+ Some plot libraries have the `box' command to draw boxes. Some don't.
+ `box' is included here via moves & lines to allow both possiblilties.
+*/
+
+extern "C++" {
+class PlotFile : public ofstream
+{
+protected:
+ PlotFile& cmd(char c);
+ PlotFile& operator << (const int x);
+ PlotFile& operator << (const char *s);
+
+public:
+
+ PlotFile() : ofstream() { }
+ PlotFile(int fd) : ofstream(fd) { }
+ PlotFile(const char *name, int mode=ios::out, int prot=0664)
+ : ofstream(name, mode, prot) { }
+
+// PlotFile& remove() { ofstream::remove(); return *this; }
+
+// int filedesc() { return ofstream::filedesc(); }
+// const char* name() { return File::name(); }
+// void setname(const char* newname) { File::setname(newname); }
+// int iocount() { return File::iocount(); }
+
+ PlotFile& arc(const int xi, const int yi,
+ const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& box(const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& circle(const int x, const int y, const int r);
+ PlotFile& cont(const int xi, const int yi);
+ PlotFile& dot(const int xi, const int yi, const int dx,
+ int n, const int* pat);
+ PlotFile& erase();
+ PlotFile& label(const char* s);
+ PlotFile& line(const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& linemod(const char* s);
+ PlotFile& move(const int xi, const int yi);
+ PlotFile& point(const int xi, const int yi);
+ PlotFile& space(const int x0, const int y0,
+ const int x1, const int y1);
+};
+} // extern "C++"
+#endif
diff --git a/gnu/lib/libg++/libio/SFile.cc b/gnu/lib/libg++/libio/SFile.cc
new file mode 100644
index 00000000000..e5daa645695
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <SFile.h>
+
+SFile::SFile(const char *filename, int size, int mode, int prot)
+: fstream(filename, mode, prot)
+{
+ sz = size;
+}
+
+SFile::SFile(int fd, int size)
+: fstream(fd)
+{
+ sz = size;
+}
+
+void SFile::open(const char *name, int size, int mode, int prot)
+{
+ fstream::open(name, mode, prot);
+ sz = size;
+}
+
+SFile& SFile::get(void* x)
+{
+ read(x, sz);
+ return *this;
+}
+
+SFile& SFile::put(void* x)
+{
+ write(x, sz);
+ return *this;
+}
+
+SFile& SFile::operator[](long i)
+{
+ if (rdbuf()->pubseekoff(i * sz, ios::beg) == EOF)
+ set(ios::badbit);
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/SFile.h b/gnu/lib/libg++/libio/SFile.h
new file mode 100644
index 00000000000..f07277cee49
--- /dev/null
+++ b/gnu/lib/libg++/libio/SFile.h
@@ -0,0 +1,55 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1988, 1992, 1993 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _SFile_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _SFile_h 1
+
+#include <fstream.h>
+
+extern "C++" {
+class SFile: public fstream
+{
+ protected:
+ int sz; // unit size for structured binary IO
+
+public:
+ SFile() : fstream() { }
+ SFile(int fd, int size);
+ SFile(const char *name, int size, int mode, int prot=0664);
+ void open(const char *name, int size, int mode, int prot=0664);
+
+ int size() { return sz; }
+ int setsize(int s) { int old = sz; sz = s; return old; }
+
+ SFile& get(void* x);
+ SFile& put(void* x);
+ SFile& operator[](long i);
+};
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libio/_G_config.h b/gnu/lib/libg++/libio/_G_config.h
new file mode 100644
index 00000000000..a8b1066e716
--- /dev/null
+++ b/gnu/lib/libg++/libio/_G_config.h
@@ -0,0 +1,78 @@
+/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
+#ifndef _G_config_h
+#define _G_config_h
+#define _G_LIB_VERSION "2.7.1"
+#define _G_NAMES_HAVE_UNDERSCORE 1
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+#define _G_VTABLE_LABEL_PREFIX "__vt$"
+#define _G_HAVE_ST_BLKSIZE 1
+typedef unsigned long _G_clock_t;
+typedef int _G_dev_t;
+typedef long long _G_fpos_t;
+typedef unsigned int _G_gid_t;
+typedef unsigned int _G_ino_t;
+typedef unsigned short _G_mode_t;
+typedef unsigned short _G_nlink_t;
+typedef long long _G_off_t;
+typedef int _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 int _G_uid_t;
+typedef int _G_wchar_t;
+typedef int _G_ssize_t;
+typedef int /* default */ _G_wint_t;
+typedef char * _G_va_list;
+#define _G_signal_return_type void
+#define _G_sprintf_return_type int
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+typedef int _G_int8_t __attribute__((__mode__(__QI__)));
+typedef unsigned int _G_uint8_t __attribute__((__mode__(__QI__)));
+typedef int _G_int16_t __attribute__((__mode__(__HI__)));
+typedef unsigned int _G_uint16_t __attribute__((__mode__(__HI__)));
+typedef int _G_int32_t __attribute__((__mode__(__SI__)));
+typedef unsigned int _G_uint32_t __attribute__((__mode__(__SI__)));
+typedef int _G_int64_t __attribute__((__mode__(__DI__)));
+typedef unsigned int _G_uint64_t __attribute__((__mode__(__DI__)));
+#else
+typedef short _G_int16_t;
+typedef unsigned short _G_uint16_t;
+typedef int _G_int32_t;
+typedef unsigned int _G_uint32_t;
+#endif
+
+#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
+#if !defined (__GNUG__)
+#define _G_NO_EXTERN_TEMPLATES
+#endif
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_RESOURCE 1
+#define _G_HAVE_SYS_TIMES 1
+#define _G_HAVE_SYS_SOCKET 1
+#define _G_HAVE_SYS_CDEFS 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 1
+#endif /* !_G_config_h */
diff --git a/gnu/lib/libg++/libio/builtinbuf.cc b/gnu/lib/libg++/libio/builtinbuf.cc
new file mode 100644
index 00000000000..05e65a5c371
--- /dev/null
+++ b/gnu/lib/libg++/libio/builtinbuf.cc
@@ -0,0 +1,78 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+#include "builtinbuf.h"
+#include "iostreamP.h"
+#if !_IO_UNIFIED_JUMPTABLES
+int builtinbuf::overflow(int ch) { return _IO_OVERFLOW (this, ch); }
+
+int builtinbuf::underflow() { return _IO_UNDERFLOW (this); }
+
+streamsize builtinbuf::xsgetn(char* buf, streamsize n)
+{ return _IO_XSGETN (this, buf, n); }
+
+streamsize builtinbuf::xsputn(const char* buf, streamsize n)
+{ return _IO_XSPUTN (this, buf, n); }
+
+int builtinbuf::doallocate() { return _IO_DOALLOCATE (this); }
+
+builtinbuf::~builtinbuf() { _IO_FINISH (this); }
+
+int builtinbuf::sync() { return _IO_SYNC (this); }
+
+streambuf* builtinbuf::setbuf(char *buf, int n)
+{ return (streambuf*)_IO_SETBUF (this, buf, n); }
+
+streampos builtinbuf::seekoff(streamoff off, _seek_dir dir, int mode)
+{
+ return _IO_SEEKOFF (this, off, dir, mode);
+}
+
+streampos builtinbuf::seekpos(streampos pos, int mode)
+{
+ return _IO_SEEKPOS (this, pos, mode);
+}
+
+int builtinbuf::pbackfail(int c)
+{ return _IO_PBACKFAIL (this, c); }
+
+streamsize builtinbuf::sys_read(char* buf, streamsize size)
+{ return _IO_SYSREAD (this, buf, size); }
+
+streampos builtinbuf::sys_seek(streamoff off, _seek_dir dir)
+{ return _IO_SYSSEEK (this, off, dir); }
+
+streamsize builtinbuf::sys_write(const char* buf, streamsize size)
+{ return _IO_SYSWRITE (this, buf, size); }
+
+int builtinbuf::sys_stat(void* buf) // Actually, a (struct stat*)
+{ return _IO_SYSSTAT (this, buf); }
+
+int builtinbuf::sys_close()
+{ return _IO_SYSCLOSE (this); }
+#endif
diff --git a/gnu/lib/libg++/libio/builtinbuf.h b/gnu/lib/libg++/libio/builtinbuf.h
new file mode 100644
index 00000000000..0e0c6e85a9e
--- /dev/null
+++ b/gnu/lib/libg++/libio/builtinbuf.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _BUILTINBUF_H
+#define _BUILTINBUF_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <streambuf.h>
+
+#if !_IO_UNIFIED_JUMPTABLES
+// A builtinbuf a a streambuf where all the virtual operations
+// call the _IO_jump_t table.
+
+extern "C++" {
+class builtinbuf : public streambuf {
+ friend ios;
+ virtual int overflow(int);
+ virtual int underflow();
+ virtual streamsize xsgetn(char *, streamsize);
+ virtual streamsize xsputn(const char *, streamsize);
+ virtual streambuf* setbuf(char*, int);
+ virtual int doallocate();
+ virtual ~builtinbuf();
+ virtual int sync();
+
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual int pbackfail(int c);
+ virtual streamsize sys_read(char* buf, streamsize size);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+ virtual int sys_close();
+#if 0
+ virtual int get_column();
+ virtual int set_column(int);
+#endif
+ private:
+ builtinbuf() { }
+};
+} // extern "C++"
+#endif
+
+#endif /* _BUILTINBUF_H */
diff --git a/gnu/lib/libg++/libio/cleanup.c b/gnu/lib/libg++/libio/cleanup.c
new file mode 100644
index 00000000000..b4c8be927f9
--- /dev/null
+++ b/gnu/lib/libg++/libio/cleanup.c
@@ -0,0 +1,15 @@
+#include "libioP.h"
+#if _G_HAVE_ATEXIT
+#include <stdlib.h>
+
+typedef void (*voidfunc) __P((void));
+
+static void
+DEFUN_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 00000000000..22304820f8f
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "libioP.h"
+#include "editbuf.h"
+#include <stddef.h>
+#include <stdlib.h>
+
+/* NOTE: Some of the code here is taken from GNU emacs */
+/* Hence this file falls under the GNU License! */
+
+// Invariants for edit_streambuf:
+// An edit_streambuf is associated with a specific edit_string,
+// which again is a sub-string of a specific edit_buffer.
+// An edit_streambuf is always in either get mode or put mode, never both.
+// In get mode, gptr() is the current position,
+// and pbase(), pptr(), and epptr() are all NULL.
+// In put mode, pptr() is the current position,
+// and eback(), gptr(), and egptr() are all NULL.
+// Any edit_streambuf that is actively doing insertion (as opposed to
+// replacing) // must have its pptr() pointing to the start of the gap.
+// Only one edit_streambuf can be actively inserting into a specific
+// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf.
+// That edit_streambuf "owns" the gap, and the actual start of the
+// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer
+// will only be updated on an edit_streambuf::overflow().
+
+int edit_streambuf::truncate()
+{
+ str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()),
+ str->buffer->tell(str->end));
+ return 0;
+}
+
+#ifdef OLD_STDIO
+inline void disconnect_gap_from_file(edit_buffer* buffer, FILE* fp)
+{
+ if (buffer->gap_start_ptr != &fp->__bufp)
+ return;
+ buffer->gap_start_normal = fp->__bufp;
+ buffer->gap_start_ptr = &buffer->gap_start_normal;
+}
+#endif
+
+void edit_streambuf::flush_to_buffer(edit_buffer* buffer)
+{
+ if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end())
+ buffer->_gap_start = pptr();
+}
+
+void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer)
+{
+ if (buffer->_writer != this) return;
+ flush_to_buffer(buffer);
+ setp(pptr(),pptr());
+ buffer->_writer = NULL;
+}
+
+buf_index edit_buffer::tell(buf_char *ptr)
+{
+ if (ptr <= gap_start())
+ return ptr - data;
+ else
+ return ptr - gap_end() + size1();
+}
+
+#if 0
+buf_index buf_cookie::tell()
+{
+ return str->buffer->tell(file->__bufp);
+}
+#endif
+
+buf_index edit_buffer::tell(edit_mark*mark)
+{
+ return tell(data + mark->index_in_buffer(this));
+}
+
+// adjust the position of the gap
+
+void edit_buffer::move_gap(buf_offset pos)
+{
+ if (pos < size1())
+ gap_left (pos);
+ else if (pos > size1())
+ gap_right (pos);
+}
+
+void edit_buffer::gap_left (int pos)
+{
+ register buf_char *to, *from;
+ register int i;
+ int new_s1;
+
+ i = size1();
+ from = gap_start();
+ to = from + gap_size();
+ new_s1 = size1();
+
+ /* Now copy the characters. To move the gap down,
+ copy characters up. */
+
+ for (;;)
+ {
+ /* I gets number of characters left to copy. */
+ i = new_s1 - pos;
+ if (i == 0)
+ break;
+#if 0
+ /* If a quit is requested, stop copying now.
+ Change POS to be where we have actually moved the gap to. */
+ if (QUITP)
+ {
+ pos = new_s1;
+ break;
+ }
+#endif
+ /* Move at most 32000 chars before checking again for a quit. */
+ if (i > 32000)
+ i = 32000;
+ new_s1 -= i;
+ while (--i >= 0)
+ *--to = *--from;
+ }
+
+ /* Adjust markers, and buffer data structure, to put the gap at POS.
+ POS is where the loop above stopped, which may be what was specified
+ or may be where a quit was detected. */
+ adjust_markers (pos << 1, size1() << 1, gap_size(), data);
+#ifndef OLD_STDIO
+ _gap_start = data + pos;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + pos;
+#endif
+ __gap_end_pos = to - data;
+/* QUIT;*/
+}
+
+void edit_buffer::gap_right (int pos)
+{
+ register buf_char *to, *from;
+ register int i;
+ int new_s1;
+
+ i = size1();
+ to = gap_start();
+ from = i + gap_end();
+ new_s1 = i;
+
+ /* Now copy the characters. To move the gap up,
+ copy characters down. */
+
+ while (1)
+ {
+ /* I gets number of characters left to copy. */
+ i = pos - new_s1;
+ if (i == 0)
+ break;
+#if 0
+ /* If a quit is requested, stop copying now.
+ Change POS to be where we have actually moved the gap to. */
+ if (QUITP)
+ {
+ pos = new_s1;
+ break;
+ }
+#endif
+ /* Move at most 32000 chars before checking again for a quit. */
+ if (i > 32000)
+ i = 32000;
+ new_s1 += i;
+ while (--i >= 0)
+ *to++ = *from++;
+ }
+
+ adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1,
+ - gap_size(), data);
+#ifndef OLD_STDIO
+ _gap_start = data+pos;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + pos;
+#endif
+ __gap_end_pos = from - data;
+/* QUIT;*/
+}
+
+/* make sure that the gap in the current buffer is at least k
+ characters wide */
+
+void edit_buffer::make_gap(buf_offset k)
+{
+ register buf_char *p1, *p2, *lim;
+ buf_char *old_data = data;
+ int s1 = size1();
+
+ if (gap_size() >= k)
+ return;
+
+ /* Get more than just enough */
+ if (buf_size > 1000) k += 2000;
+ else k += /*200;*/ 20; // for testing!
+
+ p1 = (buf_char *) realloc (data, s1 + size2() + k);
+ if (p1 == 0)
+ abort(); /*memory_full ();*/
+
+ k -= gap_size(); /* Amount of increase. */
+
+ /* Record new location of text */
+ data = p1;
+
+ /* Transfer the new free space from the end to the gap
+ by shifting the second segment upward */
+ p2 = data + buf_size;
+ p1 = p2 + k;
+ lim = p2 - size2();
+ while (lim < p2)
+ *--p1 = *--p2;
+
+ /* Finish updating text location data */
+ __gap_end_pos += k;
+
+#ifndef OLD_STDIO
+ _gap_start = data + s1;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + s1;
+#endif
+
+ /* adjust markers */
+ adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data);
+ buf_size += k;
+}
+
+/* Add `amount' to the position of every marker in the current buffer
+ whose current position is between `from' (exclusive) and `to' (inclusive).
+ Also, any markers past the outside of that interval, in the direction
+ of adjustment, are first moved back to the near end of the interval
+ and then adjusted by `amount'. */
+
+void edit_buffer::adjust_markers(register mark_pointer low,
+ register mark_pointer high,
+ int amount, buf_char *old_data)
+{
+ register struct edit_mark *m;
+ register mark_pointer mpos;
+ /* convert to mark_pointer */
+ amount <<= 1;
+
+ if (_writer)
+ _writer->disconnect_gap_from_file(this);
+
+ for (m = mark_list(); m != NULL; m = m->chain)
+ {
+ mpos = m->_pos;
+ if (amount > 0)
+ {
+ if (mpos > high && mpos < high + amount)
+ mpos = high + amount;
+ }
+ else
+ {
+ if (mpos > low + amount && mpos <= low)
+ mpos = low + amount;
+ }
+ if (mpos > low && mpos <= high)
+ mpos += amount;
+ m->_pos = mpos;
+ }
+
+ // Now adjust files
+ edit_streambuf *file;
+
+ for (file = files; file != NULL; file = file->next) {
+ mpos = file->current() - old_data;
+ if (amount > 0)
+ {
+ if (mpos > high && mpos < high + amount)
+ mpos = high + amount;
+ }
+ else
+ {
+ if (mpos > low + amount && mpos <= low)
+ mpos = low + amount;
+ }
+ if (mpos > low && mpos <= high)
+ mpos += amount;
+ char* new_pos = data + mpos;
+ file->set_current(new_pos, file->is_reading());
+ }
+}
+
+#if 0
+stdio_
+ __off == index at start of buffer (need only be valid after seek ? )
+ __buf ==
+
+if read/read_delete/overwrite mode:
+ __endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer))
+
+if inserting:
+ must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp
+ file->edit_string->end->ptr(buffer) == *gap_start_ptr+end
+if write_mode:
+ if before gap
+#endif
+
+int edit_streambuf::underflow()
+{
+ if (!(_mode & ios::in))
+ return EOF;
+ struct edit_buffer *buffer = str->buffer;
+ if (!is_reading()) { // Must switch from put to get mode.
+ disconnect_gap_from_file(buffer);
+ set_current(pptr(), 1);
+ }
+ buf_char *str_end = str->end->ptr(buffer);
+ retry:
+ if (gptr() < egptr()) {
+ return *gptr();
+ }
+ if ((buf_char*)gptr() == str_end)
+ return EOF;
+ if (str_end <= buffer->gap_start()) {
+ setg(eback(), gptr(), str_end);
+ goto retry;
+ }
+ if (gptr() < buffer->gap_start()) {
+ setg(eback(), gptr(), buffer->gap_start());
+ goto retry;
+ }
+ if (gptr() == buffer->gap_start()) {
+ disconnect_gap_from_file(buffer);
+// fp->__offset += fp->__bufp - fp->__buffer;
+ setg(buffer->gap_end(), buffer->gap_end(), str_end);
+ }
+ else
+ setg(eback(), gptr(), str_end);
+ goto retry;
+}
+
+int edit_streambuf::overflow(int ch)
+{
+ if (_mode == ios::in)
+ return EOF;
+ struct edit_buffer *buffer = str->buffer;
+ flush_to_buffer(buffer);
+ if (ch == EOF)
+ return 0;
+ if (is_reading()) { // Must switch from get to put mode.
+ set_current(gptr(), 0);
+ }
+ buf_char *str_end = str->end->ptr(buffer);
+ retry:
+ if (pptr() < epptr()) {
+ *pptr() = ch;
+ pbump(1);
+ return (unsigned char)ch;
+ }
+ if ((buf_char*)pptr() == str_end || inserting()) {
+ /* insert instead */
+ if (buffer->_writer)
+ buffer->_writer->flush_to_buffer(); // Redundant?
+ buffer->_writer = NULL;
+ if (pptr() >= buffer->gap_end())
+ buffer->move_gap(pptr() - buffer->gap_size());
+ else
+ buffer->move_gap(pptr());
+ buffer->make_gap(1);
+ setp(buffer->gap_start(), buffer->gap_end());
+ buffer->_writer = this;
+ *pptr() = ch;
+ pbump(1);
+ return (unsigned char)ch;
+ }
+ if (str_end <= buffer->gap_start()) {
+ // Entire string is left of gap.
+ setp(pptr(), str_end);
+ }
+ else if (pptr() < buffer->gap_start()) {
+ // Current pos is left of gap.
+ setp(pptr(), buffer->gap_start());
+ goto retry;
+ }
+ else if (pptr() == buffer->gap_start()) {
+ // Current pos is at start of gap; move to end of gap.
+// disconnect_gap_from_file(buffer);
+ setp(buffer->gap_end(), str_end);
+// __offset += __bufp - __buffer;
+ }
+ else {
+ // Otherwise, current pos is right of gap.
+ setp(pptr(), str_end);
+ }
+ goto retry;
+}
+
+void edit_streambuf::set_current(char *new_pos, int reading)
+{
+ if (reading) {
+ setg(new_pos, new_pos, new_pos);
+ setp(NULL, NULL);
+ }
+ else {
+ setg(NULL, NULL, NULL);
+ setp(new_pos, new_pos);
+ }
+}
+
+// Called by fseek(fp, pos, whence) if fp is bound to a edit_buffer.
+
+streampos edit_streambuf::seekoff(streamoff offset, _seek_dir dir,
+ int /* =ios::in|ios::out*/)
+{
+ struct edit_buffer *buffer = str->buffer;
+ disconnect_gap_from_file(buffer);
+ buf_index cur_pos = buffer->tell((buf_char*)current());;
+ buf_index start_pos = buffer->tell(str->start);
+ buf_index end_pos = buffer->tell(str->end);
+ switch (dir) {
+ case ios::beg:
+ offset += start_pos;
+ break;
+ case ios::cur:
+ offset += cur_pos;
+ break;
+ case ios::end:
+ offset += end_pos;
+ break;
+ }
+ if (offset < start_pos || offset > end_pos)
+ return EOF;
+ buf_char *new_pos = buffer->data + offset;
+ buf_char* gap_start = buffer->gap_start();
+ if (new_pos > gap_start) {
+ buf_char* gap_end = buffer->gap_end();
+ new_pos += gap_end - gap_start;
+ if (new_pos >= buffer->data + buffer->buf_size) abort(); // Paranoia.
+ }
+ set_current(new_pos, is_reading());
+ return EOF;
+}
+
+#if 0
+int buf_seek(void *arg_cookie, fpos_t * pos, int whence)
+{
+ struct buf_cookie *cookie = arg_cookie;
+ FILE *file = cookie->file;
+ struct edit_buffer *buffer = cookie->str->buffer;
+ buf_char *str_start = cookie->str->start->ptr(buffer);
+ disconnect_gap_from_file(buffer, cookie->file);
+ fpos_t cur_pos, new_pos;
+ if (file->__bufp <= *buffer->gap_start_ptr
+ || str_start >= buffer->__gap_end)
+ cur_pos = str_start - file->__bufp;
+ else
+ cur_pos =
+ (*buffer->gap_start_ptr - str_start) + (file->__bufp - __gap_end);
+ end_pos = ...;
+ switch (whence) {
+ case SEEK_SET:
+ new_pos = *pos;
+ break;
+ case SEEK_CUR:
+ new_pos = cur_pos + *pos;
+ break;
+ case SEEK_END:
+ new_pos = end_pos + *pos;
+ break;
+ }
+ if (new_pos > end_pos) {
+ seek to end_pos;
+ insert_nulls(new_pos - end_pos);
+ return;
+ }
+ if (str_start + new_pos <= *gap_start_ptr &* *gap_start_ptr < end) {
+ __buffer = str_start;
+ __off = 0;
+ __bufp = str_start + new_pos;
+ file->__get_limit =
+ *buffer->gap_start_ptr; /* what if gap_start_ptr == &bufp ??? */
+ } else if () {
+
+ }
+ *pos = new_pos;
+}
+#endif
+
+/* Delete characters from `from' up to (but not incl) `to' */
+
+void edit_buffer::delete_range (buf_index from, buf_index to)
+{
+ register int numdel;
+
+ if ((numdel = to - from) <= 0)
+ return;
+
+ /* Make sure the gap is somewhere in or next to what we are deleting */
+ if (from > size1())
+ gap_right (from);
+ if (to < size1())
+ gap_left (to);
+
+ /* Relocate all markers pointing into the new, larger gap
+ to point at the end of the text before the gap. */
+ adjust_markers ((to + gap_size()) << 1, (to + gap_size()) << 1,
+ - numdel - gap_size(), data);
+
+ __gap_end_pos = to + gap_size();
+ _gap_start = data + from;
+}
+
+void edit_buffer::delete_range(struct edit_mark *start, struct edit_mark *end)
+{
+ delete_range(tell(start), tell(end));
+}
+
+void buf_delete_chars(struct edit_buffer *, struct edit_mark *, size_t)
+{
+ abort();
+}
+
+edit_streambuf::edit_streambuf(edit_string* bstr, int mode)
+{
+ _mode = mode;
+ str = bstr;
+ edit_buffer* buffer = bstr->buffer;
+ next = buffer->files;
+ buffer->files = this;
+ char* buf_ptr = bstr->start->ptr(buffer);
+ _inserting = 0;
+// setb(buf_ptr, buf_ptr, 0);
+ set_current(buf_ptr, !(mode & ios::out+ios::trunc+ios::app));
+ if (_mode & ios::trunc)
+ truncate();
+ if (_mode & ios::ate)
+ seekoff(0, ios::end);
+}
+
+// Called by fclose(fp) if fp is bound to a edit_buffer.
+
+#if 0
+static int buf_close(void *arg)
+{
+ register struct buf_cookie *cookie = arg;
+ struct edit_buffer *buffer = cookie->str->buffer;
+ struct buf_cookie **ptr;
+ for (ptr = &buffer->files; *ptr != cookie; ptr = &(*ptr)->next) ;
+ *ptr = cookie->next;
+ disconnect_gap_from_file(buffer, cookie->file);
+ free (cookie);
+ return 0;
+}
+#endif
+
+edit_streambuf::~edit_streambuf()
+{
+ if (_mode == ios::out)
+ truncate();
+ // Unlink this from list of files associated with bstr->buffer.
+ edit_streambuf **ptr = &str->buffer->files;
+ for (; *ptr != this; ptr = &(*ptr)->next) { }
+ *ptr = next;
+
+ disconnect_gap_from_file(str->buffer);
+}
+
+edit_buffer::edit_buffer()
+{
+ buf_size = /*200;*/ 15; /* for testing! */
+ data = (buf_char*)malloc(buf_size);
+ files = NULL;
+#ifndef OLD_STDIO
+ _gap_start = data;
+ _writer = NULL;
+#else
+ gap_start_normal = data;
+ gap_start_ptr = &gap_start_normal;
+#endif
+ __gap_end_pos = buf_size;
+ start_mark.chain = &end_mark;
+ start_mark._pos = 0;
+ end_mark.chain = NULL;
+ end_mark._pos = 2 * buf_size + 1;
+}
+
+// Allocate a new mark, which is adjusted by 'delta' bytes from 'this'.
+// Restrict new mark to lie within 'str'.
+
+edit_mark::edit_mark(struct edit_string *str, long delta)
+{
+ struct edit_buffer *buf = str->buffer;
+ chain = buf->start_mark.chain;
+ buf->start_mark.chain = this;
+ mark_pointer size1 = buf->size1() << 1;
+ int gap_size = buf->gap_size() << 1;
+ delta <<= 1;
+
+ // check if new and old marks are opposite sides of gap
+ if (_pos <= size1 && _pos + delta > size1)
+ delta += gap_size;
+ else if (_pos >= size1 + gap_size && _pos + delta < size1 + gap_size)
+ delta -= gap_size;
+
+ _pos = _pos + delta;
+ if (_pos < str->start->_pos & ~1)
+ _pos = (str->start->_pos & ~ 1) + (_pos & 1);
+ else if (_pos >= str->end->_pos)
+ _pos = (str->end->_pos & ~ 1) + (_pos & 1);
+}
+
+// A (slow) way to find the buffer a mark belongs to.
+
+edit_buffer * edit_mark::buffer()
+{
+ struct edit_mark *mark;
+ for (mark = this; mark->chain != NULL; mark = mark->chain) ;
+ // Assume that the last mark on the chain is the end_mark.
+ return (edit_buffer *)((char*)mark - offsetof(edit_buffer, end_mark));
+}
+
+edit_mark::~edit_mark()
+{
+ // Must unlink mark from chain of owning buffer
+ struct edit_buffer *buf = buffer();
+ if (this == &buf->start_mark || this == &buf->end_mark) abort();
+ edit_mark **ptr;
+ for (ptr = &buf->start_mark.chain; *ptr != this; ptr = &(*ptr)->chain) ;
+ *ptr = this->chain;
+}
+
+int edit_string::length() const
+{
+ ptrdiff_t delta = end->ptr(buffer) - start->ptr(buffer);
+ if (end->ptr(buffer) <= buffer->gap_start() ||
+ start->ptr(buffer) >= buffer->gap_end())
+ return delta;
+ return delta - buffer->gap_size();
+}
+
+buf_char * edit_string::copy_bytes(int *lenp) const
+{
+ char *new_str;
+ int len1, len2;
+ buf_char *start1, *start2;
+ start1 = start->ptr(buffer);
+ if (end->ptr(buffer) <= buffer->gap_start()
+ || start->ptr(buffer) >= buffer->gap_end()) {
+ len1 = end->ptr(buffer) - start1;
+ len2 = 0;
+ start2 = NULL; // To avoid a warning from g++.
+ }
+ else {
+ len1 = buffer->gap_start() - start1;
+ start2 = buffer->gap_end();
+ len2 = end->ptr(buffer) - start2;
+ }
+ new_str = (char*)malloc(len1 + len2 + 1);
+ memcpy(new_str, start1, len1);
+ if (len2 > 0) memcpy(new_str + len1, start2, len2);
+ new_str[len1+len2] = '\0';
+ *lenp = len1+len2;
+ return new_str;
+}
+
+// Replace the buf_chars in 'this' with ones from 'src'.
+// Equivalent to deleting this, then inserting src, except tries
+// to leave marks in place: Marks whose offset from the start
+// of 'this' is less than 'src->length()' will still have the
+// same offset in 'this' when done.
+
+void edit_string::assign(struct edit_string *src)
+{
+ edit_streambuf dst_file(this, ios::out);
+ if (buffer == src->buffer /*&& ???*/) { /* overly conservative */
+ int src_len;
+ buf_char *new_str;
+ new_str = src->copy_bytes(&src_len);
+ dst_file.sputn(new_str, src_len);
+ free (new_str);
+ } else {
+ edit_streambuf src_file(src, ios::in);
+ for ( ; ; ) {
+ int ch = src_file.sbumpc();
+ if (ch == EOF) break;
+ dst_file.sputc(ch);
+ }
+ }
+}
diff --git a/gnu/lib/libg++/libio/editbuf.h b/gnu/lib/libg++/libio/editbuf.h
new file mode 100644
index 00000000000..d15758f257e
--- /dev/null
+++ b/gnu/lib/libg++/libio/editbuf.h
@@ -0,0 +1,185 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _EDITBUF_H
+#define _EDITBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <stdio.h>
+#include <fstream.h>
+
+extern "C++" {
+typedef unsigned long mark_pointer;
+// At some point, it might be nice to parameterize this code
+// in terms of buf_char.
+typedef /*unsigned*/ char buf_char;
+
+// Logical pos from start of buffer (does not count gap).
+typedef long buf_index;
+
+// Pos from start of buffer, possibly including gap_size.
+typedef long buf_offset;
+
+#if 0
+struct buf_cookie {
+ FILE *file;
+ struct edit_string *str;
+ struct buf_cookie *next;
+ buf_index tell();
+};
+#endif
+
+struct edit_buffer;
+struct edit_mark;
+
+// A edit_string is defined as the region between the 'start' and 'end' marks.
+// Normally (always?) 'start->insert_before()' should be false,
+// and 'end->insert_before()' should be true.
+
+struct edit_string {
+ struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to
+ struct edit_mark *start, *end;
+ int length() const; // count of buf_chars currently in string
+ edit_string(struct edit_buffer *b,
+ struct edit_mark *ms, struct edit_mark *me)
+ { buffer = b; start = ms; end = me; }
+/* Make a fresh, contiguous copy of the data in STR.
+ Assign length of STR to *LENP.
+ (Output has extra NUL at out[*LENP].) */
+ buf_char *copy_bytes(int *lenp) const;
+// FILE *open_file(char *mode);
+ void assign(struct edit_string *src); // copy bytes from src to this
+};
+
+struct edit_streambuf : public streambuf {
+ friend edit_buffer;
+ edit_string *str;
+ edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer.
+ short _mode;
+ edit_streambuf(edit_string* bstr, int mode);
+ ~edit_streambuf();
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ void flush_to_buffer();
+ void flush_to_buffer(edit_buffer* buffer);
+ int _inserting;
+ int inserting() { return _inserting; }
+ void inserting(int i) { _inserting = i; }
+// int delete_chars(int count, char* cut_buf); Not implemented.
+ int truncate();
+ int is_reading() { return gptr() != NULL; }
+ buf_char* current() { return is_reading() ? gptr() : pptr(); }
+ void set_current(char *p, int is_reading);
+ protected:
+ void disconnect_gap_from_file(edit_buffer* buffer);
+};
+
+// A 'edit_mark' indicates a position in a buffer.
+// It is "attached" the text (rather than the offset).
+// There are two kinds of mark, which have different behavior
+// when text is inserted at the mark:
+// If 'insert_before()' is true the mark will be adjusted to be
+// *after* the new text.
+
+struct edit_mark {
+ struct edit_mark *chain;
+ mark_pointer _pos;
+ inline int insert_before() { return _pos & 1; }
+ inline unsigned long index_in_buffer(struct edit_buffer *)
+ { return _pos >> 1; }
+ inline buf_char *ptr(struct edit_buffer *buf);
+ buf_index tell();
+ edit_mark() { }
+ edit_mark(struct edit_string *str, long delta);
+ edit_buffer *buffer();
+ ~edit_mark();
+};
+
+// A 'edit_buffer' consists of a sequence of buf_chars (the data),
+// a list of edit_marks pointing into the data, and a list of FILEs
+// also pointing into the data.
+// A 'edit_buffer' coerced to a edit_string is the string of
+// all the buf_chars in the buffer.
+
+// This implementation uses a conventional buffer gap (as in Emacs).
+// The gap start is defined by de-referencing a (buf_char**).
+// This is because sometimes a FILE is inserting into the buffer,
+// so rather than having each putc adjust the gap, we use indirection
+// to have the gap be defined as the write pointer of the FILE.
+// (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.)
+
+struct edit_buffer {
+ buf_char *data; /* == emacs buffer_text.p1+1 */
+ buf_char *_gap_start;
+ edit_streambuf* _writer; // If non-NULL, currently writing stream
+ inline buf_char *gap_start()
+ { return _writer ? _writer->pptr() : _gap_start; }
+ buf_offset __gap_end_pos; // size of part 1 + size of gap
+ /* int gap; implicit: buf_size - size1 - size2 */
+ int buf_size;
+ struct edit_streambuf *files;
+ struct edit_mark start_mark;
+ struct edit_mark end_mark;
+ edit_buffer();
+ inline buf_offset gap_end_pos() { return __gap_end_pos; }
+ inline struct edit_mark *start_marker() { return &start_mark; }
+ inline struct edit_mark *end_marker() { return &end_mark; }
+/* these should be protected, ultimately */
+ buf_index tell(edit_mark*);
+ buf_index tell(buf_char*);
+ inline buf_char *gap_end() { return data + gap_end_pos(); }
+ inline int gap_size() { return gap_end() - gap_start(); }
+ inline int size1() { return gap_start() - data; }
+ inline int size2() { return buf_size - gap_end_pos(); }
+ inline struct edit_mark * mark_list() { return &start_mark; }
+ void make_gap (buf_offset);
+ void move_gap (buf_offset pos);
+ void move_gap (buf_char *pos) { move_gap(pos - data); }
+ void gap_left (int pos);
+ void gap_right (int pos);
+ void adjust_markers(mark_pointer low, mark_pointer high,
+ int amount, buf_char *old_data);
+ void delete_range(buf_index from, buf_index to);
+ void delete_range(struct edit_mark *start, struct edit_mark *end);
+};
+
+extern buf_char * bstr_copy(struct edit_string *str, int *lenp);
+
+// Convert a edit_mark to a (buf_char*)
+
+inline buf_char *edit_mark::ptr(struct edit_buffer *buf)
+ { return buf->data + index_in_buffer(buf); }
+
+inline void edit_streambuf::flush_to_buffer()
+{
+ edit_buffer* buffer = str->buffer;
+ if (buffer->_writer == this) flush_to_buffer(buffer);
+}
+} // extern "C++"
+#endif /* !_EDITBUF_H*/
+
diff --git a/gnu/lib/libg++/libio/filebuf.cc b/gnu/lib/libg++/libio/filebuf.cc
new file mode 100644
index 00000000000..8f4bdc8a020
--- /dev/null
+++ b/gnu/lib/libg++/libio/filebuf.cc
@@ -0,0 +1,198 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#include "iostreamP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "builtinbuf.h"
+
+void filebuf::init()
+{
+ _IO_file_init(this);
+}
+
+filebuf::filebuf()
+{
+ _IO_file_init(this);
+}
+
+#if !_IO_UNIFIED_JUMPTABLES
+/* This is like "new filebuf()", but it uses the _IO_file_jump jumptable,
+ for eficiency. */
+
+filebuf* filebuf::__new()
+{
+ filebuf *fb = new filebuf;
+ _IO_JUMPS(fb) = &_IO_file_jumps;
+ fb->_vtable() = builtinbuf_vtable;
+ return fb;
+}
+#endif
+
+filebuf::filebuf(int fd)
+{
+ _IO_file_init(this);
+ _IO_file_attach(this, fd);
+}
+
+filebuf::filebuf(int fd, char* p, int len)
+{
+ _IO_file_init(this);
+ _IO_file_attach(this, fd);
+ setbuf(p, len);
+}
+
+filebuf::~filebuf()
+{
+ if (_IO_file_is_open(this))
+ {
+ _IO_do_flush (this);
+ if (!(xflags() & _IO_DELETE_DONT_CLOSE))
+ _IO_SYSCLOSE (this);
+ }
+}
+
+filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot)
+{
+ if (_IO_file_is_open (this))
+ return NULL;
+ int posix_mode;
+ int read_write;
+ if (mode & ios::app)
+ mode |= ios::out;
+ if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) {
+ posix_mode = O_RDWR;
+ read_write = 0;
+ }
+ else if (mode & ios::out)
+ posix_mode = O_WRONLY, read_write = _IO_NO_READS;
+ else if (mode & (int)ios::in)
+ posix_mode = O_RDONLY, read_write = _IO_NO_WRITES;
+ else
+ posix_mode = 0, read_write = _IO_NO_READS+_IO_NO_WRITES;
+ if ((mode & (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 (pubseekoff(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 (streambuf*)_IO_file_setbuf (this, p, len);
+}
+
+int filebuf::doallocate() { return _IO_file_doallocate(this); }
+
+int filebuf::overflow(int c)
+{
+ return _IO_file_overflow(this, c);
+}
+
+int filebuf::underflow()
+{
+ return _IO_file_underflow(this);
+}
+
+int filebuf::sync()
+{
+ return _IO_file_sync(this);
+}
+
+streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
+{
+ return _IO_file_seekoff (this, offset, dir, mode);
+}
+
+filebuf* filebuf::close()
+{
+ return (_IO_file_close_it(this) ? (filebuf*)NULL : this);
+}
+
+streamsize filebuf::sys_read(char* buf, streamsize size)
+{
+ return _IO_file_read(this, buf, size);
+}
+
+streampos filebuf::sys_seek(streamoff offset, _seek_dir dir)
+{
+ return _IO_file_seek(this, offset, dir);
+}
+
+streamsize filebuf::sys_write(const char *buf, streamsize n)
+{
+ return _IO_file_write (this, buf, n);
+}
+
+int filebuf::sys_stat(void* st)
+{
+ return _IO_file_stat (this, st);
+}
+
+int filebuf::sys_close()
+{
+ return _IO_file_close (this);
+}
+
+streamsize filebuf::xsputn(const char *s, streamsize n)
+{
+ return _IO_file_xsputn(this, s, n);
+}
+
+streamsize filebuf::xsgetn(char *s, streamsize n)
+{
+ // FIXME: OPTIMIZE THIS (specifically, when unbuffered()).
+ return streambuf::xsgetn(s, n);
+}
+
+// Non-ANSI AT&T-ism: Default open protection.
+const int filebuf::openprot = 0644;
diff --git a/gnu/lib/libg++/libio/filedoalloc.c b/gnu/lib/libg++/libio/filedoalloc.c
new file mode 100644
index 00000000000..6218135eaed
--- /dev/null
+++ b/gnu/lib/libg++/libio/filedoalloc.c
@@ -0,0 +1,104 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* 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>
+#include <unistd.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
+DEFUN(_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 || _IO_SYSSTAT (fp, &st) < 0)
+ {
+ couldbetty = 0;
+ size = _IO_BUFSIZ;
+#if 0
+ /* do not try to optimise fseek() */
+ fp->_flags |= __SNPT;
+#endif
+ }
+ else
+ {
+ couldbetty = S_ISCHR(st.st_mode);
+#if _IO_HAVE_ST_BLKSIZE
+ size = st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize;
+#else
+ size = _IO_BUFSIZ;
+#endif
+ }
+ 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 00000000000..89381ec6997
--- /dev/null
+++ b/gnu/lib/libg++/libio/fileops.c
@@ -0,0 +1,738 @@
+/*
+Copyright (C) 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* written by Per Bothner (bothner@cygnus.com) */
+
+#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 _IO_read_end, except in putback mode,
+ when it is _IO_save_end.
+ If the field _fb._offset is >= 0, it gives the offset in
+ the file as a whole corresponding to eGptr(). (?)
+
+ PUT MODE:
+ If a filebuf is in put mode, 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
+DEFUN(_IO_file_init, (fp),
+ register _IO_FILE *fp)
+{
+ /* POSIX.1 allows another file handle to be used to change the position
+ of our file descriptor. Hence we actually don't know the actual
+ position before we do the first fseek (and until a following fflush). */
+ fp->_offset = _IO_pos_BAD;
+ fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
+
+ _IO_link_in(fp);
+ fp->_fileno = -1;
+}
+
+int
+DEFUN(_IO_file_close_it, (fp),
+ register _IO_FILE* fp)
+{
+ int sync_status, close_status;
+ if (!_IO_file_is_open(fp))
+ return EOF;
+
+ sync_status = _IO_file_sync (fp);
+
+ _IO_unsave_markers(fp);
+
+ close_status = _IO_SYSCLOSE (fp);
+
+ /* Free buffer. */
+ _IO_setb(fp, NULL, NULL, 0);
+ _IO_setg(fp, NULL, NULL, NULL);
+ _IO_setp(fp, NULL, NULL);
+
+ _IO_un_link(fp);
+ fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
+ fp->_fileno = EOF;
+ fp->_offset = _IO_pos_BAD;
+
+ return close_status ? close_status : sync_status;
+}
+
+void
+DEFUN(_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))
+ _IO_SYSCLOSE (fp);
+ }
+ _IO_default_finish(fp);
+}
+
+_IO_FILE *
+DEFUN(_IO_file_fopen, (fp, filename, mode),
+ register _IO_FILE *fp AND const char *filename AND 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 (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
+ == _IO_pos_BAD)
+ return NULL;
+ _IO_link_in(fp);
+ return fp;
+}
+
+_IO_FILE*
+DEFUN(_IO_file_attach, (fp, fd),
+ _IO_FILE *fp AND 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;
+}
+
+_IO_FILE*
+DEFUN(_IO_file_setbuf, (fp, p, len),
+ register _IO_FILE *fp AND char* p AND _IO_ssize_t len)
+{
+ if (_IO_default_setbuf(fp, p, len) == NULL)
+ return NULL;
+
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+ = fp->_IO_buf_base;
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+
+ return fp;
+}
+
+/* Write TO_DO bytes from DATA to FP.
+ Then mark FP has having empty buffers. */
+
+int
+DEFUN(_IO_do_write, (fp, data, to_do),
+ register _IO_FILE *fp AND const char* data AND _IO_size_t to_do)
+{
+ _IO_size_t count;
+ if (to_do == 0)
+ return 0;
+ if (fp->_flags & _IO_IS_APPENDING)
+ /* On a system without a proper O_APPEND implementation,
+ you would need to sys_seek(0, SEEK_END) here, but is
+ is not needed nor desirable for Unix- or Posix-like systems.
+ Instead, just indicate that offset (before and after) is
+ unpredictable. */
+ fp->_offset = _IO_pos_BAD;
+ else if (fp->_IO_read_end != fp->_IO_write_base)
+ {
+ _IO_pos_t new_pos
+ = _IO_SYSSEEK(fp, fp->_IO_write_base - fp->_IO_read_end, 1);
+ if (new_pos == _IO_pos_BAD)
+ return EOF;
+ fp->_offset = new_pos;
+ }
+ count = _IO_SYSWRITE (fp, data, to_do);
+ if (fp->_cur_column)
+ fp->_cur_column = _IO_adjust_column(fp->_cur_column - 1, data, to_do) + 1;
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
+ fp->_IO_write_end = (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) ? fp->_IO_buf_base
+ : fp->_IO_buf_end;
+ return count != to_do ? EOF : 0;
+}
+
+int
+DEFUN(_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 = _IO_SYSREAD (fp, fp->_IO_buf_base,
+ fp->_IO_buf_end - fp->_IO_buf_base);
+ if (count <= 0)
+ {
+ if (count == 0)
+ fp->_flags |= _IO_EOF_SEEN;
+ else
+ fp->_flags |= _IO_ERR_SEEN, count = 0;
+ }
+ fp->_IO_read_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
+DEFUN(_IO_file_overflow, (f, ch),
+ register _IO_FILE* f AND int ch)
+{
+ if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
+ return EOF;
+ /* If currently reading or no buffer allocated. */
+ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
+ {
+ /* Allocate a buffer if needed. */
+ if (f->_IO_write_base == 0)
+ {
+ _IO_doallocbuf(f);
+ _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
+ }
+ /* Otherwise must be currently reading. */
+ 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
+DEFUN(_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 = _IO_SYSSEEK (fp, delta, 1);
+ if (new_pos != (_IO_off_t)EOF)
+ fp->_IO_read_end = fp->_IO_read_ptr;
+#ifdef ESPIPE
+ else if (errno == ESPIPE)
+ ; /* Ignore error from unseekable devices. */
+#endif
+ else
+ return EOF;
+ }
+ fp->_offset = _IO_pos_BAD;
+ /* FIXME: Cleanup - can this be shared? */
+ /* setg(base(), ptr, ptr); */
+ return 0;
+}
+
+_IO_pos_t
+DEFUN(_IO_file_seekoff, (fp, offset, dir, mode),
+ register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
+{
+ _IO_pos_t result;
+ _IO_off_t delta, new_offset;
+ long count;
+
+ if (mode == 0)
+ dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+
+ /* Flush unwritten characters.
+ (This may do an unneeded write if we seek within the buffer.
+ But to be able to switch to reading, we would need to set
+ egptr to ptr. That can't be done in the current design,
+ which assumes file_ptr() is eGptr. Anyway, since we probably
+ end up flushing when we close(), it doesn't make much difference.)
+ FIXME: simulate mem-papped files. */
+
+ if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode(fp))
+ if (_IO_switch_to_get_mode(fp)) return EOF;
+
+ if (fp->_IO_buf_base == NULL)
+ {
+ _IO_doallocbuf(fp);
+ _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ }
+
+ switch (dir)
+ {
+ case _IO_seek_cur:
+ /* Adjust for read-ahead (bytes is buffer). */
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ if (fp->_offset == _IO_pos_BAD)
+ goto dumb;
+ /* Make offset absolute, assuming current pointer is file_ptr(). */
+ offset += _IO_pos_as_off(fp->_offset);
+
+ dir = _IO_seek_set;
+ break;
+ case _IO_seek_set:
+ break;
+ case _IO_seek_end:
+ {
+ struct stat st;
+ if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG(st.st_mode))
+ {
+ offset += st.st_size;
+ dir = _IO_seek_set;
+ }
+ else
+ goto dumb;
+ }
+ }
+ /* At this point, dir==_IO_seek_set. */
+
+ /* If destination is within current buffer, optimize: */
+ if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
+ && !_IO_in_backup (fp))
+ {
+ /* Offset relative to start of main get area. */
+ _IO_pos_t rel_offset = offset - fp->_offset
+ + (fp->_IO_read_end - fp->_IO_read_base);
+ if (rel_offset >= 0)
+ {
+#if 0
+ if (_IO_in_backup(fp))
+ _IO_switch_to_main_get_area(fp);
+#endif
+ if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
+ {
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
+ fp->_IO_read_end);
+ _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ return offset;
+ }
+#ifdef TODO
+ /* If we have streammarkers, seek forward by reading ahead. */
+ if (_IO_have_markers(fp))
+ {
+ int to_skip = rel_offset
+ - (fp->_IO_read_ptr - fp->_IO_read_base);
+ if (ignore(to_skip) != to_skip)
+ goto dumb;
+ return offset;
+ }
+#endif
+ }
+#ifdef TODO
+ if (rel_offset < 0 && rel_offset >= Bbase() - Bptr())
+ {
+ if (!_IO_in_backup(fp))
+ _IO_switch_to_backup_area(fp);
+ gbump(fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
+ return offset;
+ }
+#endif
+ }
+
+#ifdef TODO
+ _IO_unsave_markers(fp);
+#endif
+
+ if (fp->_flags & _IO_NO_READS)
+ goto dumb;
+
+ /* Try to seek to a block boundary, to improve kernel page management. */
+ new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
+ delta = offset - new_offset;
+ if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
+ {
+ new_offset = offset;
+ delta = 0;
+ }
+ result = _IO_SYSSEEK (fp, new_offset, 0);
+ if (result < 0)
+ return EOF;
+ if (delta == 0)
+ count = 0;
+ else
+ {
+ count = _IO_SYSREAD (fp, fp->_IO_buf_base,
+ fp->_IO_buf_end - fp->_IO_buf_base);
+ if (count < delta)
+ {
+ /* We weren't allowed to read, but try to seek the remainder. */
+ offset = count == EOF ? delta : delta-count;
+ dir = _IO_seek_cur;
+ goto dumb;
+ }
+ }
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base+delta, fp->_IO_buf_base+count);
+ _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ fp->_offset = result + count;
+ _IO_mask_flags(fp, 0, _IO_EOF_SEEN);
+ return offset;
+ dumb:
+
+ _IO_unsave_markers(fp);
+ result = _IO_SYSSEEK (fp, offset, dir);
+ if (result != EOF)
+ _IO_mask_flags(fp, 0, _IO_EOF_SEEN);
+ fp->_offset = result;
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ return result;
+}
+
+_IO_ssize_t
+DEFUN(_IO_file_read, (fp, buf, size),
+ register _IO_FILE* fp AND void* buf AND _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
+DEFUN(_IO_file_seek, (fp, offset, dir),
+ _IO_FILE *fp AND _IO_off_t offset AND int dir)
+{
+ return _IO_lseek(fp->_fileno, offset, dir);
+}
+
+int
+DEFUN(_IO_file_stat, (fp, st),
+ _IO_FILE *fp AND void* st)
+{
+ return _IO_fstat(fp->_fileno, (struct stat*)st);
+}
+
+int
+DEFUN(_IO_file_close, (fp),
+ _IO_FILE* fp)
+{
+ return _IO_close(fp->_fileno);
+}
+
+_IO_ssize_t
+DEFUN(_IO_file_write, (f, data, n),
+ register _IO_FILE* f AND const void* data AND _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
+DEFUN(_IO_file_xsputn, (f, data, n),
+ _IO_FILE *f AND const void *data AND _IO_size_t n)
+{
+ register const char *s = (char*) data;
+ _IO_size_t to_do = n;
+ int must_flush = 0;
+ _IO_size_t count;
+
+ if (n <= 0)
+ return 0;
+ /* This is an optimized implementation.
+ If the amount to be written straddles a block boundary
+ (or the filebuf is unbuffered), use sys_write directly. */
+
+ /* First figure out how much space is available in the buffer. */
+ count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+ if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ count = f->_IO_buf_end - f->_IO_write_ptr;
+ if (count >= n)
+ { register const char *p;
+ for (p = s + n; p > s; )
+ {
+ if (*--p == '\n') {
+ count = p - s + 1;
+ must_flush = 1;
+ break;
+ }
+ }
+ }
+ }
+ /* Then fill the buffer. */
+ if (count > 0)
+ {
+ if (count > to_do)
+ count = to_do;
+ if (count > 20) {
+ memcpy(f->_IO_write_ptr, s, count);
+ s += count;
+ }
+ else
+ {
+ register char *p = f->_IO_write_ptr;
+ register int i = (int)count;
+ while (--i >= 0) *p++ = *s++;
+ }
+ f->_IO_write_ptr += count;
+ to_do -= count;
+ }
+ if (to_do + must_flush > 0)
+ { _IO_size_t block_size, dont_write;
+ /* Next flush the (full) buffer. */
+ if (__overflow(f, EOF) == EOF)
+ return n - to_do;
+
+ /* Try to maintain alignment: write a whole number of blocks.
+ dont_write is what gets left over. */
+ block_size = f->_IO_buf_end - f->_IO_buf_base;
+ dont_write = block_size >= 128 ? to_do % block_size : 0;
+
+ count = to_do - dont_write;
+ if (_IO_do_write(f, s, count) == EOF)
+ return n - to_do;
+ to_do = dont_write;
+
+ /* Now write out the remainder. Normally, this will fit in the
+ buffer, but it's somewhat messier for line-buffered files,
+ so we let _IO_default_xsputn handle the general case. */
+ if (dont_write)
+ to_do -= _IO_default_xsputn(f, s+count, dont_write);
+ }
+ return n - to_do;
+}
+
+#if 0
+/* Work in progress */
+_IO_size_t
+DEFUN(_IO_file_xsgetn, (fp, data, n),
+ _IO_FILE *fp AND void *data AND _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 = _IO_SYSREAD (fp, s, more);
+ if (count <= 0)
+ {
+ if (count == 0)
+ fp->_flags |= _IO_EOF_SEEN;
+ else
+ fp->_flags |= _IO_ERR_SEEN, count = 0;
+ }
+
+ s += count;
+ more -= count;
+ }
+#endif
+ if (more == 0 || __underflow(fp) == EOF)
+ break;
+ }
+ return n - more;
+}
+#endif
+
+struct _IO_jump_t _IO_file_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_file_finish),
+ JUMP_INIT(overflow, _IO_file_overflow),
+ JUMP_INIT(underflow, _IO_file_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_file_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_file_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_file_setbuf),
+ JUMP_INIT(sync, _IO_file_sync),
+ JUMP_INIT(doallocate, _IO_file_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_file_close),
+ JUMP_INIT(stat, _IO_file_stat)
+};
diff --git a/gnu/lib/libg++/libio/floatconv.c b/gnu/lib/libg++/libio/floatconv.c
new file mode 100644
index 00000000000..a6183f9e9de
--- /dev/null
+++ b/gnu/lib/libg++/libio/floatconv.c
@@ -0,0 +1,2349 @@
+/*
+Copyright (C) 1993, 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+#ifdef _IO_USE_DTOA
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Some cleaning up by Per Bothner, bothner@cygnus.com, 1992, 1993.
+ Re-written to not need static variables
+ (except result, result_k, HIWORD, LOWORD). */
+
+/* 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;
+
+union doubleword {
+ double d;
+ unsigned32 u[2];
+};
+
+#ifdef IEEE_8087
+#define HIWORD 1
+#define LOWORD 0
+#define TEST_ENDIANNESS /* nothing */
+#else
+#if defined(IEEE_MC68k)
+#define HIWORD 0
+#define LOWORD 1
+#define TEST_ENDIANNESS /* nothing */
+#else
+static int HIWORD = -1, LOWORD;
+static void test_endianness()
+{
+ union doubleword dw;
+ dw.d = 10;
+ if (dw.u[0] != 0) /* big-endian */
+ HIWORD=0, LOWORD=1;
+ else
+ HIWORD=1, LOWORD=0;
+}
+#define TEST_ENDIANNESS if (HIWORD<0) test_endianness();
+#endif
+#endif
+
+#if 0
+union doubleword _temp;
+#endif
+#ifdef __GNUC__
+#define word0(x) ({ union doubleword _du; _du.d = (x); _du.u[HIWORD]; })
+#define word1(x) ({ union doubleword _du; _du.d = (x); _du.u[LOWORD]; })
+#define setword0(D,W) \
+ ({ union doubleword _du; _du.d = (D); _du.u[HIWORD]=(W); (D)=_du.d; })
+#define setword1(D,W) \
+ ({ union doubleword _du; _du.d = (D); _du.u[LOWORD]=(W); (D)=_du.d; })
+#define setwords(D,W0,W1) ({ union doubleword _du; \
+ _du.u[HIWORD]=(W0); _du.u[LOWORD]=(W1); (D)=_du.d; })
+#define addword0(D,W) \
+ ({ union doubleword _du; _du.d = (D); _du.u[HIWORD]+=(W); (D)=_du.d; })
+#else
+#define word0(x) ((unsigned32 *)&x)[HIWORD]
+#define word1(x) ((unsigned32 *)&x)[LOWORD]
+#define setword0(D,W) word0(D) = (W)
+#define setword1(D,W) word1(D) = (W)
+#define setwords(D,W0,W1) (setword0(D,W0),setword1(D,W1))
+#define addword0(D,X) (word0(D) += (X))
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors. */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#if defined(IEEE_MC68k)
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+#endif
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_Unknown)
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#define Kmax 15
+
+/* (1<<BIGINT_MINIMUM_K) is the minimum number of words to allocate
+ in a Bigint. dtoa usually manages with 1<<2, and has not been
+ known to need more than 1<<3. */
+
+#define BIGINT_MINIMUM_K 3
+
+struct Bigint {
+ struct Bigint *next;
+ int k; /* Parameter given to Balloc(k) */
+ int maxwds; /* Allocated space: equals 1<<k. */
+ short on_stack; /* 1 if stack-allocated. */
+ short sign; /* 0 if value is positive or zero; 1 if negative. */
+ int wds; /* Current length. */
+ unsigned32 x[1<<BIGINT_MINIMUM_K]; /* Actually: x[maxwds] */
+};
+
+#define BIGINT_HEADER_SIZE \
+ (sizeof(Bigint) - (1<<BIGINT_MINIMUM_K) * sizeof(unsigned32))
+
+typedef struct Bigint Bigint;
+
+/* Initialize a stack-allocated Bigint. */
+
+static Bigint *
+Binit
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ v->on_stack = 1;
+ v->k = BIGINT_MINIMUM_K;
+ v->maxwds = 1 << BIGINT_MINIMUM_K;
+ v->sign = v->wds = 0;
+ return v;
+}
+
+/* Allocate a Bigint with '1<<k' big digits. */
+
+static Bigint *
+Balloc
+#ifdef KR_headers
+ (k) int k;
+#else
+ (int k)
+#endif
+{
+ int x;
+ Bigint *rv;
+
+ if (k < BIGINT_MINIMUM_K)
+ k = BIGINT_MINIMUM_K;
+
+ x = 1 << k;
+ rv = (Bigint *)
+ malloc(BIGINT_HEADER_SIZE + x * sizeof(unsigned32));
+ rv->k = k;
+ rv->maxwds = x;
+ rv->sign = rv->wds = 0;
+ rv->on_stack = 0;
+ return rv;
+}
+
+static void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v && !v->on_stack)
+ free (v);
+}
+
+static void
+Bcopy
+#ifdef KR_headers
+ (x, y) Bigint *x, *y;
+#else
+ (Bigint *x, Bigint *y)
+#endif
+{
+ register unsigned32 *xp, *yp;
+ register int i = y->wds;
+ x->sign = y->sign;
+ x->wds = i;
+ for (xp = x->x, yp = y->x; --i >= 0; )
+ *xp++ = *yp++;
+}
+
+/* Make sure b has room for at least 1<<k big digits. */
+
+static Bigint *
+Brealloc
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint * b, int k)
+#endif
+{
+ if (b == NULL)
+ return Balloc(k);
+ if (b->k >= k)
+ return b;
+ else
+ {
+ Bigint *rv = Balloc (k);
+ Bcopy(rv, b);
+ Bfree(b);
+ return rv;
+ }
+}
+
+/* Return b*m+a. b is modified.
+ Assumption: 0xFFFF*m+a fits in 32 bits. */
+
+static Bigint *
+multadd
+#ifdef KR_headers
+ (b, m, a) Bigint *b; int m, a;
+#else
+ (Bigint *b, int m, int a)
+#endif
+{
+ int i, wds;
+ unsigned32 *x, y;
+ unsigned32 xi, z;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int)(z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+ }
+ while(++i < wds);
+ if (a) {
+ if (wds >= b->maxwds)
+ b = Brealloc(b, b->k+1);
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+static Bigint *
+s2b
+#ifdef KR_headers
+ (result, s, nd0, nd, y9)
+ Bigint *result; CONST char *s; int nd0, nd; unsigned32 y9;
+#else
+ (Bigint *result, CONST char *s, int nd0, int nd, unsigned32 y9)
+#endif
+{
+ int i, k;
+ _G_int32_t x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+ result = Brealloc(result, k);
+ result->x[0] = y9;
+ result->wds = 1;
+
+ i = 9;
+ if (9 < nd0)
+ {
+ s += 9;
+ do
+ result = multadd(result, 10, *s++ - '0');
+ while (++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ result = multadd(result, 10, *s++ - '0');
+ return result;
+}
+
+static int
+hi0bits
+#ifdef KR_headers
+ (x) register unsigned32 x;
+#else
+ (register unsigned32 x)
+#endif
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+ }
+
+static int
+lo0bits
+#ifdef KR_headers
+ (y) unsigned32 *y;
+#else
+ (unsigned32 *y)
+#endif
+{
+ register int k;
+ register unsigned32 x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+ }
+
+static Bigint *
+i2b
+#ifdef KR_headers
+ (result, i) Bigint *result; int i;
+#else
+ (Bigint* result, int i)
+#endif
+{
+ result = Brealloc(result, 1);
+ result->x[0] = i;
+ result->wds = 1;
+ return result;
+}
+
+/* Do: c = a * b. */
+
+static Bigint *
+mult
+#ifdef KR_headers
+ (c, a, b) Bigint *a, *b, *c;
+#else
+ (Bigint *c, Bigint *a, Bigint *b)
+#endif
+{
+ int k, wa, wb, wc;
+ unsigned32 carry, y, z;
+ unsigned32 *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ unsigned32 z2;
+ if (a->wds < b->wds) {
+ Bigint *tmp = a;
+ a = b;
+ b = tmp;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Brealloc(c, k);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+ for(; xb < xbe; xb++, xc0++) {
+ if ((y = *xb & 0xffff)) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16)) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+/* Returns b*(5**k). b is modified. */
+/* Re-written by Per Bothner to not need a static list. */
+
+static Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ static int p05[6] = { 5, 25, 125, 625, 3125, 15625 };
+
+ for (; k > 6; k -= 6)
+ b = multadd(b, 15625, 0); /* b *= 5**6 */
+ if (k == 0)
+ return b;
+ else
+ return multadd(b, p05[k-1], 0);
+}
+
+/* Re-written by Per Bothner so shift can be in place. */
+
+static Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i;
+ unsigned32 *x, *x1, *xe;
+ int old_wds = b->wds;
+ int n = k >> 5;
+ int k1 = b->k;
+ int n1 = n + old_wds + 1;
+
+ if (k == 0)
+ return b;
+
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b = Brealloc(b, k1);
+
+ xe = b->x; /* Source limit */
+ x = xe + old_wds; /* Source pointer */
+ x1 = x + n; /* Destination pointer */
+ if (k &= 0x1f) {
+ int k1 = 32 - k;
+ unsigned32 z = *--x;
+ if ((*x1 = (z >> k1)) != 0) {
+ ++n1;
+ }
+ while (x > xe) {
+ unsigned32 w = *--x;
+ *--x1 = (z << k) | (w >> k1);
+ z = w;
+ }
+ *--x1 = z << k;
+ }
+ else
+ do {
+ *--x1 = *--x;
+ } while(x > xe);
+ while (x1 > xe)
+ *--x1 = 0;
+ b->wds = n1 - 1;
+ return b;
+}
+
+static int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ unsigned32 *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+ }
+
+/* Do: c = a-b. */
+
+static Bigint *
+diff
+#ifdef KR_headers
+ (c, a, b) Bigint *c, *a, *b;
+#else
+ (Bigint *c, Bigint *a, Bigint *b)
+#endif
+{
+ int i, wa, wb;
+ _G_int32_t borrow, y; /* We need signed shifts here. */
+ unsigned32 *xa, *xae, *xb, *xbe, *xc;
+ _G_int32_t z;
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Brealloc(c, 0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ Bigint *tmp = a;
+ a = b;
+ b = tmp;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Brealloc(c, a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+static double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ register _G_int32_t L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ setwords(a, L, 0);
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift)
+ setwords(a, 0x80000 >> L, 0);
+ else {
+ L -= Exp_shift;
+ setwords(a, 0, L >= 31 ? 1 : 1 << (31 - L));
+ }
+ }
+#endif
+ return a;
+ }
+
+static double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ unsigned32 *xa, *xa0, w, y, z;
+ int k;
+ double d;
+ unsigned32 d0, d1;
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+ if (k < Ebits) {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+ 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
+ setwords(d, d0 >> 16 | d0 << 16, d1 >> 16 | d1 << 16);
+#else
+ setwords (d, d0, d1);
+#endif
+ return d;
+ }
+
+static Bigint *
+d2b
+#ifdef KR_headers
+ (result, d, e, bits) Bigint *result; double d; int *e, *bits;
+#else
+ (Bigint *result, double d, int *e, int *bits)
+#endif
+{
+ int de, i, k;
+ unsigned32 *x, y, z;
+ unsigned32 d0, d1;
+#ifdef VAX
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+ d0 = word0(d);
+ d1 = word1(d);
+#endif
+
+ result = Brealloc(result, 1);
+ x = result->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+
+ de = (int)(d0 >> Exp_shift); /* The exponent part of d. */
+
+ /* Put back the suppressed high-order bit, if normalized. */
+#ifndef IBM
+#ifndef Sudden_Underflow
+ if (de)
+#endif
+ z |= Exp_msk11;
+#endif
+
+ 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;
+ }
+
+static double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+ k = ka - kb + 32*(a->wds - b->wds);
+#ifdef IBM
+ if (k > 0) {
+ addword0(da, (k >> 2)*Exp_msk1);
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ addword0(db,(k >> 2)*Exp_msk1);
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ addword0(da, k*Exp_msk1);
+ else {
+ k = -k;
+ addword0(db, k*Exp_msk1);
+ }
+#endif
+ return da / db;
+ }
+
+static CONST double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+#ifdef IEEE_Arith
+static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+static CONST double bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+ double
+_IO_strtod
+#ifdef KR_headers
+ (s00, se) CONST char *s00; char **se;
+#else
+ (CONST char *s00, char **se)
+#endif
+{
+ 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;
+ _G_int32_t L;
+ unsigned32 y, z;
+ Bigint _bb, _b_avail, _bd, _bd0, _bs, _delta;
+ Bigint *bb = Binit(&_bb);
+ Bigint *bd = Binit(&_bd);
+ Bigint *bd0 = Binit(&_bd0);
+ Bigint *bs = Binit(&_bs);
+ Bigint *b_avail = Binit(&_b_avail);
+ Bigint *delta = Binit(&_delta);
+
+ TEST_ENDIANNESS;
+ sign = nz0 = nz = 0;
+ rv = 0.;
+ for(s = s00;;s++) switch(*s) {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ /* "+" and "-" should be reported as an error? */
+ sign = 0;
+ s = s00;
+ goto ret;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == '.') {
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ e = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ e = 10*e + c - '0';
+ if (s - s1 > 8)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 9999999;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+ rv = tens[k - 9] * rv + z;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ addword0(rv, - P*Exp_msk1);
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ addword0(rv, P*Exp_msk1);
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15))
+ rv *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ errno = ERANGE;
+#if defined(sun) && !defined(__svr4__)
+/* SunOS defines HUGE_VAL as __infinity(), which is in libm. */
+#undef HUGE_VAL
+#endif
+#ifndef HUGE_VAL
+#define HUGE_VAL 1.7976931348623157E+308
+#endif
+ rv = HUGE_VAL;
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ addword0(rv, -P*Exp_msk1);
+ rv *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ setwords(rv, Big0, Big1);
+ }
+ else
+ addword0(rv, P*Exp_msk1);
+ }
+
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15))
+ rv /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (!rv) {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (!rv) {
+ undfl:
+ rv = 0.;
+ errno = ERANGE;
+ goto ret;
+ }
+ setwords(rv, Tiny0, Tiny1);
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(bd0, s0, nd0, nd, y);
+ bd = Brealloc(bd, bd0->k);
+
+ for(;;) {
+ Bcopy(bd, bd0);
+ bb = d2b(bb, rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(bs, 1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P-Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ Bigint *b_tmp;
+ bs = pow5mult(bs, bb5);
+ b_tmp = mult(b_avail, bs, bb);
+ b_avail = bb;
+ bb = b_tmp;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(delta, bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ setword0(rv, (word0(rv) & Exp_mask)
+ + Exp_msk1);
+#ifdef IBM
+ setword0 (rv,
+ word0(rv) | (Exp_msk1 >> 4));
+#endif
+ setword1(rv, 0);
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ setwords(rv, L | Bndry_mask1, 0xffffffff);
+#ifdef IBM
+ continue;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (!rv)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ addword0(rv, - P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ setwords(rv, Big0, Big1);
+ continue;
+ }
+ else
+ addword0(rv, P*Exp_msk1);
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ addword0(rv, P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ setwords(rv, Tiny0, Tiny1);
+ continue;
+ }
+ else
+ addword0(rv, -P*Exp_msk1);
+ }
+ else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = word0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = (_G_int32_t)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ }
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ Bfree(b_avail);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -rv : rv;
+ }
+
+static int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ _G_int32_t borrow, y;
+ unsigned32 carry, q, ys;
+ unsigned32 *bx, *bxe, *sx, *sxe;
+ _G_int32_t z;
+ unsigned32 si, zs;
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+ }
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the long
+ * calculation.
+ */
+
+ char *
+_IO_dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ 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;
+ _G_int32_t L;
+#ifndef Sudden_Underflow
+ int denorm;
+#endif
+ Bigint _b_avail, _b, _mhi, _mlo, _S;
+ Bigint *b_avail = Binit(&_b_avail);
+ Bigint *b = Binit(&_b);
+ Bigint *S = Binit(&_S);
+ /* mhi and mlo are only set and used if leftright. */
+ Bigint *mhi = NULL, *mlo = NULL;
+ double d2, ds, eps;
+ char *s, *s0;
+ static Bigint *result = NULL;
+ static int result_k;
+
+ TEST_ENDIANNESS;
+ if (result) {
+ /* result is contains a string, so its fields (interpreted
+ as a Bigint have been trashed. Restore them.
+ This is a really ugly interface - result should
+ not be static, since that is not thread-safe. FIXME. */
+ result->k = result_k;
+ result->maxwds = 1 << result_k;
+ result->on_stack = 0;
+ }
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ setword0(d, word0(d) & ~Sign_bit); /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff))
+ {
+ s = "Infinity";
+ if (rve)
+ *rve = s + 8;
+ }
+ else
+#endif
+ {
+ s = "NaN";
+ if (rve)
+ *rve = s +3;
+ }
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (!d) {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(b, d, &be, &bbits);
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#ifndef Sudden_Underflow
+ if (i) {
+#endif
+ d2 = d;
+ setword0(d2, (word0(d2) & Frac_mask1) | Exp_11);
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+ d2 /= 1 << j;
+#endif
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+ unsigned32 x;
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
+ : word1(d) << (32 - i);
+ d2 = x;
+ addword0(d2, - 31*Exp_msk1); /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+
+ /* Now i is the unbiased base-2 exponent. */
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = i*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = i*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i) by 0.301029995663981; since |i| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ /* i is now an upper bound of the number of digits to generate. */
+ j = sizeof(unsigned32) * (1<<BIGINT_MINIMUM_K);
+ /* The test is <= so as to allow room for the final '\0'. */
+ for(result_k = BIGINT_MINIMUM_K; BIGINT_HEADER_SIZE + j <= i;
+ j <<= 1) result_k++;
+ if (!result || result_k > result->k)
+ {
+ Bfree (result);
+ result = Balloc(result_k);
+ }
+ s = s0 = (char *)result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if ((j1 = -k)) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ addword0(eps, - (P-1)*Exp_msk1);
+ if (ilim == 0) {
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = (_G_int32_t)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for(i = 1;; i++, d *= 10.) {
+ L = (_G_int32_t)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++) {
+ L = (_G_int32_t)(d / ds);
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ d += d;
+ if (d > ds || (d == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ if (leftright) {
+ if (mode < 2) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(Binit(&_mhi), 1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ Bigint *b_tmp;
+ mhi = pow5mult(mhi, m5);
+ b_tmp = mult(b_avail, mhi, b);
+ b_avail = b;
+ b = b_tmp;
+ }
+ if ((j = b5 - m5))
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(S, 1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2) {
+ if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & Exp_mask
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
+ i = 32 - i;
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ if (spec_case) {
+ mlo = Brealloc(Binit(&_mlo), mhi->k);
+ Bcopy(mlo, mhi);
+ mhi = lshift(mhi, Log2P);
+ }
+ else
+ mlo = mhi;
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ b_avail = diff(b_avail, S, mhi); /* b_avail = S - mi */
+ j1 = b_avail->sign ? 1 : cmp(b, b_avail);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(word1(d) & 1)) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1)
+#endif
+ )) {
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(b_avail);
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
+#endif /* _IO_USE_DTOA */
diff --git a/gnu/lib/libg++/libio/floatio.h b/gnu/lib/libg++/libio/floatio.h
new file mode 100644
index 00000000000..827767bde35
--- /dev/null
+++ b/gnu/lib/libg++/libio/floatio.h
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * %W% (Berkeley) %G%
+ */
+
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
diff --git a/gnu/lib/libg++/libio/fstream.cc b/gnu/lib/libg++/libio/fstream.cc
new file mode 100644
index 00000000000..8930e0b9271
--- /dev/null
+++ b/gnu/lib/libg++/libio/fstream.cc
@@ -0,0 +1,110 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+extern "C" {
+#include "libioP.h"
+}
+#include <fstream.h>
+
+inline void
+fstreambase::__fb_init()
+{
+#ifdef _IO_NEW_STREAMS
+#if !_IO_UNIFIED_JUMPTABLES
+ /* Uses the _IO_file_jump jumptable, for eficiency. */
+ __my_fb._jumps = &_IO_file_jumps;
+ __my_fb._vtable() = builtinbuf_vtable;
+#endif
+ init (&__my_fb);
+#else
+ init(filebuf::__new());
+ _flags &= ~ios::dont_close;
+#endif
+}
+
+fstreambase::fstreambase()
+{
+ __fb_init ();
+}
+
+fstreambase::fstreambase(int fd)
+{
+ __fb_init ();
+ _IO_file_attach(rdbuf(), fd);
+}
+
+fstreambase::fstreambase(const char *name, int mode, int prot)
+{
+ __fb_init ();
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+fstreambase::fstreambase(int fd, char *p, int l)
+{
+#ifdef _IO_NEW_STREAMS
+ __fb_init ();
+#else
+ init(filebuf::__new());
+#endif
+ _IO_file_attach(rdbuf(), fd);
+ _IO_file_setbuf(rdbuf(), p, l);
+}
+
+void fstreambase::open(const char *name, int mode, int prot)
+{
+ clear();
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+void fstreambase::close()
+{
+ if (!rdbuf()->close())
+ set(ios::failbit);
+}
+
+void fstreambase::attach(int fd)
+{
+ if (!rdbuf()->attach(fd))
+ set(ios::failbit);
+}
+
+#if 0
+static int mode_to_sys(enum open_mode mode)
+{
+ return O_WRONLY;
+}
+
+static char* fopen_cmd_arg(io_mode i)
+{
+ return "w";
+}
+#endif
diff --git a/gnu/lib/libg++/libio/fstream.h b/gnu/lib/libg++/libio/fstream.h
new file mode 100644
index 00000000000..398cd31d75a
--- /dev/null
+++ b/gnu/lib/libg++/libio/fstream.h
@@ -0,0 +1,92 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _FSTREAM_H
+#define _FSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <iostream.h>
+
+extern "C++" {
+class fstreambase : virtual public ios {
+#ifdef _IO_NEW_STREAMS
+ filebuf __my_fb;
+#endif
+ void __fb_init ();
+ public:
+ fstreambase();
+ fstreambase(int fd);
+ fstreambase(int fd, char *p, int l); /* Deprecated */
+ fstreambase(const char *name, int mode, int prot=0664);
+ void close();
+#ifdef _IO_NEW_STREAMS
+ filebuf* rdbuf() const { return (filebuf*)&__my_fb; }
+#else
+ filebuf* rdbuf() const { return (filebuf*) ios::rdbuf(); }
+#endif
+ void open(const char *name, int mode, int prot=0664);
+ int is_open() const { return rdbuf()->is_open(); }
+ void setbuf(char *ptr, int len) { rdbuf()->setbuf(ptr, len); }
+ void attach(int fd);
+#ifdef _STREAM_COMPAT
+ int filedesc() { return rdbuf()->fd(); }
+ fstreambase& raw() { rdbuf()->setbuf(NULL, 0); return *this; }
+#endif
+};
+
+class ifstream : public fstreambase, public istream {
+ public:
+ ifstream() : fstreambase() { }
+ ifstream(int fd) : fstreambase(fd) { }
+ ifstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/
+ ifstream(const char *name, int mode=ios::in, int prot=0664)
+ : fstreambase(name, mode, prot) { }
+ void open(const char *name, int mode=ios::in, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+
+class ofstream : public fstreambase, public ostream {
+ public:
+ ofstream() : fstreambase() { }
+ ofstream(int fd) : fstreambase(fd) { }
+ ofstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/
+ ofstream(const char *name, int mode=ios::out, int prot=0664)
+ : fstreambase(name, mode, prot) { }
+ void open(const char *name, int mode=ios::out, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+
+class fstream : public fstreambase, public iostream {
+ public:
+ fstream() : fstreambase() { }
+ fstream(int fd) : fstreambase(fd) { }
+ fstream(const char *name, int mode, int prot=0664)
+ : fstreambase(name, mode, prot) { }
+ fstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/
+ void open(const char *name, int mode, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+} // extern "C++"
+#endif /*!_FSTREAM_H*/
diff --git a/gnu/lib/libg++/libio/genops.c b/gnu/lib/libg++/libio/genops.c
new file mode 100644
index 00000000000..7eb2d43ee19
--- /dev/null
+++ b/gnu/lib/libg++/libio/genops.c
@@ -0,0 +1,837 @@
+/*
+Copyright (C) 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Generic or default I/O operations. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+void
+DEFUN(_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
+DEFUN(_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
+DEFUN(_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
+DEFUN(_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
+DEFUN(_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
+DEFUN(_IO_switch_to_get_mode, (fp),
+ register _IO_FILE *fp)
+{
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ if (_IO_OVERFLOW (fp, EOF) == EOF)
+ return EOF;
+ if (_IO_in_backup(fp))
+ fp->_IO_read_base = fp->_IO_backup_base;
+ else
+ {
+ fp->_IO_read_base = fp->_IO_buf_base;
+ if (fp->_IO_write_ptr > fp->_IO_read_end)
+ fp->_IO_read_end = fp->_IO_write_ptr;
+ }
+ fp->_IO_read_ptr = fp->_IO_write_ptr;
+
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
+
+ fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ return 0;
+}
+
+void
+DEFUN(_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
+DEFUN(_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
+DEFUN(__overflow, (f, ch),
+ _IO_FILE *f AND int ch)
+{
+ return _IO_OVERFLOW (f, ch);
+}
+
+static int
+DEFUN(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
+DEFUN(__underflow, (fp),
+ _IO_FILE *fp)
+{
+ if (_IO_in_put_mode(fp))
+ if (_IO_switch_to_get_mode(fp) == EOF) return EOF;
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *(unsigned char*)fp->_IO_read_ptr;
+ if (_IO_in_backup(fp))
+ {
+ _IO_switch_to_main_get_area(fp);
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *fp->_IO_read_ptr;
+ }
+ if (_IO_have_markers(fp))
+ {
+ if (save_for_backup (fp))
+ return EOF;
+ }
+ else if (_IO_have_backup(fp))
+ _IO_free_backup_area(fp);
+ return _IO_UNDERFLOW (fp);
+}
+
+int
+DEFUN(__uflow, (fp),
+ _IO_FILE *fp)
+{
+ if (_IO_in_put_mode(fp))
+ if (_IO_switch_to_get_mode(fp) == EOF) return EOF;
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *(unsigned char*)fp->_IO_read_ptr++;
+ if (_IO_in_backup(fp))
+ {
+ _IO_switch_to_main_get_area(fp);
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ return *fp->_IO_read_ptr++;
+ }
+ if (_IO_have_markers(fp))
+ {
+ if (save_for_backup (fp))
+ return EOF;
+ }
+ else if (_IO_have_backup(fp))
+ _IO_free_backup_area(fp);
+ return _IO_UFLOW (fp);
+}
+
+void
+DEFUN(_IO_setb, (f, b, eb, a),
+ _IO_FILE *f AND char *b AND char *eb AND 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
+DEFUN(_IO_doallocbuf, (fp),
+ register _IO_FILE *fp)
+{
+ if (fp->_IO_buf_base)
+ return;
+ if (!(fp->_flags & _IO_UNBUFFERED))
+ if (_IO_DOALLOCATE (fp) != EOF)
+ return;
+ _IO_setb(fp, fp->_shortbuf, fp->_shortbuf+1, 0);
+}
+
+int
+DEFUN(_IO_default_underflow, (fp),
+ _IO_FILE *fp)
+{
+ return EOF;
+}
+
+int
+DEFUN(_IO_default_uflow, (fp),
+ _IO_FILE *fp)
+{
+ int ch = _IO_UNDERFLOW (fp);
+ if (ch == EOF)
+ return EOF;
+ return *(unsigned char*)fp->_IO_read_ptr++;
+}
+
+_IO_size_t
+DEFUN(_IO_default_xsputn, (f, data, n),
+ register _IO_FILE *f AND const void *data AND _IO_size_t n)
+{
+ register const char *s = (char*) 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
+DEFUN(_IO_sgetn, (fp, data, n),
+ _IO_FILE *fp AND void *data AND _IO_size_t n)
+{
+ /* FIXME handle putback buffer here! */
+ return _IO_XSGETN (fp, data, n);
+}
+
+_IO_size_t
+DEFUN(_IO_default_xsgetn, (fp, data, n),
+ _IO_FILE *fp AND void *data AND _IO_size_t n)
+{
+ register _IO_size_t more = n;
+ register char *s = (char*) 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
+DEFUN(_IO_sync, (fp),
+ register _IO_FILE *fp)
+{
+ return 0;
+}
+
+_IO_FILE*
+DEFUN(_IO_default_setbuf, (fp, p, len),
+ register _IO_FILE *fp AND char* p AND _IO_ssize_t len)
+{
+ if (_IO_SYNC (fp) == EOF)
+ return NULL;
+ if (p == NULL || len == 0)
+ {
+ fp->_flags |= _IO_UNBUFFERED;
+ _IO_setb(fp, fp->_shortbuf, fp->_shortbuf+1, 0);
+ }
+ else
+ {
+ fp->_flags &= ~_IO_UNBUFFERED;
+ _IO_setb(fp, p, p+len, 0);
+ }
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
+ return fp;
+}
+
+_IO_pos_t
+DEFUN(_IO_default_seekpos, (fp, pos, mode),
+ _IO_FILE *fp AND _IO_pos_t pos AND int mode)
+{
+ return _IO_SEEKOFF (fp, _IO_pos_as_off(pos), 0, mode);
+}
+
+int
+DEFUN(_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
+DEFUN(_IO_init, (fp, flags),
+ register _IO_FILE *fp AND 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
+DEFUN(_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
+DEFUN(_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
+DEFUN(_IO_default_seekoff, (fp, offset, dir, mode),
+ register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
+{
+ return _IO_pos_BAD;
+}
+
+int
+DEFUN(_IO_sputbackc, (fp, c),
+ register _IO_FILE *fp AND 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 _IO_PBACKFAIL (fp, c);
+}
+
+int
+DEFUN(_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 _IO_PBACKFAIL (fp, EOF);
+}
+
+#if 0 /* Work in progress */
+void
+DEFUN(_IO_set_column, (fp, c),
+ register _IO_FILE *fp AND int c)
+{
+ if (c == -1)
+ fp->_column = -1;
+ else
+ fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
+}
+#else
+int
+DEFUN(_IO_set_column, (fp, i),
+ register _IO_FILE *fp AND int i)
+{
+ fp->_cur_column = i+1;
+ return 0;
+}
+#endif
+
+
+unsigned
+DEFUN(_IO_adjust_column, (start, line, count),
+ unsigned start AND const char *line AND int count)
+{
+ register const char *ptr = line + count;
+ while (ptr > line)
+ if (*--ptr == '\n')
+ return line + count - ptr - 1;
+ return start + count;
+}
+
+int
+DEFUN(_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
+DEFUN_VOID(_IO_flush_all)
+{
+ int result = 0;
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if (fp->_IO_write_ptr > fp->_IO_write_base
+ && _IO_OVERFLOW (fp, EOF) == EOF)
+ result = EOF;
+ return result;
+}
+
+void
+DEFUN_VOID(_IO_flush_all_linebuffered)
+{
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if (fp->_flags & _IO_LINE_BUF)
+ _IO_OVERFLOW (fp, EOF);
+}
+
+void
+DEFUN_VOID(_IO_unbuffer_all)
+{
+ _IO_FILE *fp;
+ for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+ if (! (fp->_flags & _IO_UNBUFFERED))
+ _IO_SETBUF (fp, NULL, 0);
+}
+
+void
+DEFUN_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
+DEFUN(_IO_init_marker, (marker, fp),
+ struct _IO_marker *marker AND _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
+DEFUN(_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
+DEFUN(_IO_marker_difference, (mark1, mark2),
+ struct _IO_marker *mark1 AND struct _IO_marker *mark2)
+{
+ return mark1->_pos - mark2->_pos;
+}
+
+/* Return difference between MARK and current posistion of MARK's stream. */
+int
+DEFUN(_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
+DEFUN(_IO_seekmark, (fp, mark, delta),
+ _IO_FILE *fp AND struct _IO_marker *mark AND 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
+DEFUN(_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
+DEFUN(_IO_nobackup_pbackfail, (fp, c),
+ register _IO_FILE *fp AND 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
+DEFUN(_IO_default_pbackfail, (fp, c),
+ register _IO_FILE *fp AND 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
+DEFUN(_IO_default_seek, (fp, offset, dir),
+ _IO_FILE *fp AND _IO_off_t offset AND int dir)
+{
+ return _IO_pos_BAD;
+}
+
+int
+DEFUN(_IO_default_stat, (fp, st),
+ _IO_FILE *fp AND void* st)
+{
+ return EOF;
+}
+
+_IO_ssize_t
+DEFUN(_IO_default_read, (fp, data, n),
+ register _IO_FILE* fp AND void* data AND _IO_ssize_t n)
+{
+ return -1;
+}
+
+_IO_ssize_t
+DEFUN(_IO_default_write, (fp, data, n),
+ register _IO_FILE* fp AND const void* data AND _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 00000000000..e74f4dbac4f
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <indstream.h>
+
+indirectbuf::indirectbuf(streambuf *get, streambuf *put, int delete_mode)
+: streambuf()
+{
+ _get_stream = get;
+ _put_stream = put == NULL ? get : put;
+ _delete_flags = delete_mode;
+}
+
+indirectbuf::~indirectbuf()
+{
+ if (_delete_flags & ios::in) delete get_stream();
+ if (_delete_flags & ios::out) delete put_stream();
+}
+
+streamsize indirectbuf::xsputn(const char* s, streamsize n)
+{
+ return put_stream()->sputn(s, n);
+}
+
+streamsize indirectbuf::xsgetn(char* s, streamsize n)
+{
+ return get_stream()->sgetn(s, n);
+}
+
+int indirectbuf::overflow(int c /* = EOF */)
+{
+ if (c == EOF)
+ return put_stream()->overflow(c);
+ else
+ return put_stream()->sputc(c);
+}
+
+int indirectbuf::underflow()
+{
+ return get_stream()->sbumpc();
+}
+
+streampos indirectbuf::seekoff(streamoff off, _seek_dir dir, int mode)
+{
+ int ret_val = 0;
+ int select = mode == 0 ? (ios::in|ios::out) : mode;
+ streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL;
+ if (gbuf == pbuf)
+ ret_val = gbuf->seekoff(off, dir, mode);
+ else {
+ if (gbuf)
+ ret_val = gbuf->seekoff(off, dir, ios::in);
+ if (pbuf && ret_val != EOF)
+ ret_val = pbuf->seekoff(off, dir, ios::out);
+ }
+ return ret_val;
+}
+
+streampos indirectbuf::seekpos(streampos pos, int mode)
+{
+ int ret_val = EOF;
+ int select = mode == 0 ? (ios::in|ios::out) : mode;
+ streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL;
+ if (gbuf == pbuf)
+ 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/indstream.h b/gnu/lib/libg++/libio/indstream.h
new file mode 100644
index 00000000000..6afffdd9bc9
--- /dev/null
+++ b/gnu/lib/libg++/libio/indstream.h
@@ -0,0 +1,76 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _INDSTREAM_H
+#define _INDSTREAM_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <iostream.h>
+
+extern "C++" {
+// An indirectbuf is one that forwards all of its I/O requests
+// to another streambuf.
+// All get-related requests are sent to get_stream().
+// All put-related requests are sent to put_stream().
+
+// An indirectbuf can be used to implement Common Lisp
+// synonym-streams and two-way-streams.
+//
+// class synonymbuf : public indirectbuf {
+// Symbol *sym;
+// synonymbuf(Symbol *s) { sym = s; }
+// virtual streambuf *lookup_stream(int mode) {
+// return coerce_to_streambuf(lookup_value(sym)); }
+// };
+
+class indirectbuf : public streambuf {
+ protected:
+ streambuf *_get_stream; // Optional cache for get_stream().
+ streambuf *_put_stream; // Optional cache for put_stream().
+ int _delete_flags;
+ public:
+ streambuf *get_stream()
+ { return _get_stream ? _get_stream : lookup_stream(ios::in); }
+ streambuf *put_stream()
+ { return _put_stream ? _put_stream : lookup_stream(ios::out); }
+ virtual streambuf *lookup_stream(int/*mode*/) { return NULL; } // ERROR!
+ indirectbuf(streambuf *get=NULL, streambuf *put=NULL, int delete_mode=0);
+ virtual ~indirectbuf();
+ virtual streamsize xsputn(const char* s, streamsize n);
+ virtual streamsize xsgetn(char* s, streamsize n);
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual int sync();
+ virtual int pbackfail(int c);
+};
+} // extern "C++"
+
+#endif /* !_INDSTREAM_H */
diff --git a/gnu/lib/libg++/libio/ioassign.cc b/gnu/lib/libg++/libio/ioassign.cc
new file mode 100644
index 00000000000..5b8e68bbf53
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioassign.cc
@@ -0,0 +1,49 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include <iostream.h>
+#include "libioP.h"
+
+// These method are provided for backward compatibility reasons.
+// It's generally poor style to use them.
+// They are not supported by the ANSI/ISO working paper.
+
+_IO_istream_withassign& _IO_istream_withassign::operator=(istream& rhs)
+{
+ if (&rhs != (istream*)this)
+ {
+ init (rhs.rdbuf ());
+ _gcount = 0;
+ }
+ return *this;
+}
+
+_IO_ostream_withassign& _IO_ostream_withassign::operator=(ostream& rhs)
+{
+ if (&rhs != (ostream*)this)
+ init (rhs.rdbuf ());
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/ioextend.cc b/gnu/lib/libg++/libio/ioextend.cc
new file mode 100644
index 00000000000..e0ec0cb6499
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioextend.cc
@@ -0,0 +1,132 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <iostream.h>
+
+static int __xalloc = 0;
+
+int ios::xalloc()
+{
+ return __xalloc++;
+}
+
+static ios::fmtflags __used_fmt_flags
+= ios::skipws | ios::left | ios::right | ios::internal
+| ios::dec | ios::oct | ios::hex | ios::showbase | ios::showpoint
+| ios::uppercase | ios::showpos | ios::scientific | ios::fixed
+#ifndef _IO_NEW_STREAMS
+| ios::dont_close
+#endif
+| ios::unitbuf | ios::stdio;
+
+ios::fmtflags ios::bitalloc()
+{
+ fmtflags bit_to_try = (fmtflags)1;
+ for (; bit_to_try; bit_to_try <<= 1)
+ {
+ if ((__used_fmt_flags & bit_to_try) == 0)
+ {
+ __used_fmt_flags |= bit_to_try;
+ return bit_to_try;
+ }
+ }
+ return 0;
+}
+
+// NOTE: This implementation of ios::iword and ios::pword assumes
+// that these methods are seldom used, so we want to minimize
+// the space and time overhead when NOT using these methods.
+//
+// ANSI specifies two conceptually-infinite arrays, one whose
+// elements are longs, and one whose elements are (void*)s.
+// We implement this as a single array, each of whose element is
+// a (struct ptr_and_long), which has space for both a long and a void*.
+// We also specify that (the i field of) the 0'th element of the array
+// contains the allocated length of the array (not counting that
+// initial element).
+
+struct ptr_and_long {
+ void *p;
+ long i;
+};
+
+static struct ptr_and_long&
+get_array_element(ios& io, int index)
+{
+ if (index < 0)
+ io._throw_failure();
+ register struct ptr_and_long *array = (ptr_and_long*)io._arrays;
+ int old_length = array == NULL ? 0 : array[0].i;
+ if (index >= old_length)
+ {
+ register int i;
+ int new_length = index + 10;
+ register struct ptr_and_long *new_array
+ = new ptr_and_long[1 + new_length];
+ if (array != NULL)
+ {
+ for (i = 1; i <= old_length; i++)
+ new_array[i] = array[i];
+ delete [] array;
+ }
+ for (i = old_length + 1; i <= new_length; i++)
+ {
+ new_array[i].i = 0;
+ new_array[i].p = (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 00000000000..f3ae0964e82
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+int
+DEFUN(_IO_fclose, (fp),
+ register _IO_FILE *fp)
+{
+ int status;
+ CHECK_FILE(fp, EOF);
+ if (fp->_IO_file_flags & _IO_IS_FILEBUF)
+ status = _IO_file_close_it(fp);
+ else
+ status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
+ _IO_FINISH (fp);
+ 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/iofdopen.c b/gnu/lib/libg++/libio/iofdopen.c
new file mode 100644
index 00000000000..f8bc76869ad
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofdopen.c
@@ -0,0 +1,121 @@
+/*
+Copyright (C) 1993, 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <fcntl.h>
+
+#ifndef _IO_fcntl
+#define _IO_fcntl fcntl
+#endif
+
+_IO_FILE *
+DEFUN(_IO_fdopen, (fd, mode),
+ int fd AND const char *mode)
+{
+ int read_write;
+ int posix_mode = 0;
+ struct _IO_FILE_plus *fp;
+ int fd_flags;
+
+ switch (*mode++)
+ {
+ case 'r':
+ read_write = _IO_NO_WRITES;
+ break;
+ case 'w':
+ read_write = _IO_NO_READS;
+ break;
+ case 'a':
+ posix_mode = O_APPEND;
+ read_write = _IO_NO_READS|_IO_IS_APPENDING;
+ break;
+ default:
+#ifdef EINVAL
+ errno = EINVAL;
+#endif
+ return NULL;
+ }
+ if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
+ read_write &= _IO_IS_APPENDING;
+#ifdef F_GETFL
+ fd_flags = _IO_fcntl (fd, F_GETFL);
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
+ if (fd_flags == -1
+ || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
+ || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
+ return NULL;
+
+ /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
+ [System Application Program Interface (API) Amendment 1:
+ Realtime Extensions], Rationale B.8.3.3
+ Open a Stream on a File Descriptor says:
+
+ Although not explicitly required by POSIX.1, a good
+ implementation of append ("a") mode would cause the
+ O_APPEND flag to be set.
+
+ (Historical implementations [such as Solaris2] do a one-time
+ seek in fdopen.)
+
+ However, we do not turn O_APPEND off if the mode is "w" (even
+ though that would seem consistent) because that would be more
+ likely to break historical programs.
+ */
+ if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
+ {
+#ifdef F_SETFL
+ if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
+#endif
+ return NULL;
+ }
+#endif
+
+ fp = (struct _IO_FILE_plus*)malloc(sizeof(struct _IO_FILE_plus));
+ if (fp == NULL)
+ return NULL;
+ _IO_init(&fp->file, 0);
+ _IO_JUMPS(&fp->file) = &_IO_file_jumps;
+ _IO_file_init(&fp->file);
+#if !_IO_UNIFIED_JUMPTABLES
+ fp->vtable = NULL;
+#endif
+ if (_IO_file_attach(&fp->file, fd) == NULL)
+ {
+ _IO_un_link(&fp->file);
+ free (fp);
+ return NULL;
+ }
+ fp->file._flags &= ~_IO_DELETE_DONT_CLOSE;
+
+ fp->file._IO_file_flags =
+ _IO_mask_flags(&fp->file, read_write,
+ _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+
+ return (_IO_FILE*)fp;
+}
diff --git a/gnu/lib/libg++/libio/iofflush.c b/gnu/lib/libg++/libio/iofflush.c
new file mode 100644
index 00000000000..ecb816d4198
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofflush.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+int
+DEFUN(_IO_fflush, (fp),
+ register _IO_FILE *fp)
+{
+ if (fp == NULL)
+ return _IO_flush_all();
+ else
+ {
+ CHECK_FILE(fp, EOF);
+ return _IO_SYNC (fp) ? EOF : 0;
+ }
+}
diff --git a/gnu/lib/libg++/libio/iofgetpos.c b/gnu/lib/libg++/libio/iofgetpos.c
new file mode 100644
index 00000000000..5e7a8632102
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofgetpos.c
@@ -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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <errno.h>
+/* ANSI explicily requires setting errno to a positive value on failure. */
+
+int
+DEFUN(_IO_fgetpos, (fp, posp),
+ _IO_FILE* fp AND _IO_fpos_t *posp)
+{
+ _IO_fpos_t pos;
+ CHECK_FILE(fp, EOF);
+ pos = _IO_seekoff(fp, 0, _IO_seek_cur, 0);
+ 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/iofgets.c b/gnu/lib/libg++/libio/iofgets.c
new file mode 100644
index 00000000000..7b0b708a208
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofgets.c
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+char*
+DEFUN(_IO_fgets, (buf, n, fp),
+ char* buf AND int n AND _IO_FILE* fp)
+{
+ _IO_size_t count;
+ CHECK_FILE(fp, NULL);
+ if (n <= 0)
+ return NULL;
+ count = _IO_getline(fp, buf, n - 1, '\n', 1);
+ if (count == 0 || (fp->_IO_file_flags & _IO_ERR_SEEN))
+ return NULL;
+ buf[count] = 0;
+ return buf;
+}
diff --git a/gnu/lib/libg++/libio/iofopen.c b/gnu/lib/libg++/libio/iofopen.c
new file mode 100644
index 00000000000..96910520ce7
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofopen.c
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+_IO_FILE *
+DEFUN(_IO_fopen, (filename, mode),
+ const char *filename AND const char *mode)
+{
+ struct _IO_FILE_plus *fp =
+ (struct _IO_FILE_plus*)malloc(sizeof(struct _IO_FILE_plus));
+ if (fp == NULL)
+ return NULL;
+ _IO_init(&fp->file, 0);
+ _IO_JUMPS(&fp->file) = &_IO_file_jumps;
+ _IO_file_init(&fp->file);
+#if !_IO_UNIFIED_JUMPTABLES
+ fp->vtable = NULL;
+#endif
+ if (_IO_file_fopen(&fp->file, filename, mode) != NULL)
+ return (_IO_FILE*)fp;
+ _IO_un_link(&fp->file);
+ free (fp);
+ return NULL;
+}
diff --git a/gnu/lib/libg++/libio/iofprintf.c b/gnu/lib/libg++/libio/iofprintf.c
new file mode 100644
index 00000000000..11c76421809
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofprintf.c
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_fprintf
+#ifdef __STDC__
+ (_IO_FILE *fp, const char* format, ...)
+#else
+(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ CHECK_FILE(fp, -1);
+ _IO_va_start(args, format);
+ ret = _IO_vfprintf(fp, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/iofputs.c b/gnu/lib/libg++/libio/iofputs.c
new file mode 100644
index 00000000000..7a2580f7e35
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofputs.c
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <string.h>
+
+int
+DEFUN(_IO_fputs, (str, fp),
+ const char *str AND _IO_FILE *fp)
+{
+ _IO_size_t len = strlen(str);
+ CHECK_FILE(fp, EOF);
+ if (_IO_sputn(fp, str, len) != len)
+ return EOF;
+ return 1;
+}
diff --git a/gnu/lib/libg++/libio/iofread.c b/gnu/lib/libg++/libio/iofread.c
new file mode 100644
index 00000000000..8516cf30c14
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofread.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+_IO_size_t
+DEFUN(_IO_fread, (buf, size, count, fp),
+ void *buf AND _IO_size_t size AND _IO_size_t count AND _IO_FILE* fp)
+{
+ _IO_size_t bytes_requested = size*count;
+ _IO_size_t bytes_read;
+ CHECK_FILE(fp, 0);
+ if (bytes_requested == 0)
+ return 0;
+ 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 00000000000..3e12d9b5315
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_fscanf
+#ifdef __STDC__
+ (_IO_FILE *fp, const char* format, ...)
+#else
+(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ CHECK_FILE(fp, EOF);
+ _IO_va_start(args, format);
+ ret = _IO_vfscanf(fp, format, args, NULL);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/iofsetpos.c b/gnu/lib/libg++/libio/iofsetpos.c
new file mode 100644
index 00000000000..ac8a3deb12d
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofsetpos.c
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+#include <errno.h>
+
+int
+DEFUN(_IO_fsetpos, (fp, posp),
+ _IO_FILE* fp AND const _IO_fpos_t *posp)
+{
+ CHECK_FILE(fp, EOF);
+ if (_IO_seekpos(fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _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/ioftell.c b/gnu/lib/libg++/libio/ioftell.c
new file mode 100644
index 00000000000..d49ddaac821
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioftell.c
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <errno.h>
+/* ANSI explicily requires setting errno to a positive value on failure. */
+
+long int
+DEFUN(_IO_ftell, (fp),
+ _IO_FILE* fp)
+{
+ _IO_pos_t pos;
+ CHECK_FILE(fp, -1L);
+ pos = _IO_seekoff(fp, 0, _IO_seek_cur, 0);
+ if (pos == _IO_pos_BAD)
+ {
+#ifdef EIO
+ if (errno == 0)
+ errno = EIO;
+#endif
+ return -1L;
+ }
+ return _IO_pos_as_off(pos);
+}
diff --git a/gnu/lib/libg++/libio/iofwrite.c b/gnu/lib/libg++/libio/iofwrite.c
new file mode 100644
index 00000000000..eb3cd32b028
--- /dev/null
+++ b/gnu/lib/libg++/libio/iofwrite.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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+_IO_size_t
+DEFUN(_IO_fwrite, (buf, size, count, fp),
+ const void* buf AND _IO_size_t size AND _IO_size_t count
+ AND _IO_FILE *fp)
+{
+ _IO_size_t request = size*count;
+ _IO_size_t written;
+ CHECK_FILE(fp, 0);
+ if (request == 0)
+ return 0;
+ written = _IO_sputn(fp, (const char *)buf, request);
+ /* Many traditional implementations return 0 if size==0 && count > 0,
+ but ANSI seems to require us to return count in this case. */
+ if (written == request)
+ return count;
+ else
+ return written/size;
+}
diff --git a/gnu/lib/libg++/libio/iogetdelim.c b/gnu/lib/libg++/libio/iogetdelim.c
new file mode 100644
index 00000000000..ee6c0bf1f19
--- /dev/null
+++ b/gnu/lib/libg++/libio/iogetdelim.c
@@ -0,0 +1,99 @@
+/*
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <string.h>
+#include <errno.h>
+
+/* Read up to (and including) a TERMINATOR from FP into *LINEPTR
+ (and null-terminate it). *LINEPTR is a pointer returned from malloc (or
+ NULL), pointing to *N characters of space. It is realloc'ed as
+ necessary. Returns the number of characters read (not including the
+ null terminator), or -1 on error or EOF. */
+
+_IO_ssize_t
+DEFUN(_IO_getdelim, (lineptr, n, delimiter, fp),
+ char **lineptr AND _IO_size_t *n AND int delimiter AND _IO_FILE *fp)
+{
+ register _IO_ssize_t cur_len = 0;
+ _IO_ssize_t len;
+
+ if (lineptr == NULL || n == NULL)
+ {
+#ifdef EINVAL
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+ CHECK_FILE (fp, -1);
+ if (_IO_ferror (fp))
+ return -1;
+
+ if (*lineptr == NULL || *n == 0)
+ {
+ *n = 120;
+ *lineptr = (char *) malloc (*n);
+ if (*lineptr == NULL)
+ return -1;
+ }
+
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (len <= 0)
+ {
+ if (__underflow (fp) == EOF)
+ return -1;
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+
+ for (;;)
+ {
+ _IO_size_t needed;
+ char *t;
+ t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
+ if (t != NULL)
+ len = (t - fp->_IO_read_ptr) + 1;
+ /* make enough space for len+1 (for final NUL) bytes. */
+ needed = cur_len + len + 1;
+ if (needed > *n)
+ {
+ if (t == NULL && needed < 2 * *n)
+ needed = 2 * *n; /* Be generous. */
+ *n = needed;
+ *lineptr = (char *) realloc (*lineptr, needed);
+ if (*lineptr == NULL)
+ return -1;
+ }
+ memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
+ fp->_IO_read_ptr += len;
+ cur_len += len;
+ if (t != NULL || __underflow (fp) == EOF)
+ break;
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+ (*lineptr)[cur_len] = '\0';
+ return cur_len;
+}
diff --git a/gnu/lib/libg++/libio/iogetline.c b/gnu/lib/libg++/libio/iogetline.c
new file mode 100644
index 00000000000..278905d135d
--- /dev/null
+++ b/gnu/lib/libg++/libio/iogetline.c
@@ -0,0 +1,74 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <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
+DEFUN(_IO_getline, (fp, buf, n, delim, extract_delim),
+ _IO_FILE *fp AND char* buf AND _IO_size_t n
+ AND int delim AND 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/iogets.c b/gnu/lib/libg++/libio/iogets.c
new file mode 100644
index 00000000000..f45d9c16e3f
--- /dev/null
+++ b/gnu/lib/libg++/libio/iogets.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <limits.h>
+
+char*
+DEFUN(_IO_gets, (buf),
+ char* buf)
+{
+ _IO_size_t count;
+ int ch = _IO_getc (_IO_stdin);
+ if (ch == EOF)
+ return NULL;
+ if (ch == '\n')
+ count = 0;
+ else
+ {
+ buf[0] = (char)ch;
+ count = _IO_getline(_IO_stdin, buf + 1, INT_MAX, '\n', 0) + 1;
+ if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN)
+ return NULL;
+ }
+ buf[count] = 0;
+ return buf;
+}
diff --git a/gnu/lib/libg++/libio/ioignore.c b/gnu/lib/libg++/libio/ioignore.c
new file mode 100644
index 00000000000..a7c2f286755
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioignore.c
@@ -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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+int
+DEFUN(_IO_ignore, (fp, n),
+ register _IO_FILE *fp AND _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/iolibio.h b/gnu/lib/libg++/libio/iolibio.h
new file mode 100644
index 00000000000..e5de77ea85c
--- /dev/null
+++ b/gnu/lib/libg++/libio/iolibio.h
@@ -0,0 +1,53 @@
+#include "libio.h"
+
+/* These emulate stdio functionality, but with a different name
+ (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int _IO_fclose __P((_IO_FILE*));
+extern _IO_FILE *_IO_fdopen __P((int, const char*));
+extern int _IO_fflush __P((_IO_FILE*));
+extern int _IO_fgetpos __P((_IO_FILE*, _IO_fpos_t*));
+extern char* _IO_fgets __P((char*, int, _IO_FILE*));
+extern _IO_FILE *_IO_fopen __P((const char*, const char*));
+extern int _IO_fprintf __P((_IO_FILE*, const char*, ...));
+extern int _IO_fputs __P((const char*, _IO_FILE*));
+extern int _IO_fsetpos __P((_IO_FILE*, const _IO_fpos_t *));
+extern long int _IO_ftell __P((_IO_FILE*));
+extern _IO_size_t _IO_fread __P((void*, _IO_size_t, _IO_size_t, _IO_FILE*));
+extern _IO_size_t _IO_fwrite __P((const void*,
+ _IO_size_t, _IO_size_t, _IO_FILE*));
+extern char* _IO_gets __P((char*));
+extern void _IO_perror __P((const char*));
+extern int _IO_printf __P((const char*, ...));
+extern int _IO_puts __P((const char*));
+extern int _IO_scanf __P((const char*, ...));
+extern void _IO_setbuffer __P((_IO_FILE *, char*, _IO_size_t));
+extern int _IO_setvbuf __P((_IO_FILE*, char*, int, _IO_size_t));
+extern int _IO_sscanf __P((const char*, const char*, ...));
+extern int _IO_sprintf __P((char *, const char*, ...));
+extern int _IO_ungetc __P((int, _IO_FILE*));
+extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list));
+extern int _IO_vsprintf __P((char*, const char*, _IO_va_list));
+#ifndef _IO_pos_BAD
+#define _IO_pos_BAD ((_IO_fpos_t)(-1))
+#endif
+#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
+#define _IO_fseek(__fp, __offset, __whence) \
+ (_IO_seekoff(__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD ? EOF : 0)
+#define _IO_rewind(FILE) (void)_IO_seekoff(FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT)
+#define _IO_vprintf(FORMAT, ARGS) _IO_vfprintf(_IO_stdout, FORMAT, ARGS)
+#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)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gnu/lib/libg++/libio/iomanip.cc b/gnu/lib/libg++/libio/iomanip.cc
new file mode 100644
index 00000000000..fddba55a2b9
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include "iomanip.h"
+
+
+// Those functions are called through a pointer,
+// thus it does not make sense, to inline them.
+
+ios & __iomanip_setbase (ios& i, int n)
+{
+ ios::fmtflags b;
+ switch (n)
+ {
+ case 8:
+ b = ios::oct; break;
+ case 10:
+ b = ios::dec; break;
+ case 16:
+ b = ios::hex; break;
+ default:
+ b = 0;
+ }
+ i.setf(b, ios::basefield);
+ return i;
+}
+
+ios & __iomanip_setfill (ios& i, int n)
+{
+ //FIXME if ( i.flags() & ios::widechar )
+ i.fill( (char) n);
+ //FIXME else
+ //FIXME i.fill( (wchar) n);
+ return i;
+}
+
+ios & __iomanip_setprecision (ios& i, int n)
+{
+ i.precision(n);
+ return i;
+}
+ios & __iomanip_setw (ios& i, int n)
+{
+ i.width(n);
+ return i;
+}
+
+ios & __iomanip_setiosflags (ios& i, ios::fmtflags n)
+{
+ i.setf(n,n);
+ return i;
+}
+
+ios & __iomanip_resetiosflags (ios& i, ios::fmtflags n)
+{
+ i.setf(0,n);
+ return i;
+}
+
+template class smanip<int>;
+template class smanip<ios::fmtflags>;
+template istream& operator>>(istream&, const smanip<int>&);
+template istream& operator>>(istream&, const smanip<ios::fmtflags>&);
+template ostream& operator<<(ostream&, const smanip<int>&);
+template ostream& operator<<(ostream&, const smanip<ios::fmtflags>&);
diff --git a/gnu/lib/libg++/libio/iomanip.h b/gnu/lib/libg++/libio/iomanip.h
new file mode 100644
index 00000000000..fe1156569b4
--- /dev/null
+++ b/gnu/lib/libg++/libio/iomanip.h
@@ -0,0 +1,165 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _IOMANIP_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _IOMANIP_H
+
+#include <iostream.h>
+
+extern "C++" {
+//-----------------------------------------------------------------------------
+// Parametrized Manipulators as specified by ANSI draft
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class smanip; // TP = Type Param
+
+template<class TP> class sapp {
+ ios& (*_f)(ios&, TP);
+public:
+ sapp(ios& (*f)(ios&, TP)) : _f(f) {}
+ //
+ smanip<TP> operator()(TP a)
+ { return smanip<TP>(_f, a); }
+};
+
+template <class TP> 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);
+};
+
+template <class TP>
+inline istream& operator>>(istream& i, const imanip<TP>& m)
+{ return (*m._f)( i, m._a); }
+
+//-----------------------------------------------------------------------------
+// Output-Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class omanip;
+
+template<class TP> class oapp {
+ ostream& (*_f)(ostream&, TP);
+public:
+ oapp(ostream& (*f)(ostream&,TP)) : _f(f) {}
+ //
+ omanip<TP> operator()(TP a)
+ { return omanip<TP>(_f, a); }
+};
+
+template <class TP> class omanip {
+ ostream& (*_f)(ostream&, TP);
+ TP _a;
+public:
+ omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ ostream& operator<<(ostream& o, const omanip<TP>& m);
+};
+
+template <class TP>
+inline ostream& operator<<(ostream& o, const omanip<TP>& m)
+{ return (*m._f)(o, m._a); }
+
+//-----------------------------------------------------------------------------
+// Available Manipulators
+//-----------------------------------------------------------------------------
+
+//
+// Macro to define an iomanip function, with one argument
+// The underlying function is `__iomanip_<name>'
+//
+#define __DEFINE_IOMANIP_FN1(type,param,function) \
+ extern ios& __iomanip_##function (ios&, param); \
+ inline type<param> function (param n) \
+ { return type<param> (__iomanip_##function, n); }
+
+__DEFINE_IOMANIP_FN1( smanip, int, setbase)
+__DEFINE_IOMANIP_FN1( smanip, int, setfill)
+__DEFINE_IOMANIP_FN1( smanip, int, setprecision)
+__DEFINE_IOMANIP_FN1( smanip, int, setw)
+
+__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, resetiosflags)
+__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, setiosflags)
+} // extern "C++"
+
+#endif /*!_IOMANIP_H*/
diff --git a/gnu/lib/libg++/libio/iopadn.c b/gnu/lib/libg++/libio/iopadn.c
new file mode 100644
index 00000000000..0e502b712c3
--- /dev/null
+++ b/gnu/lib/libg++/libio/iopadn.c
@@ -0,0 +1,65 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#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
+DEFUN(_IO_padn, (fp, pad, count),
+ _IO_FILE *fp AND int pad AND _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/ioperror.c b/gnu/lib/libg++/libio/ioperror.c
new file mode 100644
index 00000000000..55d822b63a6
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioperror.c
@@ -0,0 +1,22 @@
+#include "libioP.h"
+#include <errno.h>
+#include <string.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifndef _IO_strerror
+extern char* _IO_strerror __P((int));
+#endif
+
+void
+DEFUN(_IO_perror, (s),
+ const char *s)
+{
+ char *error = _IO_strerror (errno);
+
+ if (s != NULL && *s != '\0')
+ _IO_fprintf (_IO_stderr, "%s:", s);
+
+ _IO_fprintf (_IO_stderr, "%s\n", error ? error : "");
+}
diff --git a/gnu/lib/libg++/libio/iopopen.c b/gnu/lib/libg++/libio/iopopen.c
new file mode 100644
index 00000000000..d2030028d1f
--- /dev/null
+++ b/gnu/lib/libg++/libio/iopopen.c
@@ -0,0 +1,222 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* written by Per Bothner (bothner@cygnus.com) */
+
+#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/types.h>
+#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 *
+DEFUN(_IO_proc_open, (fp, command, mode),
+ _IO_FILE* fp AND const char *command AND 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 *
+DEFUN(_IO_popen, (command, mode),
+ const char *command AND 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);
+ _IO_JUMPS(fp) = &_IO_proc_jumps;
+ _IO_file_init(fp);
+#if !_IO_UNIFIED_JUMPTABLES
+ ((struct _IO_FILE_plus*)fp)->vtable = NULL;
+#endif
+ if (_IO_proc_open (fp, command, mode) != NULL)
+ return fp;
+ free (fpx);
+ return NULL;
+}
+
+int
+DEFUN(_IO_proc_close, (fp),
+ _IO_FILE *fp)
+{
+ /* This is not name-space clean. FIXME! */
+#if _IO_HAVE_SYS_WAIT
+ int wstatus;
+ _IO_proc_file **ptr = &proc_file_chain;
+ _IO_pid_t wait_pid;
+ int status = -1;
+
+ /* Unlink from proc_file_chain. */
+ for ( ; *ptr != NULL; ptr = &(*ptr)->next)
+ {
+ if (*ptr == (_IO_proc_file*)fp)
+ {
+ *ptr = (*ptr)->next;
+ status = 0;
+ break;
+ }
+ }
+
+ if (status < 0 || _IO_close(_IO_fileno(fp)) < 0)
+ return -1;
+ /* POSIX.2 Rationale: "Some historical implementations either block
+ or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting
+ for the child process to terminate. Since this behavior is not
+ described in POSIX.2, such implementations are not conforming." */
+ do
+ {
+ wait_pid = _IO_waitpid (((_IO_proc_file*)fp)->pid, &wstatus, 0);
+ } while (wait_pid == -1 && errno == EINTR);
+ if (wait_pid == -1)
+ return -1;
+ return wstatus;
+#else /* !_IO_HAVE_SYS_WAIT */
+ return -1;
+#endif
+}
+
+struct _IO_jump_t _IO_proc_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_file_finish),
+ JUMP_INIT(overflow, _IO_file_overflow),
+ JUMP_INIT(underflow, _IO_file_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_file_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_file_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_file_setbuf),
+ JUMP_INIT(sync, _IO_file_sync),
+ JUMP_INIT(doallocate, _IO_file_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_proc_close),
+ JUMP_INIT(stat, _IO_file_stat)
+};
diff --git a/gnu/lib/libg++/libio/ioprims.c b/gnu/lib/libg++/libio/ioprims.c
new file mode 100644
index 00000000000..faa69e0feff
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioprims.c
@@ -0,0 +1,72 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* I/O OS-level primitives.
+ Needs to be replaced if not using Unix.
+ Also needs to be replaced if avoiding name-space pollution
+ (in which case read would be defined in terms of _IO_read,
+ rather than vice versa). */
+
+#include "libioP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef TODO
+/* Add open, isatty */
+#endif
+
+_IO_ssize_t
+DEFUN(_IO_read, (fildes, buf, nbyte),
+ int fildes AND void *buf AND _IO_size_t nbyte)
+{
+ return read (fildes, buf, nbyte);
+}
+
+_IO_ssize_t
+DEFUN(_IO_write, (fildes, buf, nbyte),
+ int fildes AND const void *buf AND _IO_size_t nbyte)
+{
+ return write (fildes, buf, nbyte);
+}
+
+_IO_off_t
+DEFUN(_IO_lseek, (fildes, offset, whence),
+ int fildes AND _IO_off_t offset AND int whence)
+{
+ return lseek (fildes, offset, whence);
+}
+
+int
+DEFUN(_IO_close, (fildes),
+ int fildes)
+{
+ return close (fildes);
+}
+
+int
+DEFUN(_IO_fstat, (fildes, buf),
+ int fildes AND 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 00000000000..0b99c2a6637
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_printf
+#ifdef __STDC__
+ (const char* format, ...)
+#else
+(format, va_alist) char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vfprintf(_IO_stdout, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/ioputs.c b/gnu/lib/libg++/libio/ioputs.c
new file mode 100644
index 00000000000..f0a81642853
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioputs.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <string.h>
+
+int
+DEFUN(_IO_puts, (str),
+ const char *str)
+{
+ _IO_size_t len = strlen(str);
+ if (_IO_sputn(_IO_stdout, str, len) != len)
+ return EOF;
+ if (_IO_putc('\n', _IO_stdout) == EOF)
+ return EOF;
+ return len+1;
+}
diff --git a/gnu/lib/libg++/libio/ioscanf.c b/gnu/lib/libg++/libio/ioscanf.c
new file mode 100644
index 00000000000..405d1e2eb0f
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioscanf.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_scanf
+#ifdef __STDC__
+ (const char* format, ...)
+#else
+(format, va_alist) char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vfscanf(_IO_stdin, format, args, NULL);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/ioseekoff.c b/gnu/lib/libg++/libio/ioseekoff.c
new file mode 100644
index 00000000000..06f4b9d2fe1
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioseekoff.c
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+
+_IO_pos_t
+DEFUN(_IO_seekoff, (fp, offset, dir, mode),
+ _IO_FILE* fp AND _IO_off_t offset AND int dir AND int mode)
+{
+ /* 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 _IO_SEEKOFF (fp, offset, dir, mode);
+}
diff --git a/gnu/lib/libg++/libio/ioseekpos.c b/gnu/lib/libg++/libio/ioseekpos.c
new file mode 100644
index 00000000000..1884f9df8f7
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioseekpos.c
@@ -0,0 +1,39 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+
+_IO_pos_t
+DEFUN(_IO_seekpos, (fp, pos, mode),
+ _IO_FILE* fp AND _IO_pos_t pos AND int mode)
+{
+ /* 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 _IO_SEEKPOS (fp, pos, mode);
+}
diff --git a/gnu/lib/libg++/libio/iosetbuffer.c b/gnu/lib/libg++/libio/iosetbuffer.c
new file mode 100644
index 00000000000..eb78d75d9ab
--- /dev/null
+++ b/gnu/lib/libg++/libio/iosetbuffer.c
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+void
+DEFUN(_IO_setbuffer, (fp, buf, size),
+ _IO_FILE *fp AND char *buf AND _IO_size_t size)
+{
+ CHECK_FILE(fp, );
+ fp->_flags &= ~_IO_LINE_BUF;
+ if (!buf)
+ size = 0;
+ (void) _IO_SETBUF (fp, buf, size);
+}
diff --git a/gnu/lib/libg++/libio/iosetvbuf.c b/gnu/lib/libg++/libio/iosetvbuf.c
new file mode 100644
index 00000000000..cc664b41910
--- /dev/null
+++ b/gnu/lib/libg++/libio/iosetvbuf.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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+int
+DEFUN(_IO_setvbuf, (fp, buf, mode, size),
+ _IO_FILE* fp AND char* buf AND int mode AND _IO_size_t size)
+{
+ CHECK_FILE(fp, EOF);
+ switch (mode)
+ {
+ case _IOFBF:
+ fp->_IO_file_flags &= ~_IO_LINE_BUF;
+ if (buf == NULL)
+ {
+ if (fp->_IO_buf_base == NULL)
+ {
+ /* There is no flag to distinguish between "fully buffered
+ mode has been explicitly set" as opposed to "line
+ buffering has not been explicitly set". In both
+ cases, _IO_LINE_BUF is off. If this is a tty, and
+ _IO_filedoalloc later gets called, it cannot know if
+ it should set the _IO_LINE_BUF flag (because that is
+ the default), or not (because we have explicitly asked
+ for fully buffered mode). So we make sure a buffer
+ gets allocated now, and explicitly turn off line
+ buffering.
+
+ A possibly cleaner alternative would be to add an
+ extra flag, but then flags are a finite resource. */
+ if (_IO_DOALLOCATE (fp) < 0)
+ return EOF;
+ fp->_IO_file_flags &= ~_IO_LINE_BUF;
+ }
+ return 0;
+ }
+ break;
+ case _IOLBF:
+ fp->_IO_file_flags |= _IO_LINE_BUF;
+ if (buf == NULL)
+ return 0;
+ break;
+ case _IONBF:
+ buf = NULL;
+ size = 0;
+ break;
+ default:
+ return EOF;
+ }
+ return _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
+}
diff --git a/gnu/lib/libg++/libio/iosprintf.c b/gnu/lib/libg++/libio/iosprintf.c
new file mode 100644
index 00000000000..b873eb4455d
--- /dev/null
+++ b/gnu/lib/libg++/libio/iosprintf.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_sprintf
+#ifdef __STDC__
+ (char *string, const char* format, ...)
+#else
+(string, format, va_alist) char *string; char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vsprintf(string, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/iosscanf.c b/gnu/lib/libg++/libio/iosscanf.c
new file mode 100644
index 00000000000..58868778c48
--- /dev/null
+++ b/gnu/lib/libg++/libio/iosscanf.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_sscanf
+#ifdef __STDC__
+ (const char * string, const char* format, ...)
+#else
+(string, format, va_alist) char *string; char *format; va_dcl
+#endif
+{
+ int ret;
+ va_list args;
+ _IO_va_start(args, format);
+ ret = _IO_vsscanf(string, format, args);
+ va_end(args);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/iostdio.h b/gnu/lib/libg++/libio/iostdio.h
new file mode 100644
index 00000000000..8f90d9eedfe
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostdio.h
@@ -0,0 +1,110 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* This file defines a stdio-like environment, except that it avoid
+ link-time name clashes with an existing stdio.
+ It allows for testing the libio using stdio-using programs
+ with an incompatible libc.a.
+ It is not predantically correct - e.g. some macros are used
+ that may evaluate a stream argument more than once. */
+
+#ifndef _IOSTDIO_H
+#define _IOSTDIO_H
+
+#include "iolibio.h"
+
+typedef _IO_FILE FILE;
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+/* #define size_t, fpos_t L_tmpname TMP_MAX */
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define stdin _IO_stdin
+#define stdout _IO_stdout
+#define stderr _IO_stderr
+
+#define getc(_fp) _IO_getc(_fp)
+#define putc(_ch, _fp) _IO_putc(_ch, _fp)
+
+#define clearerr _IO_clearerr
+#define fclose _IO_fclose
+#define feof _IO_feof
+#define ferror _IO_ferror
+#define fflush _IO_fflush
+#define fgetc(__fp) _IO_getc(_fp)
+#define fgetpos _IO_fgetpos
+#define fgets _IO_fgets
+#define fopen _IO_fopen
+#define fprintf _IO_fprintf
+#define fputc(_ch, _fp) _IO_putc(_ch, _fp)
+#define fputs _IO_fputs
+#define fread _IO_fread
+#define freopen _IO_freopen
+#define fscanf _IO_fscanf
+#define fseek _IO_fseek
+#define fsetpos _IO_fsetpos
+#define ftell _IO_ftell
+#define fwrite _IO_fwrite
+#define gets _IO_gets
+#define perror _IO_perror
+#define printf _IO_printf
+#define puts _IO_puts
+#define remove ??? __P((const char*))
+#define rename ??? __P((const char* _old, const char* _new))
+#define rewind _IO_rewind
+#define scanf _IO_scanf
+#define setbuf _IO_setbuf
+#define setbuffer _IO_setbuffer
+#define setvbuf _IO_setvbuf
+#define sprintf _IO_sprintf
+#define sscanf _IO_sscanf
+#define tmpfile ??? __P((void))
+#define tmpnam ??? __P((char*))
+#define ungetc _IO_ungetc
+#define vfprintf _IO_vfprintf
+#define vprintf(__fmt, __args) vfprintf(stdout, __fmt, __args)
+#define vsprintf _IO_vsprintf
+
+#if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)
+#define fdopen _IO_fdopen
+#define fileno _IO_fileno
+#define popen _IO_popen
+#define pclose _IO_pclose
+#define setbuf _IO_setbuf
+#define setlinebuf _IO_setlinebuf
+#endif
+
+#endif /* _IOSTDIO_H */
diff --git a/gnu/lib/libg++/libio/iostream.cc b/gnu/lib/libg++/libio/iostream.cc
new file mode 100644
index 00000000000..3bdfd59a054
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostream.cc
@@ -0,0 +1,821 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __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);
+ _gcount = 0;
+}
+
+int skip_ws(streambuf* sb)
+{
+ int ch;
+ for (;;) {
+ ch = sb->sbumpc();
+ if (ch == EOF || !isspace(ch))
+ return ch;
+ }
+}
+
+istream& istream::get(char& c)
+{
+ if (ipfx1()) {
+ int ch = _strbuf->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ _gcount = 0;
+ }
+ else {
+ c = (char)ch;
+ _gcount = 1;
+ }
+ }
+ else
+ _gcount = 0;
+ return *this;
+}
+
+int istream::peek()
+{
+ if (!good())
+ return EOF;
+ if (_tie && rdbuf()->in_avail() == 0)
+ _tie->flush();
+ int ch = _strbuf->sgetc();
+ if (ch == EOF)
+ set(ios::eofbit);
+ return ch;
+}
+
+istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
+{
+ _gcount = 0;
+ if (ipfx1()) {
+ register streambuf* sb = _strbuf;
+ if (delim == EOF) {
+ _gcount = sb->ignore(n);
+ return *this;
+ }
+ for (;;) {
+#if 0
+ if (n != MAXINT) // FIXME
+#endif
+ if (--n < 0)
+ break;
+ int ch = sb->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ break;
+ }
+ _gcount++;
+ if (ch == delim)
+ break;
+ }
+ }
+ return *this;
+}
+
+istream& istream::read(char *s, streamsize n)
+{
+ if (ipfx1()) {
+ _gcount = _strbuf->sgetn(s, n);
+ if (_gcount != n)
+ set(ios::failbit|ios::eofbit);
+ }
+ else
+ _gcount = 0;
+ return *this;
+}
+
+int
+istream::sync ()
+{
+ streambuf *sb = rdbuf ();
+ if (sb == NULL)
+ return EOF;
+ if (sb->sync ()) // Later: pubsync
+ {
+ setstate (ios::badbit);
+ return EOF;
+ }
+ else
+ return 0;
+}
+
+istream& istream::seekg(streampos pos)
+{
+ pos = _strbuf->pubseekpos(pos, ios::in);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+istream& istream::seekg(streamoff off, _seek_dir dir)
+{
+ streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos istream::tellg()
+{
+#if 0
+ streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in);
+#else
+ streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT);
+#endif
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+istream& istream::operator>>(char& c)
+{
+ if (ipfx0()) {
+ int ch = _strbuf->sbumpc();
+ if (ch == EOF)
+ set(ios::eofbit|ios::failbit);
+ else
+ c = (char)ch;
+ }
+ return *this;
+}
+
+istream&
+istream::operator>> (char* ptr)
+{
+ register char *p = ptr;
+ int w = width(0);
+ if (ipfx0())
+ {
+ register streambuf* sb = _strbuf;
+ for (;;)
+ {
+ int ch = sb->sbumpc();
+ if (ch == EOF)
+ {
+ set(ios::eofbit);
+ break;
+ }
+ else if (isspace(ch) || w == 1)
+ {
+ sb->sputbackc(ch);
+ break;
+ }
+ else *p++ = ch;
+ w--;
+ }
+ if (p == ptr)
+ set(ios::failbit);
+ }
+ *p = '\0';
+ return *this;
+}
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define LONGEST long long
+#else
+#define LONGEST long
+#endif
+
+static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
+{
+ if (!stream.ipfx0())
+ return 0;
+ register streambuf* sb = stream.rdbuf();
+ int base = 10;
+ int ndigits = 0;
+ register int ch = skip_ws(sb);
+ if (ch == EOF)
+ goto eof_fail;
+ neg = 0;
+ if (ch == '+') {
+ ch = skip_ws(sb);
+ }
+ else if (ch == '-') {
+ neg = 1;
+ ch = skip_ws(sb);
+ }
+ if (ch == EOF) goto eof_fail;
+ if (!(stream.flags() & ios::basefield)) {
+ if (ch == '0') {
+ ch = sb->sbumpc();
+ if (ch == EOF) {
+ val = 0;
+ return 1;
+ }
+ if (ch == 'x' || ch == 'X') {
+ base = 16;
+ ch = sb->sbumpc();
+ if (ch == EOF) goto eof_fail;
+ }
+ else {
+ sb->sputbackc(ch);
+ base = 8;
+ ch = '0';
+ }
+ }
+ }
+ else if ((stream.flags() & ios::basefield) == ios::hex)
+ base = 16;
+ else if ((stream.flags() & ios::basefield) == ios::oct)
+ base = 8;
+ val = 0;
+ for (;;) {
+ if (ch == EOF)
+ break;
+ int digit;
+ if (ch >= '0' && ch <= '9')
+ digit = ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ digit = ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ digit = ch - 'a' + 10;
+ else
+ digit = 999;
+ if (digit >= base) {
+ sb->sputbackc(ch);
+ if (ndigits == 0)
+ goto fail;
+ else
+ return 1;
+ }
+ ndigits++;
+ val = base * val + digit;
+ ch = sb->sbumpc();
+ }
+ return 1;
+ fail:
+ stream.set(ios::failbit);
+ return 0;
+ eof_fail:
+ stream.set(ios::failbit|ios::eofbit);
+ return 0;
+}
+
+#define READ_INT(TYPE) \
+istream& istream::operator>>(TYPE& i)\
+{\
+ unsigned LONGEST val; int neg;\
+ if (read_int(*this, val, neg)) {\
+ if (neg) val = -val;\
+ i = (TYPE)val;\
+ }\
+ return *this;\
+}
+
+READ_INT(short)
+READ_INT(unsigned short)
+READ_INT(int)
+READ_INT(unsigned int)
+READ_INT(long)
+READ_INT(unsigned long)
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+READ_INT(long long)
+READ_INT(unsigned long long)
+#endif
+#if _G_HAVE_BOOL
+READ_INT(bool)
+#endif
+
+istream& istream::operator>>(long double& x)
+{
+ if (ipfx0())
+ scan("%lg", &x);
+ return *this;
+}
+
+istream& istream::operator>>(double& x)
+{
+ if (ipfx0())
+ scan("%lg", &x);
+ return *this;
+}
+
+istream& istream::operator>>(float& x)
+{
+ if (ipfx0())
+ scan("%g", &x);
+ return *this;
+}
+
+istream& istream::operator>>(register streambuf* sbuf)
+{
+ if (ipfx0()) {
+ register streambuf* inbuf = rdbuf();
+ // FIXME: Should optimize!
+ for (;;) {
+ register int ch = inbuf->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit);
+ break;
+ }
+ if (sbuf->sputc(ch) == EOF) {
+ set(ios::failbit);
+ break;
+ }
+ }
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(char c)
+{
+ if (opfx()) {
+#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 _IO_USE_DTOA
+ if (_IO_outfloat(n, rdbuf(), format_char, width(0),
+ prec, flags(),
+ flags() & ios::showpos ? '+' : 0,
+ fill()) < 0)
+ set(ios::badbit|ios::failbit); // ??
+#else
+ int fpprec = 0; // 'Extra' (suppressed) floating precision.
+ if (prec > MAXFRACT) {
+ if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
+ fpprec = prec - MAXFRACT;
+ prec = MAXFRACT;
+ }
+ int negative;
+ char buf[BUF];
+ int sign = '\0';
+ char *cp = buf;
+ *cp = 0;
+ int size = __cvt_double(n, prec,
+ flags() & ios::showpoint ? 0x80 : 0,
+ &negative,
+ format_char, cp, buf + sizeof(buf));
+ if (negative) sign = '-';
+ else if (flags() & ios::showpos) sign = '+';
+ if (*cp == 0)
+ cp++;
+
+ // Calculate padding.
+ int fieldsize = size + fpprec;
+ if (sign) fieldsize++;
+ int padding = 0;
+ int w = width(0);
+ if (fieldsize < w)
+ padding = w - fieldsize;
+
+ // Do actual output.
+ register streambuf* sbuf = rdbuf();
+ register i;
+ char fill_char = fill();
+ ios::fmtflags pad_kind =
+ flags() & (ios::left|ios::right|ios::internal);
+ if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
+ && pad_kind != (ios::fmtflags)ios::internal)
+ for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+ if (sign)
+ sbuf->sputc(sign);
+ if (pad_kind == (ios::fmtflags)ios::internal)
+ for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+
+ // Emit the actual concented field, followed by extra zeros.
+ _IO_sputn (sbuf, cp, size);
+ for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
+
+ if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
+ for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+#endif
+ osfx();
+ }
+ 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);
+}
+
+ostream& ostream::seekp(streampos pos)
+{
+ pos = _strbuf->pubseekpos(pos, ios::out);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+ostream& ostream::seekp(streamoff off, _seek_dir dir)
+{
+ streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos ostream::tellp()
+{
+#if 1
+ streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
+#else
+ streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
+#endif
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+ostream& ostream::flush()
+{
+ if (_strbuf->sync())
+ set(ios::badbit);
+ return *this;
+}
+
+ostream& flush(ostream& outs)
+{
+ return outs.flush();
+}
+
+istream& ws(istream& ins)
+{
+ if (ins.ipfx1()) {
+ 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, streamsize 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);
+}
+
+// NOTE: extension for compatibility with old libg++.
+// Not really compatible with fistream::close().
+#ifdef _STREAM_COMPAT
+void ios::close()
+{
+ if (_strbuf->_flags & _IO_IS_FILEBUF)
+ ((struct filebuf*)rdbuf())->close();
+ else if (_strbuf != NULL)
+ rdbuf()->sync();
+ _strbuf = NULL;
+ _state = badbit;
+}
+
+int istream::skip(int i)
+{
+ int old = (_flags & ios::skipws) != 0;
+ if (i)
+ _flags |= ios::skipws;
+ else
+ _flags &= ~ios::skipws;
+ return old;
+}
+#endif
diff --git a/gnu/lib/libg++/libio/iostream.h b/gnu/lib/libg++/libio/iostream.h
new file mode 100644
index 00000000000..fc3aaa84dd6
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostream.h
@@ -0,0 +1,248 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _IOSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _IOSTREAM_H
+
+#include <streambuf.h>
+
+extern "C++" {
+class istream; class ostream;
+typedef ios& (*__manip)(ios&);
+typedef istream& (*__imanip)(istream&);
+typedef ostream& (*__omanip)(ostream&);
+
+extern istream& ws(istream& ins);
+extern ostream& flush(ostream& outs);
+extern ostream& endl(ostream& outs);
+extern ostream& ends(ostream& outs);
+
+class ostream : virtual public ios
+{
+ // NOTE: If fields are changed, you must fix _fake_ostream in stdstreams.C!
+ void do_osfx();
+ public:
+ ostream() { }
+ ostream(streambuf* sb, ostream* tied=NULL);
+ int opfx() {
+ if (!good()) return 0; else { if (_tie) _tie->flush(); 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, streamsize n);
+ ostream& write(const unsigned char *s, streamsize n)
+ { return write((const char*)s, n);}
+ ostream& write(const signed char *s, streamsize n)
+ { return write((const char*)s, n);}
+ ostream& write(const void *s, streamsize n)
+ { return write((const char*)s, n);}
+ ostream& seekp(streampos);
+ ostream& seekp(streamoff, _seek_dir);
+ streampos tellp();
+ ostream& form(const char *format ...);
+ ostream& vform(const char *format, _IO_va_list args);
+
+ ostream& operator<<(char c);
+ ostream& operator<<(unsigned char c) { return (*this) << (char)c; }
+ ostream& operator<<(signed char c) { return (*this) << (char)c; }
+ ostream& operator<<(const char *s);
+ ostream& operator<<(const unsigned char *s)
+ { return (*this) << (const char*)s; }
+ ostream& operator<<(const signed char *s)
+ { return (*this) << (const char*)s; }
+ ostream& operator<<(const void *p);
+ ostream& operator<<(int n);
+ ostream& operator<<(unsigned int n);
+ ostream& operator<<(long n);
+ ostream& operator<<(unsigned long n);
+#if defined(__GNUC__) && !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<<(long double 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!
+protected:
+ _IO_size_t _gcount;
+
+ int _skip_ws();
+ public:
+ istream() { _gcount = 0; }
+ istream(streambuf* sb, ostream*tied=NULL);
+ istream& get(char* ptr, int len, char delim = '\n');
+ istream& get(unsigned char* ptr, int len, char delim = '\n')
+ { return get((char*)ptr, len, delim); }
+ istream& get(char& c);
+ istream& get(unsigned char& c) { return get((char&)c); }
+ istream& getline(char* ptr, int len, char delim = '\n');
+ istream& getline(unsigned char* ptr, int len, char delim = '\n')
+ { return getline((char*)ptr, len, delim); }
+ istream& get(signed char& c) { return get((char&)c); }
+ istream& get(signed char* ptr, int len, char delim = '\n')
+ { return get((char*)ptr, len, delim); }
+ istream& getline(signed char* ptr, int len, char delim = '\n')
+ { return getline((char*)ptr, len, delim); }
+ istream& read(char *ptr, streamsize n);
+ istream& read(unsigned char *ptr, streamsize n)
+ { return read((char*)ptr, n); }
+ istream& read(signed char *ptr, streamsize n)
+ { return read((char*)ptr, n); }
+ istream& read(void *ptr, streamsize n)
+ { return read((char*)ptr, n); }
+ istream& get(streambuf& sb, char delim = '\n');
+ istream& gets(char **s, char delim = '\n');
+ int ipfx(int need = 0) {
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ 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);
+ int sync ();
+ istream& seekg(streampos);
+ istream& seekg(streamoff, _seek_dir);
+ streampos tellg();
+ istream& putback(char ch) {
+ if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::badbit);
+ return *this;}
+ istream& unget() {
+ if (good() && _strbuf->sungetc() == EOF) clear(ios::badbit);
+ return *this;}
+ istream& scan(const char *format ...);
+ istream& vscan(const char *format, _IO_va_list args);
+#ifdef _STREAM_COMPAT
+ istream& unget(char ch) { return putback(ch); }
+ int skip(int i);
+ streambuf* istreambuf() const { return _strbuf; }
+#endif
+
+ istream& operator>>(char*);
+ istream& operator>>(unsigned char* p) { return operator>>((char*)p); }
+ istream& operator>>(signed char*p) { return operator>>((char*)p); }
+ istream& operator>>(char& c);
+ istream& operator>>(unsigned char& c) {return operator>>((char&)c);}
+ istream& operator>>(signed char& c) {return operator>>((char&)c);}
+ istream& operator>>(int&);
+ istream& operator>>(long&);
+#if defined(__GNUC__) && !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>>(long double&);
+ istream& operator>>( __manip func) {(*func)(*this); return *this;}
+ istream& operator>>(__imanip func) { return (*func)(*this); }
+ istream& operator>>(streambuf*);
+};
+
+class iostream : public istream, public ostream
+{
+ public:
+ iostream() { }
+ iostream(streambuf* sb, ostream*tied=NULL);
+};
+
+class _IO_istream_withassign : public istream {
+public:
+ _IO_istream_withassign& operator=(istream&);
+};
+
+class _IO_ostream_withassign : public ostream {
+public:
+ _IO_ostream_withassign& operator=(ostream&);
+};
+
+extern _IO_istream_withassign cin;
+// clog->rdbuf() == cerr->rdbuf()
+extern _IO_ostream_withassign cout, cerr, clog;
+
+struct Iostream_init { } ; // Compatibility hack for AT&T library.
+
+inline ios& dec(ios& i)
+{ i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; }
+inline ios& hex(ios& i)
+{ i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; }
+inline ios& oct(ios& i)
+{ i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; }
+} // extern "C++"
+
+#endif /*!_IOSTREAM_H*/
diff --git a/gnu/lib/libg++/libio/iostreamP.h b/gnu/lib/libg++/libio/iostreamP.h
new file mode 100644
index 00000000000..c9c40cb6ba9
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostreamP.h
@@ -0,0 +1,26 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "streambuf.h"
+#include "libioP.h"
diff --git a/gnu/lib/libg++/libio/iostrerror.c b/gnu/lib/libg++/libio/iostrerror.c
new file mode 100644
index 00000000000..65aa25d5e4e
--- /dev/null
+++ b/gnu/lib/libg++/libio/iostrerror.c
@@ -0,0 +1,12 @@
+/* This should be replaced by whatever namespace-clean
+ version of strerror you have available. */
+
+#include "libioP.h"
+extern char *strerror __P ((int));
+
+char *
+DEFUN(_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 00000000000..033f652a067
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioungetc.c
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+int
+DEFUN(_IO_ungetc, (c, fp),
+ int c AND _IO_FILE *fp)
+{
+ CHECK_FILE(fp, EOF);
+ 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 00000000000..c6ba7957d71
--- /dev/null
+++ b/gnu/lib/libg++/libio/iovfprintf.c
@@ -0,0 +1,881 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Actual printf innards.
+ *
+ * This code is large and complicated...
+ */
+
+#include <sys/types.h>
+#include "libioP.h"
+#include <string.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/*
+ * 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
+DEFUN(_IO_helper_overflow, (fp, c),
+ _IO_FILE *fp AND int c)
+{
+ _IO_FILE *target = ((struct helper_file*)fp)->_put_stream;
+ int used = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (used)
+ {
+ _IO_sputn(target, fp->_IO_write_base, used);
+ fp->_IO_write_ptr -= used;
+ }
+ return _IO_putc (c, fp);
+}
+
+static struct _IO_jump_t _IO_helper_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_default_finish),
+ JUMP_INIT(overflow, _IO_helper_overflow),
+ JUMP_INIT(underflow, _IO_default_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_default_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_default_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_default_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_default_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat)
+};
+
+static int
+DEFUN(helper_vfprintf, (fp, fmt0, ap),
+ register _IO_FILE* fp AND char const *fmt0 AND _IO_va_list ap)
+{
+ char buf[_IO_BUFSIZ];
+ struct helper_file helper;
+ register _IO_FILE *hp = (_IO_FILE*)&helper;
+ int result, to_flush;
+
+ /* initialize helper */
+ helper._put_stream = fp;
+ hp->_IO_write_base = buf;
+ hp->_IO_write_ptr = buf;
+ hp->_IO_write_end = buf+_IO_BUFSIZ;
+ hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS;
+ _IO_JUMPS(hp) = &_IO_helper_jumps;
+
+ /* Now print to helper instead. */
+ result = _IO_vfprintf(hp, fmt0, ap);
+
+ /* Now flush anything from the helper to the fp. */
+ if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0)
+ {
+ if (_IO_sputn(fp, hp->_IO_write_base, to_flush) != to_flush)
+ return EOF;
+ }
+ return result;
+}
+
+#ifdef FLOATING_POINT
+
+#include "floatio.h"
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+#define DEFPREC 6
+extern double modf __P((double, double*));
+
+#else /* no FLOATING_POINT */
+
+#define BUF 40
+
+#endif /* FLOATING_POINT */
+
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) ((n) + '0')
+
+/*
+ * Flags used during conversion.
+ */
+#define LONGINT 0x01 /* long integer */
+#define LONGDBL 0x02 /* long double; unimplemented */
+#define SHORTINT 0x04 /* short integer */
+#define ALT 0x08 /* alternate form */
+#define LADJUST 0x10 /* left adjustment */
+#define ZEROPAD 0x20 /* zero (as opposed to blank) pad */
+#define HEXPREFIX 0x40 /* add 0x or 0X prefix */
+
+int
+DEFUN(_IO_vfprintf, (fp, fmt0, ap),
+ register _IO_FILE* fp AND char const *fmt0 AND _IO_va_list ap)
+{
+ register const char *fmt; /* format string */
+ register int ch; /* character from fmt */
+ register int n; /* handy integer (short term usage) */
+ register char *cp; /* handy char pointer (short term usage) */
+ const char *fmark; /* for remembering a place in fmt */
+ register int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format (%.3d), or -1 */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+#ifdef FLOATING_POINT
+ int softsign; /* temporary negative sign for floats */
+ double _double; /* double precision arguments %[eEfgG] */
+#ifndef _IO_USE_DTOA
+ int fpprec; /* `extra' floating precision in [eEfgG] */
+#endif
+#endif
+ unsigned long _ulong; /* integer arguments %[diouxX] */
+ enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int dpad; /* extra 0 padding needed for integers */
+ int fieldsz; /* field size expanded by sign, dpad etc */
+ /* The initialization of 'size' is to suppress a warning that
+ 'size' might be used unitialized. It seems gcc can't
+ quite grok this spaghetti code ... */
+ int size = 0; /* size of converted field or string */
+ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
+ char ox[2]; /* space for 0x hex-prefix */
+
+ /*
+ * BEWARE, these `goto error' on error, and PAD uses `n'.
+ */
+#define PRINT(ptr, len) \
+ do { if (_IO_sputn(fp,ptr, len) != len) goto error; } while (0)
+#define PAD_SP(howmany) if (_IO_padn(fp, ' ', howmany) < (howmany)) goto error;
+#define PAD_0(howmany) if (_IO_padn(fp, '0', howmany) < (howmany)) goto error;
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ (flags&LONGINT ? va_arg(ap, long) : \
+ flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+ (long)va_arg(ap, int))
+#define UARG() \
+ (flags&LONGINT ? va_arg(ap, unsigned long) : \
+ flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
+ (unsigned long)va_arg(ap, unsigned int))
+
+ /* optimise stderr (and other unbuffered Unix files) */
+ if (fp->_IO_file_flags & _IO_UNBUFFERED)
+ return helper_vfprintf(fp, fmt0, ap);
+
+ fmt = fmt0;
+ ret = 0;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (fmark = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if ((n = fmt - fmark) != 0) {
+ PRINT(fmark, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
+ fpprec = 0;
+#endif
+ width = 0;
+ prec = -1;
+ sign = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ if ((width = va_arg(ap, int)) >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ flags &= ~ZEROPAD; /* '-' disables '0' */
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ n = va_arg(ap, int);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ }
+ prec = n < 0 ? -1 : n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ if (!(flags & LADJUST))
+ flags |= ZEROPAD; /* '-' disables '0' */
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ flags |= LONGINT;
+ goto rflag;
+ case 'c':
+ *(cp = buf) = va_arg(ap, int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ _ulong = SARG();
+ if ((long)_ulong < 0) {
+ _ulong = -_ulong;
+ sign = '-';
+ }
+ base = DEC;
+ goto number;
+#ifdef FLOATING_POINT
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ _double = va_arg(ap, double);
+#ifdef _IO_USE_DTOA
+ {
+ int fmt_flags = 0;
+ int fill = ' ';
+ if (flags & ALT)
+ fmt_flags |= _IO_SHOWPOINT;
+ if (flags & LADJUST)
+ fmt_flags |= _IO_LEFT;
+ else if (flags & ZEROPAD)
+ fmt_flags |= _IO_INTERNAL, fill = '0';
+ n = _IO_outfloat(_double, fp, ch, width,
+ prec < 0 ? DEFPREC : prec,
+ fmt_flags, sign, fill);
+ if (n < 0)
+ goto error;
+ ret += n;
+ }
+ /* CHECK ERROR! */
+ continue;
+#else
+ /*
+ * don't do unrealistic precision; just pad it with
+ * zeroes later, so buffer size stays rational.
+ */
+ if (prec > MAXFRACT) {
+ if ((ch != 'g' && ch != 'G') || (flags&ALT))
+ fpprec = prec - MAXFRACT;
+ prec = MAXFRACT;
+ } else if (prec == -1)
+ prec = DEFPREC;
+ /* __cvt_double may have to round up before the
+ "start" of its buffer, i.e.
+ ``intf("%.2f", (double)9.999);'';
+ if the first character is still NUL, it did.
+ softsign avoids negative 0 if _double < 0 but
+ no significant digits will be shown. */
+ cp = buf;
+ *cp = '\0';
+ size = __cvt_double(_double, prec, flags, &softsign,
+ ch, cp, buf + sizeof(buf));
+ if (softsign)
+ sign = '-';
+ if (*cp == '\0')
+ cp++;
+ break;
+#endif
+#endif /* FLOATING_POINT */
+ case 'n':
+ if (flags & LONGINT)
+ *va_arg(ap, long *) = ret;
+ else if (flags & SHORTINT)
+ *va_arg(ap, short *) = ret;
+ else
+ *va_arg(ap, int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ _ulong = UARG();
+ base = OCT;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ /* NOSTRICT */
+ _ulong = (unsigned long)va_arg(ap, void *);
+ base = HEX;
+ flags |= HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = va_arg(ap, char *)) == NULL)
+ cp = "(null)";
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = (char*)memchr(cp, 0, prec);
+
+ if (p != NULL) {
+ size = p - cp;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = strlen(cp);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ _ulong = UARG();
+ base = DEC;
+ goto nosign;
+ case 'X':
+ case 'x':
+ _ulong = UARG();
+ base = HEX;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT && _ulong != 0)
+ flags |= HEXPREFIX;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = buf + BUF;
+ if (_ulong != 0 || prec != 0) {
+ char *xdigs; /* digits for [xX] conversion */
+ /*
+ * unsigned mod is hard, and unsigned mod
+ * by a constant is easier than that by
+ * a variable; hence this switch.
+ */
+ switch (base) {
+ case OCT:
+ do {
+ *--cp = to_char(_ulong & 7);
+ _ulong >>= 3;
+ } while (_ulong);
+ /* handle octal leading 0 */
+ if (flags & ALT && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case DEC:
+ /* many numbers are 1 digit */
+ while (_ulong >= 10) {
+ *--cp = to_char(_ulong % 10);
+ _ulong /= 10;
+ }
+ *--cp = to_char(_ulong);
+ break;
+
+ case HEX:
+ if (ch == 'X')
+ xdigs = "0123456789ABCDEF";
+ else /* ch == 'x' || ch == 'p' */
+ xdigs = "0123456789abcdef";
+ do {
+ *--cp = xdigs[_ulong & 15];
+ _ulong >>= 4;
+ } while (_ulong);
+ break;
+
+ default:
+ cp = "bug in vform: bad base";
+ goto skipsize;
+ }
+ }
+ size = buf + BUF - cp;
+ skipsize:
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = buf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point,
+ * `cp' points to a string which (if not flags&LADJUST)
+ * should be padded out to `width' places. If
+ * flags&ZEROPAD, it should first be prefixed by any
+ * sign or other prefix; otherwise, it should be blank
+ * padded before the prefix is emitted. After any
+ * left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print
+ * the string proper, then emit zeroes required by any
+ * leftover floating precision; finally, if LADJUST,
+ * pad with blanks.
+ */
+
+ /*
+ * compute actual size, so we know how much to pad.
+ */
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
+ fieldsz = size + fpprec;
+#else
+ fieldsz = size;
+#endif
+ dpad = dprec - size;
+ if (dpad < 0)
+ dpad = 0;
+
+ if (sign)
+ fieldsz++;
+ else if (flags & HEXPREFIX)
+ fieldsz += 2;
+ fieldsz += dpad;
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD_SP(width - fieldsz);
+
+ /* prefix */
+ if (sign) {
+ PRINT(&sign, 1);
+ } else if (flags & HEXPREFIX) {
+ ox[0] = '0';
+ ox[1] = ch;
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD_0(width - fieldsz);
+
+ /* leading zeroes from decimal precision */
+ PAD_0(dpad);
+
+ /* the string or number proper */
+ PRINT(cp, size);
+
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
+ /* trailing f.p. zeroes */
+ PAD_0(fpprec);
+#endif
+
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD_SP(width - fieldsz);
+
+ /* finally, adjust ret */
+ ret += width > fieldsz ? width : fieldsz;
+
+ }
+done:
+ return ret;
+error:
+ return EOF;
+ /* NOTREACHED */
+}
+
+#if defined(FLOATING_POINT) && !defined(_IO_USE_DTOA)
+
+static char *exponent(register char *p, register int exp, int fmtch)
+{
+ register char *t;
+ char expbuf[MAXEXP];
+
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXP;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXP; *p++ = *t++);
+ }
+ else {
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return (p);
+}
+
+static char * round(double fract, int *exp,
+ register char *start, register char *end,
+ char ch, int *signp)
+{
+ double tmp;
+
+ if (fract)
+ (void)modf(fract * 10, &tmp);
+ else
+ tmp = to_digit(ch);
+ if (tmp > 4)
+ for (;; --end) {
+ if (*end == '.')
+ --end;
+ if (++*end <= '9')
+ break;
+ *end = '0';
+ if (end == start) {
+ if (exp) { /* e/E; increment exponent */
+ *end = '1';
+ ++*exp;
+ }
+ else { /* f; add extra digit */
+ *--end = '1';
+ --start;
+ }
+ break;
+ }
+ }
+ /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
+ else if (*signp == '-')
+ for (;; --end) {
+ if (*end == '.')
+ --end;
+ if (*end != '0')
+ break;
+ if (end == start)
+ *signp = 0;
+ }
+ return (start);
+}
+
+int __cvt_double(double number, register int prec, int flags, int *signp,
+ int fmtch, char *startp, char *endp)
+{
+ register char *p, *t;
+ register double fract;
+ int dotrim = 0, expcnt, gformat = 0;
+ double integer, tmp;
+
+ expcnt = 0;
+ if (number < 0) {
+ number = -number;
+ *signp = '-';
+ } else
+ *signp = 0;
+
+ fract = modf(number, &integer);
+
+ /* get an extra slot for rounding. */
+ t = ++startp;
+
+ /*
+ * get integer portion of number; put into the end of the buffer; the
+ * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
+ */
+ for (p = endp - 1; integer; ++expcnt) {
+ tmp = modf(integer / 10, &integer);
+ *p-- = to_char((int)((tmp + .01) * 10));
+ }
+ switch (fmtch) {
+ case 'f':
+ case 'F':
+ /* reverse integer into beginning of buffer */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point.
+ */
+ if (prec || flags&ALT)
+ *t++ = '.';
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, (int *)NULL, startp,
+ t - 1, (char)0, signp);
+ }
+ for (; prec--; *t++ = '0');
+ break;
+ case 'e':
+ case 'E':
+eformat: if (expcnt) {
+ *t++ = *++p;
+ if (prec || flags&ALT)
+ *t++ = '.';
+ /* if requires more precision and some integer left */
+ for (; prec && ++p < endp; --prec)
+ *t++ = *p;
+ /*
+ * if done precision and more of the integer component,
+ * round using it; adjust fract so we don't re-round
+ * later.
+ */
+ if (!prec && ++p < endp) {
+ fract = 0;
+ startp = round((double)0, &expcnt, startp,
+ t - 1, *p, signp);
+ }
+ /* adjust expcnt for digit in front of decimal */
+ --expcnt;
+ }
+ /* until first fractional digit, decrement exponent */
+ else if (fract) {
+ /* adjust expcnt for digit in front of decimal */
+ for (expcnt = -1;; --expcnt) {
+ fract = modf(fract * 10, &tmp);
+ if (tmp)
+ break;
+ }
+ *t++ = to_char((int)tmp);
+ if (prec || flags&ALT)
+ *t++ = '.';
+ }
+ else {
+ *t++ = '0';
+ if (prec || flags&ALT)
+ *t++ = '.';
+ }
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, &expcnt, startp,
+ t - 1, (char)0, signp);
+ }
+ /* if requires more precision */
+ for (; prec--; *t++ = '0');
+
+ /* unless alternate flag, trim any g/G format trailing 0's */
+ if (gformat && !(flags&ALT)) {
+ while (t > startp && *--t == '0');
+ if (*t == '.')
+ --t;
+ ++t;
+ }
+ t = exponent(t, expcnt, fmtch);
+ break;
+ case 'g':
+ case 'G':
+ /* a precision of 0 is treated as a precision of 1. */
+ if (!prec)
+ ++prec;
+ /*
+ * ``The style used depends on the value converted; style e
+ * will be used only if the exponent resulting from the
+ * conversion is less than -4 or greater than the precision.''
+ * -- ANSI X3J11
+ */
+ if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
+ /*
+ * g/G format counts "significant digits, not digits of
+ * precision; for the e/E format, this just causes an
+ * off-by-one problem, i.e. g/G considers the digit
+ * before the decimal point significant and e/E doesn't
+ * count it as precision.
+ */
+ --prec;
+ fmtch -= 2; /* G->E, g->e */
+ gformat = 1;
+ goto eformat;
+ }
+ /*
+ * reverse integer into beginning of buffer,
+ * note, decrement precision
+ */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p, --prec);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point. If no digits yet, add in leading 0.
+ */
+ if (prec || flags&ALT) {
+ dotrim = 1;
+ *t++ = '.';
+ }
+ else
+ dotrim = 0;
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec) {
+ /* If no integer part, don't count initial
+ * zeros as significant digits. */
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while(!tmp && !expcnt);
+ while (--prec && fract) {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ }
+ }
+ if (fract)
+ startp = round(fract, (int *)NULL, startp,
+ t - 1, (char)0, signp);
+ }
+ /* alternate format, adds 0's for precision, else trim 0's */
+ if (flags&ALT)
+ for (; prec--; *t++ = '0');
+ else if (dotrim) {
+ while (t > startp && *--t == '0');
+ if (*t != '.')
+ ++t;
+ }
+ }
+ return (t - startp);
+}
+
+#endif /* defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) */
diff --git a/gnu/lib/libg++/libio/iovfscanf.c b/gnu/lib/libg++/libio/iovfscanf.c
new file mode 100644
index 00000000000..1220e0750b7
--- /dev/null
+++ b/gnu/lib/libg++/libio/iovfscanf.c
@@ -0,0 +1,787 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Extensively hacked for GNU iostream by Per Bothner 1991, 1992, 1993.
+ Changes copyright Free Software Foundation 1992, 1993. */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+#include <libioP.h>
+#include <ctype.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifndef NO_FLOATING_POINT
+#define FLOATING_POINT
+#endif
+
+#ifdef FLOATING_POINT
+#include "floatio.h"
+#define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
+#else
+#define BUF 40
+#endif
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x01 /* l: long or double */
+#define LONGDBL 0x02 /* L: long double; unimplemented */
+#define SHORT 0x04 /* h: short */
+#define SUPPRESS 0x08 /* suppress assignment */
+#define POINTER 0x10 /* weird %p pointer (`fake hex') */
+#define NOSKIP 0x20 /* do not skip blanks */
+#define WIDTH 0x40 /* width */
+
+/*
+ * The following are used in numeric conversions only:
+ * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+
+#define DPTOK 0x100 /* (float) decimal point is still legal */
+#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
+
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* integer, i.e., strtol or strtoul */
+#define CT_FLOAT 4 /* floating, i.e., strtod */
+
+#define u_char unsigned char
+#define u_long unsigned long
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern u_long strtoul __P((const char*, char**, int));
+extern long strtol __P((const char*, char**, int));
+static const u_char *__sccl __P((char *tab, const u_char *fmt));
+#ifndef _IO_USE_DTOA
+extern double atof();
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* If errp != NULL, *errp|=1 if we see a premature EOF;
+ *errp|=2 if we an invalid character. */
+
+int
+DEFUN(_IO_vfscanf, (fp, fmt0, ap, errp),
+ register _IO_FILE *fp AND char const *fmt0
+ AND _IO_va_list ap AND int *errp)
+{
+ register const u_char *fmt = (const u_char *)fmt0;
+ register int c; /* character from format, or conversion */
+ register _IO_ssize_t width; /* field width, or 0 */
+ register char *p; /* points into all kinds of strings */
+ register int n; /* handy integer */
+ register int flags = 0; /* flags as defined above */
+ register char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nread; /* number of characters consumed from fp */
+ /* Assignments to base and ccfn are just to suppress warnings from gcc.*/
+ int base = 0; /* base argument to strtol/strtoul */
+ typedef u_long (*strtoulfn) __P((const char*, char**, int));
+ strtoulfn ccfn = 0;
+ /* conversion function (strtol/strtoul) */
+ char ccltab[256]; /* character class table for %[...] */
+ char buf[BUF]; /* buffer for numeric conversions */
+ int seen_eof = 0;
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ nassigned = 0;
+ nread = 0;
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ goto done;
+ if (isspace(c)) {
+ for (;;) {
+ c = _IO_getc(fp);
+ if (c == EOF) {
+ seen_eof++;
+ break;
+ }
+ if (!isspace(c)) {
+ _IO_ungetc (c, fp);
+ break;
+ }
+ nread++;
+ }
+ continue;
+ }
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+ switch (c) {
+ case '%':
+literal:
+ n = _IO_getc(fp);
+ if (n == EOF)
+ goto eof_failure;
+ if (n != c) {
+ _IO_ungetc (n, fp);
+ goto match_failure;
+ }
+ nread++;
+ continue;
+
+ case '*':
+ if (flags) goto control_failure;
+ flags = SUPPRESS;
+ goto again;
+ case 'l':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= LONG;
+ goto again;
+ case 'L':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (flags & ~(SUPPRESS | WIDTH)) goto control_failure;
+ flags |= WIDTH;
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ * Those marked `compat' are for 4.[123]BSD compatibility.
+ *
+ * (According to ANSI, E and X formats are supposed
+ * to the same as e and x. Sorry about that.)
+ */
+ case 'D': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'd':
+ c = CT_INT;
+ ccfn = (strtoulfn)strtol;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ ccfn = (strtoulfn)strtol;
+ base = 0;
+ break;
+
+ case 'O': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'o':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 10;
+ break;
+
+ case 'X':
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 16;
+ break;
+
+#ifdef FLOATING_POINT
+ case 'E': case 'F':
+ case 'e': case 'f': case 'g':
+ c = CT_FLOAT;
+ break;
+#endif
+
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ fmt = __sccl(ccltab, fmt);
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 16;
+ break;
+
+ case 'n':
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORT)
+ *va_arg(ap, short *) = nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+
+ /*
+ * Disgusting backwards compatibility hacks. XXX
+ */
+ case '\0': /* compat */
+ nassigned = EOF;
+ goto done;
+
+ default: /* compat */
+ if (isupper(c))
+ flags |= LONG;
+ c = CT_INT;
+ ccfn = (strtoulfn)strtol;
+ base = 10;
+ break;
+ }
+
+ /*
+ * We have a conversion that requires input.
+ */
+ if (_IO_peekc(fp) == EOF)
+ goto eof_failure;
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ n = (unsigned char)*fp->_IO_read_ptr;
+ while (isspace(n)) {
+ fp->_IO_read_ptr++;
+ nread++;
+ n = _IO_peekc(fp);
+ if (n == EOF)
+ goto eof_failure;
+ }
+ /* Note that there is at least one character in
+ the buffer, so conversions that do not set NOSKIP
+ can no longer result in an input failure. */
+ }
+
+ /*
+ * Do the conversion.
+ */
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0) /* FIXME! */
+ width = 1;
+ if (flags & SUPPRESS) {
+ _IO_size_t sum = 0;
+ for (;;) {
+ n = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (n < (int)width) {
+ sum += n;
+ width -= n;
+ fp->_IO_read_ptr += n;
+ if (__underflow(fp) == EOF)
+ if (sum == 0)
+ goto eof_failure;
+ else {
+ seen_eof++;
+ break;
+ }
+ } else {
+ sum += width;
+ fp->_IO_read_ptr += width;
+ break;
+ }
+ }
+ nread += sum;
+ } else {
+ _IO_size_t r =
+
+ _IO_XSGETN (fp, (char*)va_arg(ap, char*), width);
+ if (r != width)
+ goto eof_failure;
+ nread += r;
+ nassigned++;
+ }
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = ~0; /* `infinity' */
+ /* take only those things in the class */
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[(unsigned char)*fp->_IO_read_ptr]) {
+ n++, fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ if (n == 0)
+ goto eof_failure;
+ seen_eof++;
+ break;
+ }
+ }
+ if (n == 0)
+ goto match_failure;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (ccltab[(unsigned char)*fp->_IO_read_ptr]) {
+ *p++ = *fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ if (p == p0)
+ goto eof_failure;
+ seen_eof++;
+ break;
+ }
+ }
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ }
+ nread += n;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = ~0;
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace((unsigned char)*fp->_IO_read_ptr)) {
+ n++, fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break;
+ }
+ }
+ nread += n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace((unsigned char)*fp->_IO_read_ptr)) {
+ *p++ = *fp->_IO_read_ptr++;
+ if (--width == 0)
+ break;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break;
+ }
+ }
+ *p = 0;
+ nread += p - p0;
+ nassigned++;
+ }
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by strtol/strtoul */
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = (unsigned char)*fp->_IO_read_ptr;
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto ok;
+ }
+ break;
+
+ /* x ok iff flag still set & 2nd char */
+ case 'x': case 'X':
+ if (flags & PFXOK && p == buf + 1) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = c;
+ fp->_IO_read_ptr++;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break; /* EOF */
+ }
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf)
+ (void) _IO_ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ c = ((u_char *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ (void) _IO_ungetc (c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ u_long res;
+
+ *p = 0;
+ res = (*ccfn)(buf, (char **)NULL, base);
+ if (flags & POINTER)
+ *va_arg(ap, void **) = (void *)res;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = res;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = res;
+ else
+ *va_arg(ap, int *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+
+#ifdef FLOATING_POINT
+ case CT_FLOAT:
+ /* scan a floating point number as if by strtod */
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+ flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
+ for (p = buf; width; width--) {
+ c = (unsigned char)*fp->_IO_read_ptr;
+ /*
+ * This code mimicks the integer conversion
+ * code, but is much simpler.
+ */
+ switch (c) {
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ flags &= ~(SIGNOK | NDIGITS);
+ goto fok;
+
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto fok;
+ }
+ break;
+ case '.':
+ if (flags & DPTOK) {
+ flags &= ~(SIGNOK | DPTOK);
+ goto fok;
+ }
+ break;
+ case 'e': case 'E':
+ /* no exponent without some digits */
+ if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
+ flags =
+ (flags & ~(EXPOK|DPTOK)) |
+ SIGNOK | NDIGITS;
+ goto fok;
+ }
+ break;
+ }
+ break;
+ fok:
+ *p++ = c;
+ fp->_IO_read_ptr++;
+ if (_IO_peekc(fp) == EOF) {
+ seen_eof++;
+ break; /* EOF */
+ }
+ }
+ /*
+ * If no digits, might be missing exponent digits
+ * (just give back the exponent) or might be missing
+ * regular digits, but had sign and/or decimal point.
+ */
+ if (flags & NDIGITS) {
+ if (flags & EXPOK) {
+ /* no digits at all */
+ while (p > buf)
+ _IO_ungetc (*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ /* just a bad exponent (e and maybe sign) */
+ c = *(u_char *)--p;
+ if (c != 'e' && c != 'E') {
+ (void) _IO_ungetc (c, fp);/* sign */
+ c = *(u_char *)--p;
+ }
+ (void) _IO_ungetc (c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ double res;
+ *p = 0;
+#ifdef _IO_USE_DTOA
+ res = _IO_strtod(buf, NULL);
+#else
+ res = atof(buf);
+#endif
+ if (flags & LONG)
+ *va_arg(ap, double *) = res;
+ else
+ *va_arg(ap, float *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+#endif /* FLOATING_POINT */
+ }
+ }
+eof_failure:
+ seen_eof++;
+input_failure:
+ if (nassigned == 0)
+ nassigned = -1;
+control_failure:
+match_failure:
+ if (errp)
+ *errp |= 2;
+done:
+ if (errp && seen_eof)
+ *errp |= 1;
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static const u_char *
+DEFUN(__sccl, (tab, fmt),
+ register char *tab AND 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/iovsprintf.c b/gnu/lib/libg++/libio/iovsprintf.c
new file mode 100644
index 00000000000..06d926d3590
--- /dev/null
+++ b/gnu/lib/libg++/libio/iovsprintf.c
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+int
+DEFUN(_IO_vsprintf, (string, format, args),
+ char *string AND const char *format AND _IO_va_list args)
+{
+ _IO_strfile sf;
+ int ret;
+ _IO_init((_IO_FILE*)&sf, 0);
+ _IO_JUMPS((_IO_FILE*)&sf) = &_IO_str_jumps;
+ _IO_str_init_static ((_IO_FILE*)&sf, string, -1, string);
+ ret = _IO_vfprintf((_IO_FILE*)&sf, format, args);
+ _IO_putc('\0', (_IO_FILE*)&sf);
+ return ret;
+}
diff --git a/gnu/lib/libg++/libio/iovsscanf.c b/gnu/lib/libg++/libio/iovsscanf.c
new file mode 100644
index 00000000000..529778098a5
--- /dev/null
+++ b/gnu/lib/libg++/libio/iovsscanf.c
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+int
+DEFUN(_IO_vsscanf, (string, format, args),
+ const char *string AND const char *format AND _IO_va_list args)
+{
+ _IO_strfile sf;
+ _IO_init((_IO_FILE*)&sf, 0);
+ _IO_JUMPS((_IO_FILE*)&sf) = &_IO_str_jumps;
+ _IO_str_init_static ((_IO_FILE*)&sf, (char*)string, 0, NULL);
+ return _IO_vfscanf((_IO_FILE*)&sf, format, args, NULL);
+}
diff --git a/gnu/lib/libg++/libio/isgetline.cc b/gnu/lib/libg++/libio/isgetline.cc
new file mode 100644
index 00000000000..add26638b20
--- /dev/null
+++ b/gnu/lib/libg++/libio/isgetline.cc
@@ -0,0 +1,139 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libioP.h>
+#include "iostream.h"
+#include <string.h>
+
+istream& istream::getline(char* buf, int len, char delim)
+{
+ _gcount = 0;
+ if (len <= 0)
+ {
+ set(ios::failbit);
+ return *this;
+ }
+ int ch;
+ if (ipfx1())
+ {
+ streambuf *sb = rdbuf();
+ _gcount = _IO_getline(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;
+ }
+
+ ptr = new char[total+1];
+ if (ptr != NULL) {
+ ptr[total] = '\0';
+ memcpy(ptr + total - count, buf, count);
+ }
+ return ptr;
+}
+
+/* Reads an arbitrarily long input line terminated by TERMINATOR.
+ This routine allocates its own memory, so the user should
+ only supply the address of a (char *). */
+
+istream& istream::gets(char **s, char delim /* = '\n' */)
+{
+ if (ipfx1()) {
+ long size = 0;
+ streambuf *sb = rdbuf();
+ *s = _sb_readline (sb, size, delim);
+ _gcount = *s ? size : 0;
+ if (sb->_flags & _IO_EOF_SEEN) {
+ set(ios::eofbit);
+ if (_gcount == 0)
+ set(ios::failbit);
+ }
+ }
+ else {
+ _gcount = 0;
+ *s = NULL;
+ }
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/isgetsb.cc b/gnu/lib/libg++/libio/isgetsb.cc
new file mode 100644
index 00000000000..55617e649a0
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "iostream.h"
+#include <string.h>
+
+istream& istream::get(streambuf& sb, char delim /* = '\n' */)
+{
+ _gcount = 0;
+ if (ipfx1())
+ {
+ register streambuf* isb = rdbuf();
+ for (;;)
+ {
+ streamsize len = isb->_IO_read_end - isb->_IO_read_ptr;
+ if (len <= 0)
+ if (__underflow(isb) == EOF)
+ break;
+ else
+ len = isb->_IO_read_end - isb->_IO_read_ptr;
+ char *delimp = (char*)memchr((void*)isb->_IO_read_ptr, delim, len);
+ if (delimp != NULL)
+ len = delimp - isb->_IO_read_ptr;
+ int written = sb.sputn(isb->_IO_read_ptr, len);
+ isb->_IO_read_ptr += written;
+ _gcount += written;
+ if (written != len)
+ {
+ set(ios::failbit);
+ break;
+ }
+ if (delimp != NULL)
+ break;
+ }
+ }
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/isscan.cc b/gnu/lib/libg++/libio/isscan.cc
new file mode 100644
index 00000000000..64d4bc682f8
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <iostream.h>
+#include <stdarg.h>
+
+istream& istream::scan(const char *format ...)
+{
+ if (ipfx0()) {
+ va_list ap;
+ va_start(ap, format);
+ _strbuf->vscan(format, ap, this);
+ va_end(ap);
+ }
+ return *this;
+}
+
+istream& istream::vscan(const char *format, _IO_va_list args)
+{
+ if (ipfx0())
+ _strbuf->vscan(format, args, this);
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/istream.h b/gnu/lib/libg++/libio/istream.h
new file mode 100644
index 00000000000..f54ec1de9a1
--- /dev/null
+++ b/gnu/lib/libg++/libio/istream.h
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <stream.h>
diff --git a/gnu/lib/libg++/libio/libio.h b/gnu/lib/libg++/libio/libio.h
new file mode 100644
index 00000000000..7080d1359d7
--- /dev/null
+++ b/gnu/lib/libg++/libio/libio.h
@@ -0,0 +1,254 @@
+/*
+Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+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. Written by Per Bothner. */
+
+#ifndef _IO_STDIO_H
+#define _IO_STDIO_H
+
+#include <_G_config.h>
+#define _IO_pos_t _G_fpos_t /* obsolete */
+#define _IO_fpos_t _G_fpos_t
+#define _IO_size_t _G_size_t
+#define _IO_ssize_t _G_ssize_t
+#define _IO_off_t _G_off_t
+#define _IO_pid_t _G_pid_t
+#define _IO_uid_t _G_uid_t
+#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT
+#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE
+#define _IO_BUFSIZ _G_BUFSIZ
+#define _IO_va_list _G_va_list
+
+#ifdef _G_NEED_STDARG_H
+/* This define avoids name pollution if we're using GNU stdarg.h */
+#define __need___va_list
+#include <stdarg.h>
+#ifdef __GNUC_VA_LIST
+#undef _IO_va_list
+#define _IO_va_list __gnuc_va_list
+#endif /* __GNUC_VA_LIST */
+#endif
+
+#ifndef __P
+#if _G_HAVE_SYS_CDEFS
+#include <sys/cdefs.h>
+#else
+#ifdef __STDC__
+#define __P(protos) protos
+#else
+#define __P(protos) ()
+#endif
+#endif
+#endif /*!__P*/
+
+/* For backward compatibility */
+#ifndef _PARAMS
+#define _PARAMS(protos) __P(protos)
+#endif /*!_PARAMS*/
+
+#ifndef __STDC__
+#define const
+#endif
+#define _IO_USE_DTOA
+#define _IO_UNIFIED_JUMPTABLES 1
+
+#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 /* Don't call close(_fileno) on cleanup. */
+#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/
+#define _IO_IN_BACKUP 0x100
+#define _IO_LINE_BUF 0x200
+#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */
+#define _IO_CURRENTLY_PUTTING 0x800
+#define _IO_IS_APPENDING 0x1000
+#define _IO_IS_FILEBUF 0x2000
+
+/* 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;
+
+ 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));
+
+#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)))
+
+#define _IO_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
+#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+
+/* 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 _IO_fpos_t _IO_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P((_IO_FILE*, _IO_fpos_t, int));
+
+extern void _IO_free_backup_area __P((_IO_FILE*));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IO_STDIO_H */
diff --git a/gnu/lib/libg++/libio/libioP.h b/gnu/lib/libg++/libio/libioP.h
new file mode 100644
index 00000000000..1b32a59de64
--- /dev/null
+++ b/gnu/lib/libg++/libio/libioP.h
@@ -0,0 +1,481 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#include "iolibio.h"
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(__cplusplus)
+/* 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 AND ,
+#define DEFUN(name, arglist, args) name(args)
+#define DEFUN_VOID(name) name(void)
+
+#else /* Not ANSI C. */
+
+#define AND ;
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define const
+#endif
+#define DEFUN(name, arglist, args) name arglist args;
+#define DEFUN_VOID(name) name()
+#endif /* ANSI C. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _IO_seek_set 0
+#define _IO_seek_cur 1
+#define _IO_seek_end 2
+
+/* THE JUMPTABLE FUNCTIONS.
+
+ * The _IO_FILE type is used to implement the FILE type in GNU libc,
+ * as well as the streambuf class in GNU iostreams for C++.
+ * These are all the same, just used differently.
+ * An _IO_FILE (or FILE) object is allows followed by a pointer to
+ * a jump table (of pointers to functions). The pointer is accessed
+ * with the _IO_JUMPS macro. The jump table has a eccentric format,
+ * so as to be compatible with the layout of a C++ virtual function table.
+ * (as implemented by g++). When a pointer to a steambuf object is
+ * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just
+ * happens to point to the virtual function table of the streambuf.
+ * Thus the _IO_JUMPS function table used for C stdio/libio does
+ * double duty as the virtual functiuon table for C++ streambuf.
+ *
+ * The entries in the _IO_JUMPS function table (and hence also the
+ * virtual functions of a streambuf) are described below.
+ * The first parameter of each function entry is the _IO_FILE/streambuf
+ * object being acted on (i.e. the 'this' parameter).
+ */
+
+#define _IO_JUMPS(THIS) ((struct _IO_FILE_plus*)(THIS))->vtable
+/* These macros will change when we re-implement vtables to use "thunks"! */
+#define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME
+#define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC.pfn(THIS)
+#define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC.pfn(THIS, X1)
+#define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC.pfn(THIS, X1, X2)
+#define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC.pfn(THIS, X1,X2, X3)
+#define JUMP_INIT(NAME, VALUE) {0, 0, VALUE}
+#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0)
+
+/* The 'finish' function does any final cleaning up of an _IO_FILE object.
+ It does not delete (free) it, but does everything else to finalize it/
+ It matches the streambuf::~streambuf virtual destructor. */
+typedef void (*_IO_finish_t) __P((_IO_FILE*)); /* finalize */
+#define _IO_FINISH(FP) JUMP0(__finish, FP)
+
+/* The 'overflow' hook flushes the buffer.
+ The second argument is a character, or EOF.
+ It matches the streambuf::overflow virtual function. */
+typedef int (*_IO_overflow_t) __P((_IO_FILE*, int));
+#define _IO_OVERFLOW(FP, CH) JUMP1(__overflow, FP, CH)
+
+/* The 'underflow' hook tries to fills the get buffer.
+ It returns the next character (as an unsigned char) or EOF. The next
+ character remains in the get buffer, and the get postion is not changed.
+ It matches the streambuf::underflow virtual function. */
+typedef int (*_IO_underflow_t) __P((_IO_FILE*));
+#define _IO_UNDERFLOW(FP) JUMP0(__underflow, FP)
+
+/* The 'uflow' hook returns the next character in the input stream
+ (cast to unsigned char), and increments the read position;
+ EOF is returned on failure.
+ It matches the streambuf::uflow virtual function, which is not in the
+ cfront implementation, but was added to C++ by the ANSI/ISO committee. */
+#define _IO_UFLOW(FP) JUMP0(__uflow, FP)
+
+/* The 'pbackfail' hook handles backing up.
+ It matches the streambuf::pbackfail virtual function. */
+typedef int (*_IO_pbackfail_t) __P((_IO_FILE*, int));
+#define _IO_PBACKFAIL(FP, CH) JUMP1(__pbackfail, FP, CH)
+
+/* The 'xsputn' hook writes upto N characters from buffer DATA.
+ Returns the number of character actually written.
+ It matches the streambuf::xsputn virtual function. */
+typedef _IO_size_t (*_IO_xsputn_t)
+ __P((_IO_FILE *FP, const void *DATA, _IO_size_t N));
+#define _IO_XSPUTN(FP, DATA, N) JUMP2(__xsputn, FP, DATA, N)
+
+/* The 'xsgetn' hook reads upto N characters into buffer DATA.
+ Returns the number of character actually read.
+ It matches the streambuf::xsgetn virtual function. */
+typedef _IO_size_t (*_IO_xsgetn_t) __P((_IO_FILE*FP, void*DATA, _IO_size_t N));
+#define _IO_XSGETN(FP, DATA, N) JUMP2(__xsgetn, FP, DATA, N)
+
+/* The 'seekoff' hook moves the stream position to a new position
+ relative to the start of the file (if DIR==0), the current position
+ (MODE==1), or the end of the file (MODE==2).
+ It matches the streambuf::seekoff virtual function.
+ It is also used for the ANSI fseek function. */
+typedef _IO_fpos_t (*_IO_seekoff_t)
+ __P((_IO_FILE* FP, _IO_off_t OFF, int DIR, int MODE));
+#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3(__seekoff, FP, OFF, DIR, MODE)
+
+/* The 'seekpos' hook also moves the stream position,
+ but to an absolute position given by a fpos_t (seekpos).
+ It matches the streambuf::seekpos virtual function.
+ It is also used for the ANSI fgetpos and fsetpos functions. */
+/* The _IO_seek_cur and _IO_seek_end options are not allowed. */
+typedef _IO_fpos_t (*_IO_seekpos_t) __P((_IO_FILE*, _IO_fpos_t, int));
+#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2(__seekpos, FP, POS, FLAGS)
+
+/* The 'setbuf' hook gives a buffer to the file.
+ It matches the streambuf::setbuf virtual function. */
+typedef _IO_FILE* (*_IO_setbuf_t) __P((_IO_FILE*, char *, _IO_ssize_t));
+#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2(__setbuf, FP, BUFFER, LENGTH)
+
+/* The 'sync' hook attempts to synchronize the internal data structures
+ of the file with the external state.
+ It matches the streambuf::sync virtual function. */
+typedef int (*_IO_sync_t) __P((_IO_FILE*));
+#define _IO_SYNC(FP) JUMP0(__sync, FP)
+
+/* The 'doallocate' hook is used to tell the file to allocate a buffer.
+ It matches the streambuf::doallocate virtual function, which is not
+ in the ANSI/ISO C++ standard, but is part traditional implementations. */
+typedef int (*_IO_doallocate_t) __P((_IO_FILE*));
+#define _IO_DOALLOCATE(FP) JUMP0(__doallocate, FP)
+
+/* The following four hooks (sysread, syswrite, sysclose, sysseek, and
+ sysstat) are low-level hooks specific to this implementation.
+ There is no correspondance in the ANSI/ISO C++ standard library.
+ The hooks basically correspond to the Unix system functions
+ (read, write, close, lseek, and stat) except that a _IO_FILE*
+ parameter is used instead of a integer file descriptor; the default
+ implementation used for normal files just calls those functions.
+ The advantage of overriding these functions instead of the higher-level
+ ones (underflow, overflow etc) is that you can leave all the buffering
+ higher-level functions. */
+
+/* The 'sysread' hook is used to read data from the external file into
+ an existing buffer. It generalizes the Unix read(2) function.
+ It matches the streambuf::sys_read virtual function, which is
+ specific to this implementaion. */
+typedef _IO_ssize_t (*_IO_read_t) __P((_IO_FILE*, void*, _IO_ssize_t));
+#define _IO_SYSREAD(FP, DATA, LEN) JUMP2(__read, FP, DATA, LEN)
+
+/* The 'syswrite' hook is used to write data from an existing buffer
+ to an external file. It generalizes the Unix write(2) function.
+ It matches the streambuf::sys_write virtual function, which is
+ specific to this implementaion. */
+typedef _IO_ssize_t (*_IO_write_t) __P((_IO_FILE*,const void*,_IO_ssize_t));
+#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2(__write, FP, DATA, LEN)
+
+/* The 'sysseek' hook is used to re-position an external file.
+ It generalizes the Unix lseek(2) function.
+ It matches the streambuf::sys_seek virtual function, which is
+ specific to this implementaion. */
+typedef _IO_fpos_t (*_IO_seek_t) __P((_IO_FILE*, _IO_off_t, int));
+#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2(__seek, FP, OFFSET, MODE)
+
+/* The 'sysclose' hook is used to finalize (close, finish up) an
+ external file. It generalizes the Unix close(2) function.
+ It matches the streambuf::sys_close virtual function, which is
+ specific to this implementation. */
+typedef int (*_IO_close_t) __P((_IO_FILE*)); /* finalize */
+#define _IO_SYSCLOSE(FP) JUMP0(__close, FP)
+
+/* The 'sysstat' hook is used to get information about an external file
+ into a struct stat buffer. It generalizes the Unix fstat(2) call.
+ It matches the streambuf::sys_stat virtual function, which is
+ specific to this implementaion. */
+typedef int (*_IO_stat_t) __P((_IO_FILE*, void*));
+#define _IO_SYSSTAT(FP, BUF) JUMP1(__stat, FP, BUF)
+
+
+#define _IO_CHAR_TYPE char /* unsigned char ? */
+#define _IO_INT_TYPE int
+
+struct _IO_jump_t {
+ JUMP_FIELD(_G_size_t, __dummy);
+ JUMP_FIELD(_IO_finish_t, __finish);
+ JUMP_FIELD(_IO_overflow_t, __overflow);
+ JUMP_FIELD(_IO_underflow_t, __underflow);
+ JUMP_FIELD(_IO_underflow_t, __uflow);
+ JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
+ /* showmany */
+ JUMP_FIELD(_IO_xsputn_t, __xsputn);
+ JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
+ JUMP_FIELD(_IO_seekoff_t, __seekoff);
+ JUMP_FIELD(_IO_seekpos_t, __seekpos);
+ JUMP_FIELD(_IO_setbuf_t, __setbuf);
+ JUMP_FIELD(_IO_sync_t, __sync);
+ JUMP_FIELD(_IO_doallocate_t, __doallocate);
+ JUMP_FIELD(_IO_read_t, __read);
+ JUMP_FIELD(_IO_write_t, __write);
+ JUMP_FIELD(_IO_seek_t, __seek);
+ JUMP_FIELD(_IO_close_t, __close);
+ JUMP_FIELD(_IO_stat_t, __stat);
+#if 0
+ get_column;
+ set_column;
+#endif
+};
+
+/* We always allocate an extra word following an _IO_FILE.
+ This contains a pointer to the function jump table used.
+ This is for compatibility with C++ streambuf; the word can
+ be used to smash to a pointer to a virtual function table. */
+
+struct _IO_FILE_plus {
+ _IO_FILE file;
+ const struct _IO_jump_t *vtable;
+};
+
+/* Generic functions */
+
+extern int _IO_switch_to_get_mode __P((_IO_FILE*));
+extern void _IO_init __P((_IO_FILE*, int));
+extern int _IO_sputbackc __P((_IO_FILE*, int));
+extern int _IO_sungetc __P((_IO_FILE*));
+extern void _IO_un_link __P((_IO_FILE*));
+extern void _IO_link_in __P((_IO_FILE *));
+extern void _IO_doallocbuf __P((_IO_FILE*));
+extern void _IO_unsave_markers __P((_IO_FILE*));
+extern void _IO_setb __P((_IO_FILE*, char*, char*, int));
+extern unsigned _IO_adjust_column __P((unsigned, const char *, int));
+#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN(__fp, __s, __n)
+
+/* Marker-related function. */
+
+extern void _IO_init_marker __P((struct _IO_marker *, _IO_FILE *));
+extern void _IO_remove_marker __P((struct _IO_marker*));
+extern int _IO_marker_difference __P((struct _IO_marker *, struct _IO_marker *));
+extern int _IO_marker_delta __P((struct _IO_marker *));
+extern int _IO_seekmark __P((_IO_FILE *, struct _IO_marker *, int));
+
+/* Default jumptable functions. */
+
+extern int _IO_default_underflow __P((_IO_FILE*));
+extern int _IO_default_uflow __P((_IO_FILE*));
+extern int _IO_default_doallocate __P((_IO_FILE*));
+extern void _IO_default_finish __P((_IO_FILE *));
+extern int _IO_default_pbackfail __P((_IO_FILE*, int));
+extern _IO_FILE* _IO_default_setbuf __P((_IO_FILE *, char*, _IO_ssize_t));
+extern _IO_size_t _IO_default_xsputn __P((_IO_FILE *, const void*, _IO_size_t));
+extern _IO_size_t _IO_default_xsgetn __P((_IO_FILE *, void*, _IO_size_t));
+extern _IO_fpos_t _IO_default_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_default_seekpos __P((_IO_FILE*, _IO_fpos_t, int));
+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((void));
+extern void _IO_cleanup __P((void));
+extern void _IO_flush_all_linebuffered __P((void));
+
+#define _IO_do_flush(_f) \
+ _IO_do_write(_f, (_f)->_IO_write_base, \
+ (_f)->_IO_write_ptr-(_f)->_IO_write_base)
+#define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING)
+#define _IO_mask_flags(fp, f, mask) \
+ ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
+#define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\
+ (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg))
+#define _IO_setp(__fp, __p, __ep) \
+ ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep))
+#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
+#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
+#define _IO_have_markers(fp) ((fp)->_markers != NULL)
+#define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
+
+/* Jumptable functions for files. */
+
+extern int _IO_file_doallocate __P((_IO_FILE*));
+extern _IO_FILE* _IO_file_setbuf __P((_IO_FILE *, char*, _IO_ssize_t));
+extern _IO_fpos_t _IO_file_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
+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,int,int));
+
+/* Other strfile functions */
+extern void _IO_str_init_static __P((_IO_FILE *, char*, int, char*));
+extern void _IO_str_init_readonly __P((_IO_FILE *, const char*, int));
+extern _IO_ssize_t _IO_str_count __P ((_IO_FILE*));
+
+extern _IO_size_t _IO_getline __P((_IO_FILE*,char*,_IO_size_t,int,int));
+extern _IO_ssize_t _IO_getdelim __P((char**, _IO_size_t*, int, _IO_FILE*));
+extern double _IO_strtod __P((const char *, char **));
+extern char * _IO_dtoa __P((double __d, int __mode, int __ndigits,
+ int *__decpt, int *__sign, char **__rve));
+extern int _IO_outfloat __P((double __value, _IO_FILE *__sb, int __type,
+ int __width, int __precision, int __flags,
+ int __sign_mode, int __fill));
+
+extern _IO_FILE *_IO_list_all;
+extern void (*_IO_cleanup_registration_needed) __P ((void));
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#if !defined(__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, FD}
+
+/* VTABLE_LABEL defines NAME as of the CLASS class.
+ CNLENGTH is strlen(#CLASS). */
+#ifdef __GNUC__
+#if _G_VTABLE_LABEL_HAS_LENGTH
+#define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+ extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS);
+#else
+#define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+ extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS);
+#endif
+#endif /* __GNUC__ */
+
+#if !defined(builtinbuf_vtable) && defined(__cplusplus)
+#ifdef __GNUC__
+VTABLE_LABEL(builtinbuf_vtable, builtinbuf, 10)
+#else
+#if _G_VTABLE_LABEL_HAS_LENGTH
+#define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf
+#else
+#define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf
+#endif
+#endif
+#endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define _IO_va_start(args, last) va_start(args, last)
+#else
+#define _IO_va_start(args, last) va_start(args)
+#endif
+
+extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf;
+
+#if 1
+#define COERCE_FILE(FILE) /* Nothing */
+#else
+/* This is part of the kludge for binary compatibility with old stdio. */
+#define COERCE_FILE(FILE) \
+ (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \
+ && (FILE) = *(FILE**)&((int*)fp)[1])
+#endif
+
+#ifdef EINVAL
+#define MAYBE_SET_EINVAL errno = EINVAL
+#else
+#define MAYBE_SET_EINVAL /* nothing */
+#endif
+
+#ifdef DEBUG
+#define CHECK_FILE(FILE,RET) \
+ if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \
+ else { COERCE_FILE(FILE); \
+ if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \
+ { errno = EINVAL; return RET; }}
+#else
+#define CHECK_FILE(FILE,RET) \
+ COERCE_FILE(FILE)
+#endif
diff --git a/gnu/lib/libg++/libio/osform.cc b/gnu/lib/libg++/libio/osform.cc
new file mode 100644
index 00000000000..8c0011703da
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include <iostream.h>
+#include <stdarg.h>
+
+ostream& ostream::form(const char *format ...)
+{
+ if (opfx()) {
+ 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/ostream.h b/gnu/lib/libg++/libio/ostream.h
new file mode 100644
index 00000000000..f54ec1de9a1
--- /dev/null
+++ b/gnu/lib/libg++/libio/ostream.h
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <stream.h>
diff --git a/gnu/lib/libg++/libio/outfloat.c b/gnu/lib/libg++/libio/outfloat.c
new file mode 100644
index 00000000000..a74b1a2c3e1
--- /dev/null
+++ b/gnu/lib/libg++/libio/outfloat.c
@@ -0,0 +1,204 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+
+/* 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
+DEFUN(_IO_outfloat, (value, sb, type, width, precision, flags,
+ sign_mode, fill),
+ double value AND _IO_FILE *sb AND int type AND int width
+ AND int precision AND int flags AND int sign_mode AND 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 00000000000..320afd06d9b
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "libioP.h"
+#include "parsestream.h"
+#include <stdlib.h>
+
+streambuf* parsebuf::setbuf(char*, int)
+{
+ return NULL;
+}
+
+int parsebuf::tell_in_line()
+{
+ return 0;
+}
+
+int parsebuf::pbackfail(int c)
+{
+ if (c == EOF)
+ return 0;
+ if (seekoff(-1, ios::cur) == EOF)
+ return EOF;
+ return (unsigned char)c;
+}
+
+char* parsebuf::current_line() { return NULL; }
+
+streampos parsebuf::seekoff(streamoff offset, _seek_dir dir, int)
+{
+ // Make offset relative to line start.
+ switch (dir) {
+ case ios::beg:
+ offset -= pos_at_line_start;
+ break;
+ case ios::cur:
+ offset += tell_in_line();
+ break;
+ default:
+ return EOF;
+ }
+ if (offset < -1)
+ return EOF;
+ if (offset > _line_length + 1)
+ return EOF;
+ return seek_in_line(offset) + pos_at_line_start;
+}
+
+// string_parsebuf invariants:
+// The reserve ares (base() .. ebuf()) is always the entire string.
+// The get area (eback() .. egptr()) is the extended current line
+// (i.e. with the '\n' at either end, if these exist).
+
+string_parsebuf::string_parsebuf(char *buf, int len,
+ int delete_at_close /* = 0*/)
+: parsebuf()
+{
+ setb(buf, buf+len, delete_at_close);
+ register char *ptr = buf;
+ while (ptr < ebuf() && *ptr != '\n') ptr++;
+ _line_length = ptr - buf;
+ setg(buf, buf, ptr);
+}
+
+int string_parsebuf::underflow()
+{
+ register char* ptr = egptr(); // Point to end of current_line
+ do {
+ int i = right() - ptr;
+ if (i <= 0)
+ return EOF;
+ ptr++; i--; // Skip '\n'.
+ char *line_start = ptr;
+ while (ptr < right() && *ptr == '\n') ptr++;
+ setg(line_start-1, line_start, ptr + (ptr < right()));
+ pos_at_line_start = line_start - left();
+ _line_length = ptr - line_start;
+ __line_number++;
+ } while (gptr() == ptr);
+ return *gptr();
+}
+
+char* string_parsebuf::current_line()
+{
+ char *ptr = eback();
+ if (__line_number > 0)
+ ptr++; // Skip '\n' at end of previous line.
+ return ptr;
+}
+
+int string_parsebuf::tell_in_line()
+{
+ int offset = gptr() - eback();
+ if (__line_number > 0)
+ offset--;
+ return offset;
+}
+
+int string_parsebuf::seek_in_line(int i)
+{
+ int delta = i - tell_in_line();
+ gbump(delta); // FIXME: Needs error (bounds) checking!
+ return i;
+}
+
+static const char NewLine[1] = { '\n' };
+
+general_parsebuf::general_parsebuf(streambuf *buf, int delete_arg_buf)
+ : parsebuf()
+{
+ delete_buf = delete_arg_buf;
+ sbuf = buf;
+ int buf_size = 128;
+ char* buffer = 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 i; // Suppress warnings.
+#else
+ if (i > 0) {
+ size_t len = line_length();
+ if ((unsigned)i > len) i = len;
+ }
+ else if (i < -1) i = -1;
+ int new_pos = seekoff(pos_at_line_start + i, ios::beg);
+ if (new_pos == EOF)
+ return tell_in_line();
+ else return new_pos - pos_at_line_start;
+#endif
+}
diff --git a/gnu/lib/libg++/libio/parsestream.h b/gnu/lib/libg++/libio/parsestream.h
new file mode 100644
index 00000000000..326ab87a809
--- /dev/null
+++ b/gnu/lib/libg++/libio/parsestream.h
@@ -0,0 +1,156 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef PARSESTREAM_H
+#define PARSESTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include "streambuf.h"
+
+extern "C++" {
+// A parsebuf is a streambuf optimized for scanning text files.
+// It keeps track of line and column numbers.
+// It is guaranteed to remember the entire current line,
+// as well the '\n'-s on either side of it (if they exist).
+// You can arbitrarily seek (or unget) within this extended line.
+// Other backward seeks are not supported.
+// Normal read semantics are supported (and hence istream operators like >>).
+
+class parsebuf : public streambuf {
+ protected:
+ _IO_fpos_t pos_at_line_start;
+ long _line_length;
+ unsigned long __line_number;
+ char *buf_start;
+ char *buf_end;
+
+ public:
+ parsebuf *chain;
+
+ // Return column number (raw - don't handle tabs etc).
+ // Retult can be -1, meaning: at '\n' before current line.
+ virtual int tell_in_line();
+
+ // seek to (raw) column I in current line.
+ // Result is new (raw) column position - differs from I if unable to seek.
+ // Seek to -1 tries to seek to before previous LF.
+ virtual int seek_in_line(int i);
+
+ // Note: there is no "current line" initially, until something is read.
+
+ // Current line number, starting with 0.
+ // If tell_in_line()==-1, then line number of next line.
+ int line_number() { return __line_number; }
+
+ // Length of current line, not counting either '\n'.
+ int line_length() { return _line_length; }
+ // Current line - not a copy, so file ops may trash it.
+ virtual char* current_line();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streambuf* setbuf(char* p, int len);
+ protected:
+ parsebuf() { chain= NULL;
+ __line_number = 0; pos_at_line_start = 0; _line_length = -1; }
+ virtual int pbackfail(int c);
+};
+
+// A string_parsebuf is a parsebuf whose source is a fixed string.
+
+class string_parsebuf : public parsebuf {
+ public:
+ int do_delete;
+ string_parsebuf(char *str, int len, int delete_at_close=0);
+ virtual int underflow();
+ virtual char* current_line();
+ virtual int seek_in_line(int i);
+ virtual int tell_in_line();
+ char *left() const { return base(); }
+ char *right() const { return ebuf(); }
+// streampos seekoff(streamoff, _seek_dir, int);
+};
+
+// A func_parsebuf calls a given function to get new input.
+// Each call returns an entire NUL-terminated line (without the '\n').
+// That line has been allocated with malloc(), not new.
+// The interface is tailored to the GNU readline library.
+// Example:
+// char* DoReadLine(void* arg)
+// {
+// char *line = readline((char*)arg); /* 'arg' is used as prompt. */
+// if line == NULL) { putc('\n', stderr); return NULL; }
+// if (line[0] != '\0') add_history(line);
+// return line;
+// }
+// char PromptBuffer[100] = "> ";
+// func_parsebuf my_stream(DoReadLine, PromptBuffer);
+
+typedef char *(*CharReader)(void *arg);
+class istream;
+
+class func_parsebuf : public parsebuf {
+ public:
+ void *arg;
+ CharReader read_func;
+ int backed_up_to_newline;
+ func_parsebuf(CharReader func, void *argm = NULL);
+ int underflow();
+ virtual int tell_in_line();
+ virtual int seek_in_line(int i);
+ virtual char* current_line();
+};
+
+// A general_parsebuf is a parsebuf which gets its input from some
+// other streambuf. It explicitly buffers up an entire line.
+
+class general_parsebuf : public parsebuf {
+ public:
+ streambuf *sbuf;
+ int delete_buf; // Delete sbuf when destroying this.
+ general_parsebuf(streambuf *buf, int delete_arg_buf = 0);
+ int underflow();
+ virtual int tell_in_line();
+ virtual int seek_in_line(int i);
+ ~general_parsebuf();
+ virtual char* current_line();
+};
+
+#if 0
+class parsestream : public istream {
+ streammarker marks[2];
+ short _first; // of the two marks; either 0 or 1
+ int _lineno;
+ int first() { return _first; }
+ int second() { return 1-_first; }
+ int line_length() { marks[second].delta(marks[first]); }
+ int line_length() { marks[second].delta(marks[first]); }
+ int seek_in_line(int i);
+ int tell_in_line();
+ int line_number();
+};
+#endif
+} // extern "C++"
+#endif /*!defined(PARSESTREAM_H)*/
diff --git a/gnu/lib/libg++/libio/pfstream.cc b/gnu/lib/libg++/libio/pfstream.cc
new file mode 100644
index 00000000000..3fa93c958f8
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "libioP.h"
+#include <pfstream.h>
+#include <procbuf.h>
+
+ipfstream::ipfstream(const char *name, int mode, int prot)
+{
+ const char* p;
+
+ // Look for '| command' (as used by ftp).
+ for (p = name; *p == ' ' || *p == '\t'; p++) ;
+ if (*p == '|') {
+ procbuf *pbuf = new procbuf();
+ init(pbuf);
+ if (!pbuf->open(p+1, mode))
+ set(ios::badbit);
+ return;
+ }
+
+ // Look for 'command |'
+ while (*p) p++; // Point to last
+ while (p[-1] == ' ' || p[-1] == '\t' || p[-1] == '\n') p--;
+ if (p[-1] == '|') {
+ // Must remove the final '|'.
+ p--;
+#if !defined (__GNUC__) || defined (__STRICT_ANSI__)
+ char *command = new char[p-name+1];
+#else
+ char command[p-name+1];
+#endif
+ memcpy(command, name, p-name);
+ command[p-name] = '\0';
+
+ procbuf *pbuf = new procbuf();
+ if (pbuf->open(command, mode))
+ set(ios::badbit);
+#if !defined (__GNUC__) || defined (__STRICT_ANSI__)
+ delete command;
+#endif
+ return;
+ }
+
+ init(new filebuf());
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+opfstream::opfstream(const char *name, int mode, int prot)
+{
+ const char *p;
+ // Look for '| command'.
+ for (p = name; *p == ' ' || *p == '\t'; p++) ;
+ if (*p == '|') {
+ procbuf *pbuf = new procbuf();
+ init(pbuf);
+ if (!pbuf->open(p+1, mode))
+ set(ios::badbit);
+ }
+ else {
+ init(new filebuf());
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+ }
+}
diff --git a/gnu/lib/libg++/libio/pfstream.h b/gnu/lib/libg++/libio/pfstream.h
new file mode 100644
index 00000000000..3c5458baaa9
--- /dev/null
+++ b/gnu/lib/libg++/libio/pfstream.h
@@ -0,0 +1,59 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _PFSTREAM_H
+#define _PFSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <fstream.h>
+
+extern "C++" {
+// ipfstream foo("NAME") is like: ifstream foo("NAME"). However,
+// if NAME starts *or ends* with a '|', the remainder of NAME is
+// evaluated as a shell command (using a procbuf), and all input
+// read from foo is whatever that shell writes to its standard output.
+// E.g. ipfstream foo("|zcat foo.Z") or ipfstream foo("zcat foo.Z|")
+// (These two forms are equivalent.)
+
+class ipfstream : public ifstream {
+ public:
+ ipfstream(const char *name, int mode=ios::in, int prot=0664);
+};
+
+// opfstream foo("NAME") is like: ofstream foo("NAME").
+// However, if NAME starts with a '|', the remainder of NAME is
+// evaluated as a shell command (using a procbuf), and all output
+// written to foo is piped to the standard input of that shell.
+// E.g. opfstream foo("|more");
+
+class opfstream : public ofstream {
+ public:
+ opfstream(const char *name, int mode=ios::out, int prot=0664);
+};
+} // extern "C++"
+#endif /*!_PFSTREAM_H*/
+
diff --git a/gnu/lib/libg++/libio/procbuf.cc b/gnu/lib/libg++/libio/procbuf.cc
new file mode 100644
index 00000000000..1c79ce4ce0f
--- /dev/null
+++ b/gnu/lib/libg++/libio/procbuf.cc
@@ -0,0 +1,55 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#define _POSIX_SOURCE
+#include "libioP.h"
+#include "procbuf.h"
+
+procbuf::procbuf(const char *command, int mode) : filebuf()
+{
+ _IO_proc_open(this, command, (mode & ios::in) ? "r" : "w");
+}
+
+procbuf *procbuf::open(const char *command, int mode)
+{
+ return (procbuf*)_IO_proc_open(this, command, (mode & ios::in) ? "r" : "w");
+}
+
+/* #define USE_SIGMASK */
+
+int procbuf::sys_close()
+{
+ return _IO_proc_close(this);
+}
+
+procbuf::~procbuf()
+{
+ close();
+}
diff --git a/gnu/lib/libg++/libio/procbuf.h b/gnu/lib/libg++/libio/procbuf.h
new file mode 100644
index 00000000000..b361a6a7c84
--- /dev/null
+++ b/gnu/lib/libg++/libio/procbuf.h
@@ -0,0 +1,50 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _PROCBUF_H
+#define _PROCBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <streambuf.h>
+
+extern "C++" {
+class procbuf : public filebuf {
+ /* Following fields must match those in struct _IO_proc_file */
+ _IO_pid_t _pid;
+ procbuf *_next;
+ public:
+ procbuf() : filebuf() { }
+ procbuf(const char *command, int mode);
+ procbuf* open(const char *command, int mode);
+ procbuf *close() { return (procbuf*)filebuf::close(); }
+ virtual int sys_close();
+ ~procbuf();
+};
+} // extern "C++"
+
+#endif /* !_PROCBUF_H */
diff --git a/gnu/lib/libg++/libio/sbform.cc b/gnu/lib/libg++/libio/sbform.cc
new file mode 100644
index 00000000000..c17bd08db15
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "streambuf.h"
+#include <stdarg.h>
+
+int streambuf::vform(char const *fmt0, _IO_va_list ap)
+{
+ return _IO_vfprintf(this, fmt0, ap);
+}
+int streambuf::form(char const *format ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int count = _IO_vfprintf(this, format, ap);
+ va_end(ap);
+ return count;
+}
diff --git a/gnu/lib/libg++/libio/sbgetline.cc b/gnu/lib/libg++/libio/sbgetline.cc
new file mode 100644
index 00000000000..700e2ec7afc
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "streambuf.h"
+
+long streambuf::sgetline(char* buf, _IO_size_t n, char delim, int extract_delim)
+{
+ return _IO_getline(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 00000000000..c0ec35c53db
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "libioP.h"
+#include "streambuf.h"
+#include <stdarg.h>
+
+int streambuf::vscan(char const *fmt0, _IO_va_list ap, ios* stream /* = NULL*/)
+{
+ int errcode = 0;
+ int count = _IO_vfscanf(this, fmt0, ap, &errcode);
+ if (stream)
+ stream->setstate((ios::iostate)errcode);
+ return count;
+}
+int streambuf::scan(char const *format ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int count = _IO_vfscanf(this, format, ap, NULL);
+ va_end(ap);
+ return count;
+}
diff --git a/gnu/lib/libg++/libio/shlib_version b/gnu/lib/libg++/libio/shlib_version
new file mode 100644
index 00000000000..97c9f92d6b8
--- /dev/null
+++ b/gnu/lib/libg++/libio/shlib_version
@@ -0,0 +1,2 @@
+major=0
+minor=0
diff --git a/gnu/lib/libg++/libio/stdfiles.c b/gnu/lib/libg++/libio/stdfiles.c
new file mode 100644
index 00000000000..1d0ef85be90
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdfiles.c
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 1993, 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+
+/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
+ for C code. Compare stdstreams.cc.
+ (The difference is that here the vtable field is set to 0,
+ so the objects defined are not valid C++ objects. On the other
+ hand, we don't need a C++ compiler to build this file.) */
+
+#include "libioP.h"
+
+
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ struct _IO_FILE_plus NAME \
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}
+
+DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
+DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS);
+DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_.file,
+ _IO_NO_READS+_IO_UNBUFFERED);
+
+_IO_FILE *_IO_list_all = &_IO_stderr_.file;
diff --git a/gnu/lib/libg++/libio/stdiostream.cc b/gnu/lib/libg++/libio/stdiostream.cc
new file mode 100644
index 00000000000..80db5e59bfd
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdiostream.cc
@@ -0,0 +1,159 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <stdiostream.h>
+#include "libioP.h"
+
+// A stdiobuf is "tied" to a FILE object (as used by the stdio package).
+// Thus a stdiobuf is always synchronized with the corresponding FILE,
+// though at the cost of some overhead. (If you use the implementation
+// of stdio supplied with this library, you don't need stdiobufs.)
+// This implementation inherits from filebuf, but implement the virtual
+// functions sys_read/..., using the stdio functions fread/... instead
+// of the low-level read/... system calls. This has the advantage that
+// we get all of the nice filebuf semantics automatically, though
+// with some overhead.
+
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+stdiobuf::stdiobuf(FILE *f) : filebuf(fileno(f))
+{
+ _file = f;
+ // Turn off buffer in stdiobuf. Instead, rely on buffering in (FILE).
+ // Thus the stdiobuf will be synchronized with the FILE.
+ setbuf(NULL, 0);
+}
+
+stdiobuf::~stdiobuf()
+{
+ /* Only needed if we're buffered. Not buffered is the default. */
+ _IO_do_flush((_IO_FILE*)this);
+}
+
+streamsize stdiobuf::sys_read(char* buf, streamsize size)
+{
+ // A minor optimization, but it makes a noticable difference.
+ // A bigger optimization would be to write stdiobuf::underflow,
+ // but that has some modularity disadvantages. Re-evaluate that
+ // after we have gotten rid of the double indirection. FIXME
+ if (size == 1)
+ {
+ register ch = getc(_file);
+ if (ch == EOF)
+ return 0;
+ *buf = (char)ch;
+ return 1;
+ }
+ else
+ return fread(buf, 1, size, _file);
+}
+
+streamsize stdiobuf::sys_write(const char *buf, streamsize n)
+{
+ _IO_ssize_t count = fwrite(buf, 1, n, _file);
+ if (_offset >= 0)
+ _offset += n;
+ return count;
+}
+
+streampos stdiobuf::sys_seek(streamoff offset, _seek_dir dir)
+{
+ // Normally, equivalent to: fdir=dir
+ int fdir =
+ (dir == ios::beg) ? SEEK_SET :
+ (dir == ios::cur) ? SEEK_CUR :
+ (dir == ios::end) ? SEEK_END :
+ dir;
+ return fseek(_file, offset, fdir);
+}
+
+int stdiobuf::sys_close()
+{
+ int status = fclose(_file);
+ _file = NULL;
+ return status;
+}
+
+int stdiobuf::sync()
+{
+ if (_IO_do_flush((_IO_FILE*)this))
+ return EOF;
+ if (!(xflags() & _IO_NO_WRITES))
+ if (fflush(_file))
+ return EOF;
+ return 0;
+}
+
+int stdiobuf::overflow(int c /* = EOF*/)
+{
+ if (filebuf::overflow(c) == EOF)
+ return EOF;
+ if (c != EOF)
+ return c;
+ return fflush(_file);
+}
+
+streamsize stdiobuf::xsputn(const char* s, streamsize n)
+{
+ if (buffered ())
+ {
+ // The filebuf implementation of sputn loses.
+ return streambuf::xsputn(s, n);
+ }
+ else
+ return fwrite (s, 1, n, _file);
+}
+
+void stdiobuf::buffered (int b)
+{
+ if (b)
+ {
+ if (_flags & _IO_UNBUFFERED)
+ { /* Was unbuffered, make it buffered. */
+ _flags &= ~_IO_UNBUFFERED;
+ }
+ }
+ else
+ {
+ if (!(_flags & _IO_UNBUFFERED))
+ { /* Was buffered, make it unbuffered. */
+ setbuf(NULL, 0);
+ }
+ }
+}
diff --git a/gnu/lib/libg++/libio/stdiostream.h b/gnu/lib/libg++/libio/stdiostream.h
new file mode 100644
index 00000000000..73d49f96c22
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdiostream.h
@@ -0,0 +1,79 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef _STDIOSTREAM_H
+#define _STDIOSTREAM_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <iostream.h>
+#include <stdio.h>
+
+extern "C++" {
+class stdiobuf : public filebuf {
+ protected:
+ FILE *_file;
+ public:
+ FILE* stdiofile() const { return _file; }
+ stdiobuf(FILE *);
+ ~stdiobuf();
+ int buffered () const { return _flags & _IO_UNBUFFERED ? 0 : 1; }
+ void buffered (int);
+ virtual streamsize sys_read(char*, streamsize);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual int sys_close();
+ virtual int sync();
+ virtual int overflow(int c = EOF);
+ streamsize xsputn(const char* s, streamsize n);
+};
+
+class istdiostream : public istream
+{
+private:
+ stdiobuf _file;
+public:
+ istdiostream (FILE* __f) : _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); }
+};
+} // extern "C++"
+
+#endif /* !_STDIOSTREAM_H */
diff --git a/gnu/lib/libg++/libio/stdstrbufs.cc b/gnu/lib/libg++/libio/stdstrbufs.cc
new file mode 100644
index 00000000000..8af259988a5
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdstrbufs.cc
@@ -0,0 +1,115 @@
+/*
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+
+/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
+ for C++ code. Compare stdfiles.c.
+ (The difference is that here the vtable field is set to
+ point to builtinbuf's vtable, so the objects are effectively
+ of class builtinbuf.) */
+
+#include "libioP.h"
+#include <stdio.h>
+
+#if !defined(filebuf_vtable) && defined(__cplusplus)
+#ifdef __GNUC__
+extern char filebuf_vtable[]
+ asm (_G_VTABLE_LABEL_PREFIX
+#if _G_VTABLE_LABEL_HAS_LENGTH
+ "7"
+#endif
+ "filebuf");
+#else /* !__GNUC__ */
+#if _G_VTABLE_LABEL_HAS_LENGTH
+#define filebuf_vtable _G_VTABLE_LABEL_PREFIX_ID##7filebuf
+#else
+#define filebuf_vtable _G_VTABLE_LABEL_PREFIX_ID##filebuf
+#endif
+extern char filebuf_vtable[];
+#endif /* !__GNUC__ */
+#endif /* !defined(filebuf_vtable) && defined(__cplusplus) */
+
+#ifndef STD_VTABLE
+#define STD_VTABLE (const struct _IO_jump_t *)filebuf_vtable
+#endif
+
+#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 {
+ struct {
+ _IO_FILE file;
+ const void *vtable;
+ } s;
+ FILE *stdio_file;
+};
+
+/* Define stdiobuf_vtable as a name for the virtual function table
+ of the stdiobuf class. */
+#ifndef stdiobuf_vtable
+#ifdef __GNUC__
+extern struct _IO_jump_t stdiobuf_vtable
+ asm (_G_VTABLE_LABEL_PREFIX
+#if _G_VTABLE_LABEL_HAS_LENGTH
+ "8"
+#endif
+ "stdiobuf");
+#else /* !__GNUC__ */
+#if _G_VTABLE_LABEL_HAS_LENGTH
+#define stdiobuf_vtable _G_VTABLE_LABEL_PREFIX_ID##8stdiobuf
+#else
+#define stdiobuf_vtable _G_VTABLE_LABEL_PREFIX_ID##stdiobuf
+#endif
+extern struct _IO_jump_t stdiobuf_vtable;
+#endif /* !__GNUC__ */
+#endif /* !stdiobuf_vtable */
+
+#if _IO_UNIFIED_JUMPTABLES
+#define JUMP_PTR /* Nothing */
+#else
+#define JUMP_PTR &_IO_streambuf_jumps,
+#endif
+
+#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, JUMP_PTR 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.s.file);
+DEF_STDIOFILE(_IO_stderr_buf, 2, stderr, _IO_NO_READS, &_IO_stdout_buf.s.file);
+
+_IO_FILE *_IO_list_all = &_IO_stderr_buf.s.file;
+#endif /* !_STDIO_USES_IOSTREAM */
diff --git a/gnu/lib/libg++/libio/stdstreams.cc b/gnu/lib/libg++/libio/stdstreams.cc
new file mode 100644
index 00000000000..051ca574fc8
--- /dev/null
+++ b/gnu/lib/libg++/libio/stdstreams.cc
@@ -0,0 +1,149 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include "libioP.h"
+#include "streambuf.h"
+#include <stdio.h>
+
+// The ANSI draft requires that operations on cin/cout/cerr can be
+// mixed with operations on stdin/stdout/stderr on a character by
+// character basis. This normally requires that the streambuf's
+// used by cin/cout/cerr be stdiostreams. However, if the stdio
+// implementation is the one that is built using this library,
+// then we don't need to, since in that case stdin/stdout/stderr
+// are identical to _IO_stdin/_IO_stdout/_IO_stderr.
+
+#include "libio.h"
+
+#ifdef _STDIO_USES_IOSTREAM
+#define CIN_SBUF _IO_stdin_
+#define COUT_SBUF _IO_stdout_
+#define CERR_SBUF _IO_stderr_
+static int use_stdiobuf = 0;
+#else
+#define CIN_SBUF _IO_stdin_buf
+#define COUT_SBUF _IO_stdout_buf
+#define CERR_SBUF _IO_stderr_buf
+static int use_stdiobuf = 1;
+#endif
+
+#define cin CIN
+#define cout COUT
+#define cerr CERR
+#define clog CLOG
+#include "iostream.h"
+#undef cin
+#undef cout
+#undef cerr
+#undef clog
+
+#ifdef __GNUG__
+#define PAD 0 /* g++ allows 0-length arrays. */
+#else
+#define PAD 1
+#endif
+struct _fake_istream {
+ struct myfields {
+#ifdef __GNUC__
+ _ios_fields *vb; /* pointer to virtual base class ios */
+ _IO_ssize_t _gcount;
+#else
+ /* This is supposedly correct for cfront. */
+ _IO_ssize_t _gcount;
+ void *vptr;
+ _ios_fields *vb; /* pointer to virtual base class ios */
+#endif
+ } mine;
+ _ios_fields base;
+ char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD];
+};
+struct _fake_ostream {
+ struct myfields {
+#ifndef __GNUC__
+ void *vptr;
+#endif
+ _ios_fields *vb; /* pointer to virtual base class ios */
+ } mine;
+ _ios_fields base;
+ char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD];
+};
+
+
+#ifdef _IO_NEW_STREAMS
+#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
+ (streambuf*)&SBUF, TIE, 0, ios::skipws|ios::dec|EXTRA_FLAGS, ' ',0,0,6
+#else
+#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
+ (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::dec|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
+#endif
+
+#ifdef __GNUC__
+#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
+ _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 00000000000..db57bb47643
--- /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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <stdarg.h>
+#include "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/stream.h b/gnu/lib/libg++/libio/stream.h
new file mode 100644
index 00000000000..2a791dffebe
--- /dev/null
+++ b/gnu/lib/libg++/libio/stream.h
@@ -0,0 +1,57 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _COMPAT_STREAM_H
+#define _COMPAT_STREAM_H
+
+// Compatibility with old library.
+
+#define _STREAM_COMPAT
+#include <iostream.h>
+
+extern "C++" {
+extern char* form(const char*, ...);
+
+extern char* dec(long, int=0);
+extern char* dec(int, int=0);
+extern char* dec(unsigned long, int=0);
+extern char* dec(unsigned int, int=0);
+
+extern char* hex(long, int=0);
+extern char* hex(int, int=0);
+extern char* hex(unsigned long, int=0);
+extern char* hex(unsigned int, int=0);
+
+extern char* oct(long, int=0);
+extern char* oct(int, int=0);
+extern char* oct(unsigned long, int=0);
+extern char* oct(unsigned int, int=0);
+
+char* chr(char ch, int width = 0);
+char* str(const char* s, int width = 0);
+
+inline istream& WS(istream& str) { return ws(str); }
+} // extern "C++"
+
+#endif /* !_COMPAT_STREAM_H */
diff --git a/gnu/lib/libg++/libio/streambuf.cc b/gnu/lib/libg++/libio/streambuf.cc
new file mode 100644
index 00000000000..d66af097aa5
--- /dev/null
+++ b/gnu/lib/libg++/libio/streambuf.cc
@@ -0,0 +1,343 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#define _STREAM_COMPAT
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "iostreamP.h"
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+void streambuf::_un_link() { _IO_un_link(this); }
+
+void streambuf::_link_in() { _IO_link_in(this); }
+
+int streambuf::switch_to_get_mode()
+{ return _IO_switch_to_get_mode(this); }
+
+void streambuf::free_backup_area()
+{ _IO_free_backup_area(this); }
+
+#if 0
+int streambuf::switch_to_put_mode()
+{ return _IO_:switch_to_put_mode(this); }
+#endif
+
+int __overflow(streambuf* sb, int c)
+{
+ return sb->overflow(c);
+}
+
+int streambuf::underflow()
+{ return EOF; }
+
+int streambuf::uflow()
+{ return _IO_default_uflow (this); }
+
+int streambuf::overflow(int /* = EOF */)
+{ return EOF; }
+
+streamsize streambuf::xsputn(register const char* s, streamsize n)
+{ return _IO_default_xsputn(this, s, n); }
+
+streamsize streambuf::xsgetn(char* s, streamsize n)
+{ return _IO_default_xsgetn(this, s, n); }
+
+int streambuf::ignore(int n)
+{
+ register int more = n;
+ for (;;) {
+ int count = _IO_read_end - _IO_read_ptr; // Data available.
+ if (count > 0) {
+ if (count > more)
+ count = more;
+ _IO_read_ptr += count;
+ more -= count;
+ }
+ if (more == 0 || __underflow(this) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+int streambuf::sync()
+{
+ return 0;
+}
+
+int streambuf::pbackfail(int c)
+{
+ return _IO_default_pbackfail(this, c);
+}
+
+streambuf* streambuf::setbuf(char* p, int len)
+{
+ if (sync() == EOF)
+ return NULL;
+ if (p == NULL || len == 0) {
+ unbuffered(1);
+ setb(_shortbuf, _shortbuf+1, 0);
+ }
+ else {
+ unbuffered(0);
+ setb(p, p+len, 0);
+ }
+ setp(0, 0);
+ setg(0, 0, 0);
+ return this;
+}
+
+streampos streambuf::seekpos(streampos pos, int mode)
+{
+ return seekoff(pos, ios::beg, mode);
+}
+
+streampos streambuf::sseekpos(streampos pos, int mode)
+{
+ return _IO_seekpos (this, pos, mode);
+}
+
+void streambuf::setb(char* b, char* eb, int a)
+{ _IO_setb(this, b, eb, a); }
+
+int streambuf::doallocate() { return _IO_default_doallocate(this); }
+
+void streambuf::doallocbuf() { _IO_doallocbuf(this); }
+
+#if !_IO_UNIFIED_JUMPTABLES
+/* The following are jump table entries that just call the virtual method */
+
+static int _IO_sb_overflow(_IO_FILE *fp, int c)
+{ return ((streambuf*)fp)->overflow(c); }
+static int _IO_sb_underflow(_IO_FILE *fp)
+{ return ((streambuf*)fp)->underflow(); }
+static _IO_size_t _IO_sb_xsputn(_IO_FILE *fp, const void *s, _IO_size_t n)
+{ return ((streambuf*)fp)->xsputn((const char*)s, n); }
+static _IO_size_t _IO_sb_xsgetn(_IO_FILE *fp, void *s, _IO_size_t n)
+{ return ((streambuf*)fp)->xsgetn((char*)s, n); }
+static int _IO_sb_close(_IO_FILE *fp)
+{ return ((streambuf*)fp)->sys_close(); }
+static int _IO_sb_stat(_IO_FILE *fp, void *b)
+{ return ((streambuf*)fp)->sys_stat(b); }
+static int _IO_sb_doallocate(_IO_FILE *fp)
+{ return ((streambuf*)fp)->doallocate(); }
+
+static _IO_pos_t _IO_sb_seekoff(_IO_FILE *fp, _IO_off_t pos, int dir, int mode)
+{
+ return ((streambuf*)fp)->seekoff(pos, (ios::seek_dir)dir, mode);
+}
+
+static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, int mode)
+{
+ return ((streambuf*)fp)->seekpos(pos, mode);
+}
+
+static int _IO_sb_pbackfail(_IO_FILE *fp, int ch)
+{ return ((streambuf*)fp)->pbackfail(ch); }
+static void _IO_sb_finish(_IO_FILE *fp)
+{ ((streambuf*)fp)->~streambuf(); }
+static _IO_ssize_t _IO_sb_read(_IO_FILE *fp, void *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->sys_read((char*)buf, n); }
+static _IO_ssize_t _IO_sb_write(_IO_FILE *fp, const void *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->sys_write((const char*)buf, n); }
+static int _IO_sb_sync(_IO_FILE *fp)
+{ return ((streambuf*)fp)->sync(); }
+static _IO_pos_t _IO_sb_seek(_IO_FILE *fp, _IO_off_t off, int dir)
+{ return ((streambuf*)fp)->sys_seek(off, (_seek_dir)dir); }
+static _IO_FILE* _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->setbuf(buf, n); }
+
+/* This callbacks in this jumptable just call the corresponding
+ virtual function, so that C functions can access (potentially user-defined)
+ streambuf-derived objects.
+ Contrast the builtinbuf class, which does the converse: Allow
+ C++ virtual calls to to be used on _IO_FILE objects that are builtin
+ (or defined by C code). */
+
+
+struct _IO_jump_t _IO_streambuf_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_sb_finish),
+ JUMP_INIT(overflow, _IO_sb_overflow),
+ JUMP_INIT(underflow, _IO_sb_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_sb_pbackfail),
+ JUMP_INIT(xsputn, _IO_sb_xsputn),
+ JUMP_INIT(xsgetn, _IO_sb_xsgetn),
+ JUMP_INIT(seekoff, _IO_sb_seekoff),
+ JUMP_INIT(seekpos, _IO_sb_seekpos),
+ JUMP_INIT(setbuf, _IO_sb_setbuf),
+ JUMP_INIT(sync, _IO_sb_sync),
+ JUMP_INIT(doallocate, _IO_sb_doallocate),
+ JUMP_INIT(read, _IO_sb_read),
+ JUMP_INIT(write, _IO_sb_write),
+ JUMP_INIT(seek, _IO_sb_seek),
+ JUMP_INIT(close, _IO_sb_close),
+ JUMP_INIT(stat, _IO_sb_stat)
+};
+#endif
+
+streambuf::streambuf(int flags)
+{
+ _IO_init(this, flags);
+#if !_IO_UNIFIED_JUMPTABLES
+ _jumps = &_IO_streambuf_jumps;
+#endif
+}
+
+streambuf::~streambuf() { _IO_default_finish(this); }
+
+streampos
+streambuf::seekoff(streamoff, _seek_dir, int /*=ios::in|ios::out*/)
+{
+ return EOF;
+}
+
+streampos
+streambuf::sseekoff(streamoff o , _seek_dir d, int m /*=ios::in|ios::out*/)
+{
+ return _IO_seekoff (this, o, d, m);
+}
+
+int streambuf::sputbackc(char c)
+{
+ return _IO_sputbackc(this, c);
+}
+
+int streambuf::sungetc()
+{
+ return _IO_sungetc(this);
+}
+
+#if 0 /* Work in progress */
+void streambuf::collumn(int c)
+{
+ if (c == -1)
+ _collumn = -1;
+ else
+ _collumn = c - (_IO_write_ptr - _IO_write_base);
+}
+#endif
+
+
+int streambuf::get_column()
+{
+ if (_cur_column)
+ return _IO_adjust_column(_cur_column - 1, pbase(), pptr() - pbase());
+ return -1;
+}
+
+int streambuf::set_column(int i)
+{
+ _cur_column = i+1;
+ return 0;
+}
+
+int streambuf::flush_all() { return _IO_flush_all (); }
+
+void streambuf::flush_all_linebuffered()
+{ _IO_flush_all_linebuffered(); }
+
+int streambuf::sys_stat(void *)
+{
+#ifdef EIO
+ errno = EIO;
+#endif
+ return -1;
+}
+
+streamsize streambuf::sys_read(char* /*buf*/, streamsize /*size*/)
+{
+ return 0;
+}
+
+streamsize streambuf::sys_write(const char* /*buf*/, streamsize /*size*/)
+{
+ return 0;
+}
+
+streampos streambuf::sys_seek(streamoff, _seek_dir)
+{
+ return EOF;
+}
+
+int streambuf::sys_close() { return 0; /* Suceess; do nothing */ }
+
+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/streambuf.h b/gnu/lib/libg++/libio/streambuf.h
new file mode 100644
index 00000000000..9eab279759c
--- /dev/null
+++ b/gnu/lib/libg++/libio/streambuf.h
@@ -0,0 +1,473 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifndef _STREAMBUF_H
+#define _STREAMBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* #define _G_IO_THROW */ /* Not implemented: ios::failure */
+
+#define _IO_NEW_STREAMS // new optimizated stream representation
+
+extern "C" {
+#include <libio.h>
+}
+//#include <_G_config.h>
+#ifdef _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
+
+extern "C++" {
+class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */
+class ostream; class streambuf;
+
+// In case some header files defines these as macros.
+#undef open
+#undef close
+
+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.
+ streambuf *_strbuf;
+ ostream* _tie;
+ int _width;
+ __fmtflags _flags;
+ _IO_wchar_t _fill;
+ __iostate _state;
+ __iostate _exceptions;
+ int _precision;
+
+ void *_arrays; /* Support for ios::iword and ios::pword. */
+};
+
+#define _IOS_GOOD 0
+#define _IOS_EOF 1
+#define _IOS_FAIL 2
+#define _IOS_BAD 4
+
+#define _IO_INPUT 1
+#define _IO_OUTPUT 2
+#define _IO_ATEND 4
+#define _IO_APPEND 8
+#define _IO_TRUNC 16
+#define _IO_NOCREATE 32
+#define _IO_NOREPLACE 64
+#define _IO_BIN 128
+
+#ifdef _STREAM_COMPAT
+enum state_value {
+ _good = _IOS_GOOD,
+ _eof = _IOS_EOF,
+ _fail = _IOS_FAIL,
+ _bad = _IOS_BAD };
+enum open_mode {
+ input = _IO_INPUT,
+ output = _IO_OUTPUT,
+ atend = _IO_ATEND,
+ append = _IO_APPEND };
+#endif
+
+class ios : public _ios_fields {
+ ios& operator=(ios&); /* Not allowed! */
+ 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
+#ifndef _IO_NEW_STREAMS
+ , dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction
+#endif
+ };
+ enum { // Masks.
+ basefield=dec+oct+hex,
+ floatfield = scientific+fixed,
+ adjustfield = left+right+internal
+ };
+
+#ifdef _IO_THROW
+ class failure : public xmsg {
+ ios* _stream;
+ public:
+ failure(ios* stream) { _stream = stream; }
+ failure(string cause, ios* stream) { _stream = stream; }
+ ios* rdios() const { return _stream; }
+ };
+#endif
+
+ ostream* tie() const { return _tie; }
+ ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
+
+ // Methods to change the format state.
+ _IO_wchar_t fill() const { return (_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
+ void clear(iostate state = 0) {
+ _state = _strbuf ? state : state|badbit;
+ if (_state & _exceptions) _throw_failure(); }
+ void set(iostate flag) { _state |= flag;
+ if (_state & _exceptions) _throw_failure(); }
+ void setstate(iostate flag) { _state |= flag; // ANSI
+ if (_state & _exceptions) _throw_failure(); }
+ int good() const { return _state == 0; }
+ int eof() const { return _state & ios::eofbit; }
+ int fail() const { return _state & (ios::badbit|ios::failbit); }
+ int bad() const { return _state & ios::badbit; }
+ iostate rdstate() const { return _state; }
+ operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
+ int operator!() const { return fail(); }
+ iostate exceptions() const { return _exceptions; }
+ void exceptions(iostate enable) {
+ _exceptions = enable;
+ if (_state & _exceptions) _throw_failure(); }
+
+ streambuf* rdbuf() const { return _strbuf; }
+ streambuf* rdbuf(streambuf *_s) {
+ streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; }
+
+ static int sync_with_stdio(int on);
+ static void sync_with_stdio() { sync_with_stdio(1); }
+ static fmtflags bitalloc();
+ static int xalloc();
+ void*& pword(int);
+ void* pword(int) const;
+ long& iword(int);
+ long iword(int) const;
+
+#ifdef _STREAM_COMPAT
+ void unset(state_value flag) { _state &= ~flag; }
+ void close();
+ int is_open();
+ int readable();
+ int writable();
+#endif
+
+ // Used to initialize standard streams. Not needed in this implementation.
+ class Init {
+ public:
+ Init () { }
+ };
+
+ protected:
+ inline ios(streambuf* sb = 0, ostream* tie_to = 0);
+ inline virtual ~ios();
+ inline void init(streambuf* sb, ostream* tie = 0);
+};
+
+#if __GNUG__==1
+typedef int _seek_dir;
+#else
+typedef ios::seek_dir _seek_dir;
+#endif
+
+// Magic numbers and bits for the _flags field.
+// The magic numbers use the high-order bits of _flags;
+// the remaining bits are abailable for variable flags.
+// Note: The magic numbers must all be negative if stdio
+// emulation is desired.
+
+// A streammarker remembers a position in a buffer.
+// You are guaranteed to be able to seek back to it if it is saving().
+class streammarker : private _IO_marker {
+ friend class streambuf;
+ void set_offset(int offset) { _pos = offset; }
+ public:
+ streammarker(streambuf *sb);
+ ~streammarker();
+ int saving() { return 1; }
+ int delta(streammarker&);
+ int delta();
+};
+
+struct streambuf : public _IO_FILE { // protected??
+ friend class ios;
+ friend class istream;
+ friend class ostream;
+ friend class streammarker;
+ const void *&_vtable() { return *(const void**)((_IO_FILE*)this + 1); }
+ protected:
+ static streambuf* _list_all; /* List of open streambufs. */
+ _IO_FILE*& xchain() { return _chain; }
+ void _un_link();
+ void _link_in();
+ char* gptr() const
+ { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_ptr; }
+ char* pptr() const { return _IO_write_ptr; }
+ char* egptr() const
+ { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_end : _IO_read_end; }
+ char* epptr() const { return _IO_write_end; }
+ char* pbase() const { return _IO_write_base; }
+ char* eback() const
+ { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_base;}
+ char* base() const { return _IO_buf_base; }
+ char* ebuf() const { return _IO_buf_end; }
+ int blen() const { return _IO_buf_end - _IO_buf_base; }
+ void xput_char(char c) { *_IO_write_ptr++ = c; }
+ int xflags() { return _IO_file_flags; }
+ int xflags(int f) {int fl = _IO_file_flags; _IO_file_flags = f; return fl;}
+ void xsetflags(int f) { _IO_file_flags |= f; }
+ void xsetflags(int f, int mask)
+ { _IO_file_flags = (_IO_file_flags & ~mask) | (f & mask); }
+ void gbump(int n)
+ { _IO_file_flags & _IO_IN_BACKUP ? (_IO_save_base+=n):(_IO_read_ptr+=n);}
+ void pbump(int n) { _IO_write_ptr += n; }
+ void setb(char* b, char* eb, int a=0);
+ void setp(char* p, char* ep)
+ { _IO_write_base=_IO_write_ptr=p; _IO_write_end=ep; }
+ void setg(char* eb, char* g, char *eg) {
+ if (_IO_file_flags & _IO_IN_BACKUP) _IO_free_backup_area(this);
+ _IO_read_base = eb; _IO_read_ptr = g; _IO_read_end = eg; }
+ char *shortbuf() { return _shortbuf; }
+
+ int in_backup() { return _flags & _IO_IN_BACKUP; }
+ // The start of the main get area: FIXME: wrong for write-mode filebuf?
+ char *Gbase() { return in_backup() ? _IO_save_base : _IO_read_base; }
+ // The end of the main get area:
+ char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; }
+ // The start of the backup area:
+ char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; }
+ char *Bptr() { return _IO_backup_base; }
+ // The end of the backup area:
+ char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; }
+ char *Nbase() { return _IO_save_base; }
+ char *eNptr() { return _IO_save_end; }
+ int have_backup() { return _IO_save_base != NULL; }
+ int have_markers() { return _markers != NULL; }
+ void free_backup_area();
+ void unsave_markers(); // Make all streammarkers !saving().
+ int put_mode() { return _flags & _IO_CURRENTLY_PUTTING; }
+ int switch_to_get_mode();
+
+ streambuf(int flags=0);
+ public:
+ static int flush_all();
+ static void flush_all_linebuffered(); // Flush all line buffered files.
+ virtual ~streambuf();
+ virtual int overflow(int c = EOF); // Leave public for now
+ virtual int underflow(); // Leave public for now
+ virtual int uflow(); // Leave public for now
+ virtual int pbackfail(int c);
+// virtual int showmany ();
+ virtual streamsize xsputn(const char* s, streamsize n);
+ virtual streamsize xsgetn(char* s, streamsize n);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+
+ streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out)
+ { return _IO_seekoff (this, o, d, mode); }
+ streampos pubseekpos(streampos pos, int mode = ios::in|ios::out)
+ { return _IO_seekpos (this, pos, mode); }
+ streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ streampos sseekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual streambuf* setbuf(char* p, int len);
+ virtual int sync();
+ virtual int doallocate();
+
+ int seekmark(streammarker& mark, int delta = 0);
+ int sputbackc(char c);
+ int sungetc();
+ int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; }
+ int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; }
+ void unbuffered(int i)
+ { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; }
+ void linebuffered(int i)
+ { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; }
+ int allocate() { // For AT&T compatibility
+ if (base() || unbuffered()) return 0;
+ else return doallocate(); }
+ // Allocate a buffer if needed; use _shortbuf if appropriate.
+ void allocbuf() { if (base() == NULL) doallocbuf(); }
+ void doallocbuf();
+ int in_avail() { return _IO_read_end - _IO_read_ptr; }
+ int out_waiting() { return _IO_write_ptr - _IO_write_base; }
+ streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); }
+ streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); }
+ streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); }
+ int ignore(int);
+ int get_column();
+ int set_column(int);
+ long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim);
+ int sputc(int c) { return _IO_putc(c, this); }
+ int sbumpc() { return _IO_getc(this); }
+ int sgetc() { return _IO_peekc(this); }
+ int snextc() {
+ if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF)
+ return EOF;
+ else return _IO_read_ptr++, sgetc(); }
+ void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; }
+ int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL);
+ int scan(char const *fmt0 ...);
+ int vform(char const *fmt0, _IO_va_list ap);
+ int form(char const *fmt0 ...);
+#if 0 /* Work in progress */
+ int column(); // Current column number (of put pointer). -1 is unknown.
+ void column(int c); // Set column number of put pointer to c.
+#endif
+ virtual streamsize sys_read(char* buf, streamsize size);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual int sys_close();
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+};
+
+// A backupbuf is a streambuf with full backup and savepoints on reading.
+// All standard streambufs in the GNU iostream library are backupbufs.
+
+class filebuf : public streambuf {
+ protected:
+ void init();
+ public:
+ static const int openprot; // Non-ANSI AT&T-ism: Default open protection.
+ filebuf();
+ filebuf(int fd);
+ filebuf(int fd, char* p, int len);
+#if !_IO_UNIFIED_JUMPTABLES
+ static filebuf *__new();
+#endif
+ ~filebuf();
+ filebuf* attach(int fd);
+ filebuf* open(const char *filename, const char *mode);
+ filebuf* open(const char *filename, ios::openmode mode, int prot = 0664);
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ int is_open() const { return _fileno >= 0; }
+ int fd() const { return is_open() ? _fileno : EOF; }
+ filebuf* close();
+ virtual int doallocate();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streambuf* setbuf(char* p, int len);
+ streamsize xsputn(const char* s, streamsize n);
+ streamsize xsgetn(char* s, streamsize n);
+ virtual int sync();
+ protected: // See documentation in filebuf.C.
+// virtual int pbackfail(int c);
+ int is_reading() { return eback() != egptr(); }
+ char* cur_ptr() { return is_reading() ? gptr() : pptr(); }
+ /* System's idea of pointer */
+ char* file_ptr() { return eGptr(); }
+ // Low-level operations (Usually invoke system calls.)
+ virtual streamsize sys_read(char* buf, streamsize size);
+ virtual streampos sys_seek(streamoff, _seek_dir);
+ virtual streamsize sys_write(const char*, streamsize);
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+ virtual int sys_close();
+#if 0
+ virtual uflow;
+ virtual showmany;
+#endif
+};
+
+inline void ios::init(streambuf* sb, ostream* tie_to) {
+ _state = sb ? ios::goodbit : ios::badbit; _exceptions=0;
+ _strbuf=sb; _tie = tie_to; _width=0; _fill=' ';
+#ifdef _IO_NEW_STREAMS
+ _flags=ios::skipws|ios::dec;
+#else
+ _flags=ios::skipws|ios::dec|ios::dont_close;
+#endif
+ _precision=6; _arrays = 0; }
+
+inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); }
+
+inline ios::~ios() {
+#ifndef _IO_NEW_STREAMS
+ if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf();
+#endif
+ if (_arrays) delete [] _arrays;
+}
+} // extern "C++"
+#endif /* _STREAMBUF_H */
diff --git a/gnu/lib/libg++/libio/strfile.h b/gnu/lib/libg++/libio/strfile.h
new file mode 100644
index 00000000000..55783bb5c1c
--- /dev/null
+++ b/gnu/lib/libg++/libio/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 this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <libio.h>
+#ifdef TODO
+Merge into libio.h ?
+#endif
+
+typedef void *(*_IO_alloc_type) __P((_IO_size_t));
+typedef void (*_IO_free_type) __P((void*));
+
+struct _IO_str_fields
+{
+ /* 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++/libio/strops.c b/gnu/lib/libg++/libio/strops.c
new file mode 100644
index 00000000000..f4f45259fb3
--- /dev/null
+++ b/gnu/lib/libg++/libio/strops.c
@@ -0,0 +1,285 @@
+/*
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "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
+DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
+ _IO_FILE *fp AND char *ptr AND int size AND 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
+DEFUN(_IO_str_init_readonly, (fp, ptr, size),
+ _IO_FILE *fp AND const char *ptr AND int size)
+{
+ _IO_str_init_static (fp, (char*)ptr, size, NULL);
+ fp->_IO_file_flags |= _IO_NO_WRITES;
+}
+
+int
+DEFUN(_IO_str_overflow, (fp, c),
+ register _IO_FILE* fp AND 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
+DEFUN(_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
+DEFUN(_IO_str_count, (fp),
+ register _IO_FILE *fp)
+{
+ _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (put_len < LEN(fp))
+ put_len = LEN(fp);
+ return put_len;
+}
+
+_IO_pos_t
+DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
+ register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
+{
+ _IO_ssize_t cur_size = _IO_str_count(fp);
+ _IO_pos_t new_pos = EOF;
+
+ /* Move the get pointer, if requested. */
+ if (mode & _IOS_INPUT)
+ {
+ switch (dir)
+ {
+ case _IO_seek_end:
+ offset += cur_size;
+ break;
+ case _IO_seek_cur:
+ offset += fp->_IO_read_ptr - fp->_IO_read_base;
+ break;
+ default: /* case _IO_seek_set: */
+ break;
+ }
+ if (offset < 0 || (_IO_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 & _IOS_OUTPUT)
+ {
+ switch (dir)
+ {
+ case _IO_seek_end:
+ offset += cur_size;
+ break;
+ case _IO_seek_cur:
+ offset += fp->_IO_write_ptr - fp->_IO_write_base;
+ break;
+ default: /* case _IO_seek_set: */
+ break;
+ }
+ if (offset < 0 || (_IO_size_t)offset > cur_size)
+ return EOF;
+ LEN(fp) = cur_size;
+ fp->_IO_write_ptr = fp->_IO_write_base + offset;
+ new_pos = offset;
+ }
+ return new_pos;
+}
+
+int
+DEFUN(_IO_str_pbackfail, (fp, c),
+ register _IO_FILE *fp AND int c)
+{
+ if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
+ return EOF;
+ return _IO_default_pbackfail(fp, c);
+}
+
+void
+DEFUN (_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 = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_str_finish),
+ JUMP_INIT(overflow, _IO_str_overflow),
+ JUMP_INIT(underflow, _IO_str_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_str_pbackfail),
+ JUMP_INIT(xsputn, _IO_default_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_str_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_default_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_default_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat)
+};
diff --git a/gnu/lib/libg++/libio/strstream.cc b/gnu/lib/libg++/libio/strstream.cc
new file mode 100644
index 00000000000..3e1d5a6bfa6
--- /dev/null
+++ b/gnu/lib/libg++/libio/strstream.cc
@@ -0,0 +1,168 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "iostreamP.h"
+#include "strstream.h"
+#include <string.h>
+
+static void* default_alloc(_IO_size_t size)
+{
+ return (void*)new char[size];
+}
+
+static void default_free(void* ptr)
+{
+ delete [] (char*)ptr;
+}
+
+#if _IO_UNIFIED_JUMPTABLES
+#define SET_STR_JUMPS(STRBUF) /* Nothing */
+#else
+/* Set to use the _IO_str_jump jumptable, for efficiency */
+
+#define SET_STR_JUMPS(STRBUF) \
+ (STRBUF)->_jumps = &_IO_str_jumps,\
+ (STRBUF)->_vtable() = builtinbuf_vtable;
+#endif
+
+istrstream::istrstream(const char *cp, int n)
+{
+#ifdef _IO_NEW_STREAMS
+ __my_sb.init_readonly (cp, n);
+ init (&__my_sb);
+#else
+ init(new strstreambuf(cp, n));
+ _flags &= ~ios::dont_close;
+#endif
+ SET_STR_JUMPS(_strbuf);
+}
+
+ostrstream::ostrstream()
+{
+#ifdef _IO_NEW_STREAMS
+ init (&__my_sb);
+#else
+ init(new strstreambuf());
+ _flags &= ~ios::dont_close;
+#endif
+ SET_STR_JUMPS(_strbuf);
+}
+
+strstream::strstream()
+{
+#ifdef _IO_NEW_STREAMS
+ init (&__my_sb);
+#else
+ init(new strstreambuf());
+ _flags &= ~ios::dont_close;
+#endif
+ SET_STR_JUMPS(_strbuf);
+}
+
+strstreambase::strstreambase(char *cp, int n, int mode)
+#ifdef _IO_NEW_STREAMS
+: __my_sb (cp, n,
+ (mode == ios::app || mode == ios::ate) ? cp + strlen(cp) : cp)
+#endif
+{
+#ifdef _IO_NEW_STREAMS
+ init (&__my_sb);
+#else
+ char *pstart;
+ if (mode == ios::app || mode == ios::ate)
+ pstart = cp + strlen(cp);
+ else
+ pstart = cp;
+ init(new strstreambuf(cp, n, pstart));
+ _flags &= ~ios::dont_close;
+#endif
+ SET_STR_JUMPS(_strbuf);
+}
+
+char *strstreambuf::str()
+{
+ freeze(1);
+ return base();
+}
+
+_IO_ssize_t strstreambuf::pcount () { return _IO_write_ptr - _IO_write_base; }
+
+int strstreambuf::overflow(int c /* = EOF */)
+{
+ return _IO_str_overflow (this, c);
+}
+
+int strstreambuf::underflow()
+{
+ return _IO_str_underflow(this);
+}
+
+
+void strstreambuf::init_dynamic(_IO_alloc_type alloc, _IO_free_type free,
+ int initial_size)
+
+{
+ _s._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, dir, mode);
+}
+
+int strstreambuf::pbackfail(int c)
+{
+ return _IO_str_pbackfail (this, c);
+}
diff --git a/gnu/lib/libg++/libio/strstream.h b/gnu/lib/libg++/libio/strstream.h
new file mode 100644
index 00000000000..86a8a687587
--- /dev/null
+++ b/gnu/lib/libg++/libio/strstream.h
@@ -0,0 +1,123 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1993 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#ifndef __STRSTREAM_H
+#define __STRSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <iostream.h>
+#include <strfile.h>
+
+extern "C++" {
+class strstreambuf : public streambuf
+{
+ struct _IO_str_fields _s;
+ friend class istrstream;
+
+ void init_dynamic(_IO_alloc_type alloc, _IO_free_type free,
+ int initial_size = 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 {
+#ifdef _IO_NEW_STREAMS
+ protected:
+ strstreambuf __my_sb;
+#endif
+ public:
+#ifdef _IO_NEW_STREAMS
+ strstreambuf* rdbuf() { return &__my_sb; }
+#else
+ strstreambuf* rdbuf() { return (strstreambuf*)ios::rdbuf(); }
+#endif
+ protected:
+ strstreambase() { }
+#ifdef _IO_NEW_STREAMS
+ strstreambase(char *cp, int n);
+#endif
+ strstreambase(char *cp, int n, int mode=ios::out);
+};
+
+class istrstream : public strstreambase, public istream {
+ public:
+ istrstream(const char*, int=0);
+};
+
+class ostrstream : public strstreambase, public ostream {
+ public:
+ ostrstream();
+ ostrstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
+ _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
+ char *str() { return ((strstreambuf*)_strbuf)->str(); }
+ void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
+ int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
+};
+
+class strstream : public strstreambase, public iostream {
+ public:
+ strstream();
+ strstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
+ _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
+ char *str() { return ((strstreambuf*)_strbuf)->str(); }
+ void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
+ int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
+};
+} // extern "C++"
+
+#endif /*!__STRSTREAM_H*/
diff --git a/gnu/lib/libg++/libiostream/Makefile b/gnu/lib/libg++/libiostream/Makefile
new file mode 100644
index 00000000000..27773fac764
--- /dev/null
+++ b/gnu/lib/libg++/libiostream/Makefile
@@ -0,0 +1,22 @@
+# $NetBSD: Makefile,v 1.1.1.1 1996/03/09 00:01:31 phil Exp $
+
+LIB= iostream
+
+SRCS= PlotFile.cc SFile.cc builtinbuf.cc editbuf.cc filebuf.cc fstream.cc \
+indstream.cc ioassign.cc ioextend.cc iomanip.cc iostream.cc isgetline.cc \
+isgetsb.cc isscan.cc osform.cc parsestream.cc pfstream.cc procbuf.cc \
+sbform.cc sbgetline.cc sbscan.cc stdiostream.cc stdstrbufs.cc stdstreams.cc \
+stream.cc streambuf.cc strstream.cc cleanup.c filedoalloc.c fileops.c \
+floatconv.c genops.c iofclose.c iofgetpos.c iofread.c iofscanf.c \
+iofsetpos.c iogetdelim.c iogetline.c ioignore.c iopadn.c iopopen.c \
+ioprims.c ioprintf.c ioseekoff.c ioseekpos.c iostrerror.c ioungetc.c \
+iovfprintf.c iovfscanf.c outfloat.c strops.c
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../include \
+ -I$(.CURDIR)/../libio
+CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../libio
+NOMAN= noman
+
+.PATH: $(.CURDIR)/../libio
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libg++/libiostream/shlib_version b/gnu/lib/libg++/libiostream/shlib_version
new file mode 100644
index 00000000000..97c9f92d6b8
--- /dev/null
+++ b/gnu/lib/libg++/libiostream/shlib_version
@@ -0,0 +1,2 @@
+major=0
+minor=0
diff --git a/gnu/lib/libg++/libstdc++/Makefile b/gnu/lib/libg++/libstdc++/Makefile
new file mode 100644
index 00000000000..2c3469be291
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/Makefile
@@ -0,0 +1,134 @@
+# $NetBSD: Makefile,v 1.1.1.1 1996/03/09 00:01:40 phil Exp $
+
+LIB= stdc++
+
+SRCS= PlotFile.cc SFile.cc builtinbuf.cc editbuf.cc filebuf.cc fstream.cc \
+indstream.cc ioassign.cc ioextend.cc iomanip.cc iostream.cc isgetline.cc \
+isgetsb.cc isscan.cc osform.cc parsestream.cc pfstream.cc procbuf.cc \
+sbform.cc sbgetline.cc sbscan.cc stdiostream.cc stdstrbufs.cc stdstreams.cc \
+stream.cc streambuf.cc strstream.cc cleanup.c filedoalloc.c fileops.c \
+floatconv.c genops.c iofclose.c iofgetpos.c iofread.c iofscanf.c \
+iofsetpos.c iogetdelim.c iogetline.c ioignore.c iopadn.c iopopen.c \
+ioprims.c ioprintf.c ioseekoff.c ioseekpos.c iostrerror.c ioungetc.c \
+iovfprintf.c iovfscanf.c outfloat.c strops.c cmathi.cc cstdlibi.cc \
+cstringi.cc exceptioni.cc newi.cc stddefi.cc stdexcepti.cc typeinfoi.cc \
+cstrmain.cc cstrio.cc fcomplex.cc fcomio.cc dcomplex.cc dcomio.cc \
+ldcomplex.cc ldcomio.cc random.cc tempbuf.cc tree.cc
+
+CXXFLAGS+= -nostdinc++
+CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../libio -I$(.CURDIR)/stl
+NOMAN= noman
+
+.PATH: $(.CURDIR)/../libio $(.CURDIR)/stl
+
+.include <bsd.lib.mk>
+
+cstrmain.cc: Makefile
+ @echo Creating cstrmain.cc
+ @(for i in REP MAIN TRAITS ADDSS ADDPS ADDCS ADDSP ADDSC EQSS EQPS EQSP NESS NEPS NESP LTSS LTPS LTSP GTSS GTPS GTSP LESS LEPS LESP GESS GEPS GESP ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define C';\
+ cat $(.CURDIR)/sinst.cc) > $(.TARGET)
+CLEANFILES+=cstrmain.cc
+
+cstrio.cc: Makefile
+ @echo Creating cstrio.cc
+ @(for i in EXTRACT INSERT GETLINE ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define C';\
+ cat $(.CURDIR)/sinst.cc) > $(.TARGET)
+CLEANFILES+=cstrio.cc
+
+fcomplex.cc: Makefile
+ @echo Creating fcomplex.cc
+ @(for i in MAIN ADDCC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC DIVCF DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR CONJ NORM COS COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define F';\
+ cat $(.CURDIR)/cinst.cc) > $(.TARGET)
+CLEANFILES+=fcomplex.cc
+
+fcomio.cc: Makefile
+ @echo Creating fcomio.cc
+ @(for i in EXTRACT INSERT ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define F';\
+ cat $(.CURDIR)/cinst.cc) > $(.TARGET)
+CLEANFILES+=fcomio.cc
+
+dcomplex.cc: Makefile
+ @echo Creating dcomplex.cc
+ @(for i in MAIN ADDCC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC DIVCF DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR CONJ NORM COS COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define D';\
+ cat $(.CURDIR)/cinst.cc) > $(.TARGET)
+CLEANFILES+=dcomplex.cc
+
+dcomio.cc: Makefile
+ @echo Creating dcomio.cc
+ @(for i in EXTRACT INSERT ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define D';\
+ cat $(.CURDIR)/cinst.cc) > $(.TARGET)
+CLEANFILES+=dcomio.cc
+
+ldcomplex.cc: Makefile
+ @echo Creating ldcomplex.cc
+ @(for i in MAIN ADDCC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC DIVCF DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR CONJ NORM COS COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define LD';\
+ cat $(.CURDIR)/cinst.cc) > $(.TARGET)
+CLEANFILES+=ldcomplex.cc
+
+ldcomio.cc: Makefile
+ @echo Creating ldcomio.cc
+ @(for i in EXTRACT INSERT ; do \
+ echo "#define $$i"; \
+ done;\
+ echo '#define LD';\
+ cat $(.CURDIR)/cinst.cc) > $(.TARGET)
+CLEANFILES+=ldcomio.cc
+
+typeinfoi.o: typeinfoi.cc
+ @echo "$(COMPILE.cc) -frtti $(.ALLSRC)"
+ @$(COMPILE.cc) -frtti $(.ALLSRC) -o $(.TARGET).o
+ @$(LD) -x -r $(.TARGET).o -o $(.TARGET)
+ @rm -f $(.TARGET).o
+
+typeinfoi.po: typeinfoi.cc
+ @echo "$(COMPILE.cc) -p -frtti $(.ALLSRC) -o $(.TARGET)"
+ @$(COMPILE.cc) -p -frtti $(.ALLSRC) -o $(.TARGET).o
+ @$(LD) -X -r $(.TARGET).o -o $(.TARGET)
+ @rm -f $(.TARGET).o
+
+typeinfoi.so: typeinfoi.cc
+ @echo "$(COMPILE.cc) $(PICFLAG) -frtti $(.ALLSRC) -o $(.TARGET)"
+ @$(COMPILE.cc) $(PICFLAG) -frtti $(.ALLSRC) -o $(.TARGET).o
+ @$(LD) -x -r $(.TARGET).o -o $(.TARGET)
+ @rm -f $(.TARGET).o
+
+stdexcepti.o: stdexcepti.cc
+ @echo "$(COMPILE.cc) -frtti $(.ALLSRC)"
+ @$(COMPILE.cc) -frtti $(.ALLSRC) -o $(.TARGET).o
+ @$(LD) -x -r $(.TARGET).o -o $(.TARGET)
+ @rm -f $(.TARGET).o
+
+stdexcepti.po: stdexcepti.cc
+ @echo "$(COMPILE.cc) -p -frtti $(.ALLSRC) -o $(.TARGET)"
+ @$(COMPILE.cc) -p -frtti $(.ALLSRC) -o $(.TARGET).o
+ @$(LD) -X -r $(.TARGET).o -o $(.TARGET)
+ @rm -f $(.TARGET).o
+
+stdexcepti.so: stdexcepti.cc
+ @echo "$(COMPILE.cc) $(PICFLAG) -frtti $(.ALLSRC) -o $(.TARGET)"
+ @$(COMPILE.cc) $(PICFLAG) -frtti $(.ALLSRC) -o $(.TARGET).o
+ @$(LD) -x -r $(.TARGET).o -o $(.TARGET)
+ @rm -f $(.TARGET).o
+
+
diff --git a/gnu/lib/libg++/libstdc++/algorithm b/gnu/lib/libg++/libstdc++/algorithm
new file mode 100644
index 00000000000..472d2416640
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/algorithm
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __ALGORITHM__
+#define __ALGORITHM__
+#include <algo.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cassert b/gnu/lib/libg++/libstdc++/cassert
new file mode 100644
index 00000000000..848087f1783
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cassert
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CASSERT__
+#include <std/cassert.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cctype b/gnu/lib/libg++/libstdc++/cctype
new file mode 100644
index 00000000000..12d96d75917
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cctype
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CCTYPE__
+#include <std/cctype.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cerrno b/gnu/lib/libg++/libstdc++/cerrno
new file mode 100644
index 00000000000..bbd93f75067
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cerrno
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CERRNO__
+#include <std/cerrno.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cfloat b/gnu/lib/libg++/libstdc++/cfloat
new file mode 100644
index 00000000000..bd7497a9ebd
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cfloat
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CFLOAT__
+#include <std/cfloat.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cinst.cc b/gnu/lib/libg++/libstdc++/cinst.cc
new file mode 100644
index 00000000000..92236c4f8c0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cinst.cc
@@ -0,0 +1,151 @@
+// Instantiation file for the -*- C++ -*- complex number classes.
+// Copyright (C) 1994 Free Software Foundation
+
+#ifdef F
+typedef float f;
+#endif
+#ifdef D
+typedef double f;
+#endif
+#ifdef LD
+typedef long double f;
+#endif
+
+#if defined (MAIN) && defined (__GNUG__)
+#ifdef F
+#pragma implementation "fcomplex"
+#endif
+#ifdef D
+#pragma implementation "dcomplex"
+#endif
+#ifdef LD
+#pragma implementation "ldcomplex"
+#endif
+#endif
+
+#if 0
+#define _G_NO_EXTERN_TEMPLATES
+#endif
+#include <std/complext.cc>
+
+typedef complex<f> c;
+typedef const c& ccr;
+
+#ifdef MAIN
+template class complex<f>;
+#endif
+
+#ifdef ADDCC
+template c operator+ (ccr, ccr);
+#endif
+#ifdef ADDCF
+template c operator+ (ccr, f);
+#endif
+#ifdef ADDFC
+template c operator+ (f, ccr);
+#endif
+#ifdef SUBCC
+template c operator- (ccr, ccr);
+#endif
+#ifdef SUBCF
+template c operator- (ccr, f);
+#endif
+#ifdef SUBFC
+template c operator- (f, ccr);
+#endif
+#ifdef MULCC
+template c operator* (ccr, ccr);
+#endif
+#ifdef MULCF
+template c operator* (ccr, f);
+#endif
+#ifdef MULFC
+template c operator* (f, ccr);
+#endif
+#ifdef DIVCC
+template c operator/ (ccr, ccr);
+#endif
+#ifdef DIVCF
+template c operator/ (ccr, f);
+#endif
+#ifdef DIVFC
+template c operator/ (f, ccr);
+#endif
+#ifdef PLUS
+template c operator+ (ccr);
+#endif
+#ifdef MINUS
+template c operator- (ccr);
+#endif
+#ifdef EQCC
+template bool operator== (ccr, ccr);
+#endif
+#ifdef EQCF
+template bool operator== (ccr, f);
+#endif
+#ifdef EQFC
+template bool operator== (f, ccr);
+#endif
+#ifdef NECC
+template bool operator!= (ccr, ccr);
+#endif
+#ifdef NECF
+template bool operator!= (ccr, f);
+#endif
+#ifdef NEFC
+template bool operator!= (f, ccr);
+#endif
+#ifdef ABS
+template f abs (ccr);
+#endif
+#ifdef ARG
+template f arg (ccr);
+#endif
+#ifdef POLAR
+template c polar (f, f);
+#endif
+#ifdef CONJ
+template c conj (ccr);
+#endif
+#ifdef NORM
+template f norm (ccr);
+#endif
+#ifdef COS
+template c cos (ccr);
+#endif
+#ifdef COSH
+template c cosh (ccr);
+#endif
+#ifdef EXP
+template c exp (ccr);
+#endif
+#ifdef LOG
+template c log (ccr);
+#endif
+#ifdef POWCC
+template c pow (ccr, ccr);
+#endif
+#ifdef POWCF
+template c pow (ccr, f);
+#endif
+#ifdef POWCI
+template c pow (ccr, int);
+#endif
+#ifdef POWFC
+template c pow (f, ccr);
+#endif
+#ifdef SIN
+template c sin (ccr);
+#endif
+#ifdef SINH
+template c sinh (ccr);
+#endif
+#ifdef SQRT
+template c sqrt (ccr);
+#endif
+#ifdef EXTRACT
+template istream& operator>> (istream&, complex<f>&);
+#endif
+#ifdef INSERT
+template ostream& operator<< (ostream&, complex<f>);
+#endif
diff --git a/gnu/lib/libg++/libstdc++/ciso646 b/gnu/lib/libg++/libstdc++/ciso646
new file mode 100644
index 00000000000..51209086695
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/ciso646
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CISO646__
+#include <std/ciso646.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/climits b/gnu/lib/libg++/libstdc++/climits
new file mode 100644
index 00000000000..4b7b81d82e3
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/climits
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CLIMITS__
+#include <std/climits.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/clocale b/gnu/lib/libg++/libstdc++/clocale
new file mode 100644
index 00000000000..9e20a88bfa4
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/clocale
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CLOCALE__
+#include <std/clocale.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cmath b/gnu/lib/libg++/libstdc++/cmath
new file mode 100644
index 00000000000..da5bce9cad3
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cmath
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CMATH__
+#include <std/cmath.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cmathi.cc b/gnu/lib/libg++/libstdc++/cmathi.cc
new file mode 100644
index 00000000000..e9fa0604eb9
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cmathi.cc
@@ -0,0 +1,7 @@
+// Implementation file for the -*- C++ -*- math functions header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifdef __GNUG__
+#pragma implementation "std/cmath.h"
+#endif
+#include <std/cmath.h>
diff --git a/gnu/lib/libg++/libstdc++/complex b/gnu/lib/libg++/libstdc++/complex
new file mode 100644
index 00000000000..17e2fe439bf
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/complex
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __COMPLEX__
+#include <std/complex.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/complex.h b/gnu/lib/libg++/libstdc++/complex.h
new file mode 100644
index 00000000000..554210dcffd
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/complex.h
@@ -0,0 +1,6 @@
+// -*- C++ -*- backward compatiblity header.
+// Copyright (C) 1994 Free Software Foundation
+
+#ifndef __COMPLEX_H__
+#include <std/complex.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/csetjmp b/gnu/lib/libg++/libstdc++/csetjmp
new file mode 100644
index 00000000000..b635d738a4f
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/csetjmp
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSETJMP__
+#include <std/csetjmp.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/csignal b/gnu/lib/libg++/libstdc++/csignal
new file mode 100644
index 00000000000..21ed90cda08
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/csignal
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSIGNAL__
+#include <std/csignal.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cstdarg b/gnu/lib/libg++/libstdc++/cstdarg
new file mode 100644
index 00000000000..c8ca3eabf13
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstdarg
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDARG__
+#include <std/cstdarg.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cstddef b/gnu/lib/libg++/libstdc++/cstddef
new file mode 100644
index 00000000000..18134383bb2
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstddef
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDDEF__
+#include <std/cstddef.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cstdio b/gnu/lib/libg++/libstdc++/cstdio
new file mode 100644
index 00000000000..ac851787b30
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstdio
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDIO__
+#include <std/cstdio.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cstdlib b/gnu/lib/libg++/libstdc++/cstdlib
new file mode 100644
index 00000000000..fa4dac415f5
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstdlib
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDLIB__
+#include <std/cstdlib.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cstdlibi.cc b/gnu/lib/libg++/libstdc++/cstdlibi.cc
new file mode 100644
index 00000000000..bd94aa5dfa3
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstdlibi.cc
@@ -0,0 +1,7 @@
+// Implementation file for the -*- C++ -*- standard library header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifdef __GNUG__
+#pragma implementation "std/cstdlib.h"
+#endif
+#include <std/cstdlib.h>
diff --git a/gnu/lib/libg++/libstdc++/cstring b/gnu/lib/libg++/libstdc++/cstring
new file mode 100644
index 00000000000..e0d18cfaa5e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstring
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTRING__
+#include <std/cstring.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cstringi.cc b/gnu/lib/libg++/libstdc++/cstringi.cc
new file mode 100644
index 00000000000..e981ab73c98
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cstringi.cc
@@ -0,0 +1,7 @@
+// Implementation file for the -*- C++ -*- null-terminated string header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifdef __GNUG__
+#pragma implementation "std/cstring.h"
+#endif
+#include <std/cstring.h>
diff --git a/gnu/lib/libg++/libstdc++/ctime b/gnu/lib/libg++/libstdc++/ctime
new file mode 100644
index 00000000000..8b68715ac44
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/ctime
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CTIME__
+#include <std/ctime.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cwchar b/gnu/lib/libg++/libstdc++/cwchar
new file mode 100644
index 00000000000..be96cc81d5b
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cwchar
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CWCHAR__
+#include <std/cwchar.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/cwctype b/gnu/lib/libg++/libstdc++/cwctype
new file mode 100644
index 00000000000..1eaa0ca8e03
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/cwctype
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CWCTYPE__
+#include <std/cwctype.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/deque b/gnu/lib/libg++/libstdc++/deque
new file mode 100644
index 00000000000..bdc14299a04
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/deque
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __DEQUE__
+#define __DEQUE__
+#include <deque.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/exception b/gnu/lib/libg++/libstdc++/exception
new file mode 100644
index 00000000000..a843d4bbc9c
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/exception
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __EXCEPTION__
+#include <std/exception.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/exceptioni.cc b/gnu/lib/libg++/libstdc++/exceptioni.cc
new file mode 100644
index 00000000000..115c6d6b7a4
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/exceptioni.cc
@@ -0,0 +1,78 @@
+// Functions for Exception Support for -*- C++ -*-
+// Copyright (C) 1994, 1995 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+#include <exception>
+#include <stdlib.h>
+
+/* terminate (), unexpected (), set_terminate (), set_unexpected () as
+ well as the default terminate func and default unexpected func */
+
+#if 0
+extern "C" int printf(const char *, ...);
+#endif
+
+void
+__default_terminate ()
+{
+ abort ();
+}
+
+void
+__default_unexpected ()
+{
+ __default_terminate ();
+}
+
+static terminate_handler __terminate_func = __default_terminate;
+static unexpected_handler __unexpected_func = __default_unexpected;
+
+terminate_handler
+set_terminate (terminate_handler func)
+{
+ terminate_handler old = __terminate_func;
+
+ __terminate_func = func;
+ return old;
+}
+
+unexpected_handler
+set_unexpected (unexpected_handler func)
+{
+ unexpected_handler old = __unexpected_func;
+
+ __unexpected_func = func;
+ return old;
+}
+
+void
+terminate ()
+{
+ __terminate_func ();
+}
+
+void
+unexpected ()
+{
+ __unexpected_func ();
+}
diff --git a/gnu/lib/libg++/libstdc++/functional b/gnu/lib/libg++/libstdc++/functional
new file mode 100644
index 00000000000..ee8b7f20202
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/functional
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __FUNCTIONAL__
+#define __FUNCTIONAL__
+#include <function.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/iterator b/gnu/lib/libg++/libstdc++/iterator
new file mode 100644
index 00000000000..a0fa054c5ec
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/iterator
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __ITERATOR__
+#define __ITERATOR__
+#include <iterator.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/list b/gnu/lib/libg++/libstdc++/list
new file mode 100644
index 00000000000..475d8443d16
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/list
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __LIST__
+#define __LIST__
+#include <list.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/map b/gnu/lib/libg++/libstdc++/map
new file mode 100644
index 00000000000..0127b9db250
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/map
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __MAP__
+#define __MAP__
+#include <map.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/memory b/gnu/lib/libg++/libstdc++/memory
new file mode 100644
index 00000000000..8328720db6d
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/memory
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __MEMORY__
+#define __MEMORY__
+#include <defalloc.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/new b/gnu/lib/libg++/libstdc++/new
new file mode 100644
index 00000000000..47944fcff98
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/new
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __NEW__
+#include <std/new.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/new.h b/gnu/lib/libg++/libstdc++/new.h
new file mode 100644
index 00000000000..02bba4509b0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/new.h
@@ -0,0 +1,7 @@
+// -*- C++ -*- backward compatiblity header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __NEW_H__
+#define __NEW_H__
+#include <std/new.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/newi.cc b/gnu/lib/libg++/libstdc++/newi.cc
new file mode 100644
index 00000000000..b4a5b6aeb7e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/newi.cc
@@ -0,0 +1,7 @@
+// Implementation file for the -*- C++ -*- dynamic memory management header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifdef __GNUG__
+#pragma implementation "std/new.h"
+#endif
+#include <std/new.h>
diff --git a/gnu/lib/libg++/libstdc++/numeric b/gnu/lib/libg++/libstdc++/numeric
new file mode 100644
index 00000000000..dcb88737f17
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/numeric
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __NUMERIC__
+#define __NUMERIC__
+#include <algo.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/queue b/gnu/lib/libg++/libstdc++/queue
new file mode 100644
index 00000000000..9b2b6d6c156
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/queue
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __QUEUE__
+#define __QUEUE__
+#include <queue.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/set b/gnu/lib/libg++/libstdc++/set
new file mode 100644
index 00000000000..0353285fe50
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/set
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __SET__
+#define __SET__
+#include <set.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/shlib_version b/gnu/lib/libg++/libstdc++/shlib_version
new file mode 100644
index 00000000000..97c9f92d6b8
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/shlib_version
@@ -0,0 +1,2 @@
+major=0
+minor=0
diff --git a/gnu/lib/libg++/libstdc++/sinst.cc b/gnu/lib/libg++/libstdc++/sinst.cc
new file mode 100644
index 00000000000..136a05e532b
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/sinst.cc
@@ -0,0 +1,147 @@
+// Instantiation file for the -*- C++ -*- string classes.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2.
+
+#ifdef __GNUG__
+#ifdef TRAITS
+#ifdef C
+#pragma implementation "std/straits.h"
+#endif
+#endif
+#endif
+
+#if 0
+#define _G_NO_EXTERN_TEMPLATES
+#endif
+#include <std/bastring.cc>
+
+#ifdef C
+typedef char c;
+#endif
+#ifdef W
+typedef wchar_t c;
+#endif
+
+#ifdef TRAITS
+template class string_char_traits <c>;
+#endif
+
+#define STRING basic_string <c, string_char_traits <c> >
+typedef class STRING s;
+#define BSREP __bsrep <c, string_char_traits <c> >
+typedef class BSREP r;
+
+#ifdef REP
+template class BSREP;
+r s::nilRep = { 0, 0, 1 };
+#ifdef _G_ALLOC_CONTROL
+bool (*r::excess_slop) (size_t, size_t) = r::default_excess;
+size_t (*r::frob_size) (size_t) = r::default_frob;
+#endif
+#endif
+
+#ifdef MAIN
+template class STRING;
+#endif
+
+#ifdef ADDSS
+template s operator+ (const s&, const s&);
+#endif
+#ifdef ADDPS
+template s operator+ (const c*, const s&);
+#endif
+#ifdef ADDCS
+template s operator+ (c, const s&);
+#endif
+#ifdef ADDSP
+template s operator+ (const s&, const c*);
+#endif
+#ifdef ADDSC
+template s operator+ (const s&, c);
+#endif
+#ifdef EQSS
+template bool operator== (const s&, const s&);
+#endif
+#ifdef EQPS
+template bool operator== (const c*, const s&);
+#endif
+#ifdef EQSP
+template bool operator== (const s&, const c*);
+#endif
+#ifdef NESS
+template bool operator!= (const s&, const s&);
+#endif
+#ifdef NEPS
+template bool operator!= (const c*, const s&);
+#endif
+#ifdef NESP
+template bool operator!= (const s&, const c*);
+#endif
+#ifdef LTSS
+template bool operator< (const s&, const s&);
+#endif
+#ifdef LTPS
+template bool operator< (const c*, const s&);
+#endif
+#ifdef LTSP
+template bool operator< (const s&, const c*);
+#endif
+#ifdef GTSS
+template bool operator> (const s&, const s&);
+#endif
+#ifdef GTPS
+template bool operator> (const c*, const s&);
+#endif
+#ifdef GTSP
+template bool operator> (const s&, const c*);
+#endif
+#ifdef LESS
+template bool operator<= (const s&, const s&);
+#endif
+#ifdef LEPS
+template bool operator<= (const c*, const s&);
+#endif
+#ifdef LESP
+template bool operator<= (const s&, const c*);
+#endif
+#ifdef GESS
+template bool operator>= (const s&, const s&);
+#endif
+#ifdef GEPS
+template bool operator>= (const c*, const s&);
+#endif
+#ifdef GESP
+template bool operator>= (const s&, const c*);
+#endif
+#ifdef EXTRACT
+template istream& operator>> (istream&, s&);
+#endif // EXTRACT
+#ifdef INSERT
+template ostream& operator<< (ostream&, const s&);
+#endif // INSERT
+#ifdef GETLINE
+template istream& getline (istream&, s&);
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stack b/gnu/lib/libg++/libstdc++/stack
new file mode 100644
index 00000000000..dfe0c51e181
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stack
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __STACK__
+#define __STACK__
+#include <stack.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/bastring.cc b/gnu/lib/libg++/libstdc++/std/bastring.cc
new file mode 100644
index 00000000000..d3317c50084
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/bastring.cc
@@ -0,0 +1,483 @@
+// Member templates for the -*- C++ -*- string classes.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2.
+
+#include <std/stddef.h>
+#include <std/bastring.h>
+
+extern "C++" {
+template <class charT, class traits>
+inline void * __bsrep <charT, traits>::
+operator new (size_t s, size_t extra)
+{
+ return ::operator new (s + extra * sizeof (charT));
+}
+
+template <class charT, class traits>
+inline size_t __bsrep <charT, traits>::
+#if _G_ALLOC_CONTROL
+default_frob (size_t s)
+#else
+frob_size (size_t s)
+#endif
+{
+ size_t i = 16;
+ while (i < s) i *= 2;
+ return i;
+}
+
+template <class charT, class traits>
+inline __bsrep <charT, traits> * __bsrep <charT, traits>::
+create (size_t extra)
+{
+ extra = frob_size (extra + 1);
+ Rep *p = new (extra) Rep;
+ p->res = extra;
+ p->ref = 1;
+ p->selfish = false;
+ return p;
+}
+
+template <class charT, class traits>
+charT * __bsrep <charT, traits>::
+clone ()
+{
+ Rep *p = Rep::create (len);
+ p->copy (0, data (), len);
+ p->len = len;
+ return p->data ();
+}
+
+template <class charT, class traits>
+inline bool __bsrep <charT, traits>::
+#ifdef _G_ALLOC_CONTROL
+default_excess (size_t s, size_t r)
+#else
+excess_slop (size_t s, size_t r)
+#endif
+{
+ return 2 * (s <= 16 ? 16 : s) < r;
+}
+
+template <class charT, class traits>
+inline bool basic_string <charT, traits>::
+check_realloc (size_t s) const
+{
+ ++s;
+ return (rep ()->ref > 1
+ || s > capacity ()
+ || Rep::excess_slop (s, capacity ()));
+}
+
+template <class charT, class traits>
+void basic_string <charT, traits>::
+alloc (size_t size, bool save)
+{
+ if (! check_realloc (size))
+ return;
+
+ Rep *p = Rep::create (size);
+
+ if (save)
+ {
+ p->copy (0, data (), length ());
+ p->len = length ();
+ }
+ else
+ p->len = 0;
+
+ repup (p);
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>& basic_string <charT, traits>::
+replace (size_t pos1, size_t n1,
+ const basic_string& str, size_t pos2, size_t n2)
+{
+ const size_t len2 = str.length ();
+
+ if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2)
+ return operator= (str);
+
+ OUTOFRANGE (pos2 > len2);
+
+ if (n2 > len2 - pos2)
+ n2 = len2 - pos2;
+
+ return replace (pos1, n1, str.data () + pos2, n2);
+}
+
+template <class charT, class traits>
+inline void __bsrep <charT, traits>::
+copy (size_t pos, const charT *s, size_t n)
+{
+ if (n)
+ traits::copy (data () + pos, s, n);
+}
+
+template <class charT, class traits>
+inline void __bsrep <charT, traits>::
+move (size_t pos, const charT *s, size_t n)
+{
+ if (n)
+ traits::move (data () + pos, s, n);
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>& basic_string <charT, traits>::
+replace (size_t pos, size_t n1, const charT* s, size_t n2)
+{
+ const size_t len = length ();
+ OUTOFRANGE (pos > len);
+ if (n1 > len - pos)
+ n1 = len - pos;
+ LENGTHERROR (len - n1 >= npos - n2);
+ size_t newlen = len - n1 + n2;
+
+ if (check_realloc (newlen))
+ {
+ Rep *p = Rep::create (newlen);
+ p->copy (0, data (), pos);
+ p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
+ p->copy (pos, s, n2);
+ repup (p);
+ }
+ else
+ {
+ rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
+ rep ()->copy (pos, s, n2);
+ }
+ rep ()->len = newlen;
+
+ return *this;
+}
+
+template <class charT, class traits>
+inline void __bsrep <charT, traits>::
+set (size_t pos, const charT c, size_t n)
+{
+ traits::set (data () + pos, c, n);
+}
+
+template <class charT, class traits>
+basic_string <charT, traits>& basic_string <charT, traits>::
+replace (size_t pos, size_t n1, size_t n2, charT c)
+{
+ const size_t len = length ();
+ OUTOFRANGE (pos > len);
+ if (n1 > len - pos)
+ n1 = len - pos;
+ LENGTHERROR (len - n1 >= npos - n2);
+ size_t newlen = len - n1 + n2;
+
+ if (check_realloc (newlen))
+ {
+ Rep *p = Rep::create (newlen);
+ p->copy (0, data (), pos);
+ p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
+ p->set (pos, c, n2);
+ repup (p);
+ }
+ else
+ {
+ rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
+ rep ()->set (pos, c, n2);
+ }
+ rep ()->len = newlen;
+
+ return *this;
+}
+
+template <class charT, class traits>
+void basic_string <charT, traits>::
+resize (size_t n, charT c)
+{
+ LENGTHERROR (n == npos);
+
+ if (n > length ())
+ append (n - length (), c);
+ else
+ remove (n);
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+copy (charT* s, size_t n, size_t pos)
+{
+ OUTOFRANGE (pos > length ());
+
+ if (n > length () - pos)
+ n = length () - pos;
+
+ traits::copy (s, data () + pos, n);
+ return n;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = pos;
+ for (; xpos + n <= length (); ++xpos)
+ if (traits::eq (data () [xpos], *s)
+ && traits::compare (data () + xpos, s, n) == 0)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+inline size_t basic_string <charT, traits>::
+_find (const charT* ptr, charT c, size_t xpos, size_t len)
+{
+ for (; xpos < len; ++xpos)
+ if (traits::eq (ptr [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find (charT c, size_t pos) const
+{
+ return _find (data (), c, pos, length ());
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+rfind (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = length () - n;
+ if (xpos > pos)
+ xpos = pos;
+
+ for (++xpos; xpos-- > 0; )
+ if (traits::eq (data () [xpos], *s)
+ && traits::compare (data () + xpos, s, n) == 0)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+rfind (charT c, size_t pos) const
+{
+ size_t xpos = length () - 1;
+ if (xpos > pos)
+ xpos = pos;
+
+ for (++xpos; xpos-- > 0; )
+ if (traits::eq (data () [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_first_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = pos;
+ for (; xpos < length (); ++xpos)
+ if (_find (s, data () [xpos], 0, n) != npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_last_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = length ();
+ for (; xpos-- > pos; )
+ if (_find (s, data () [xpos], 0, n) != npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_first_not_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = pos;
+ for (; xpos < length (); ++xpos)
+ if (_find (s, data () [xpos], 0, n) == npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_first_not_of (charT c, size_t pos) const
+{
+ size_t xpos = pos;
+ for (; xpos < length (); ++xpos)
+ if (traits::ne (data () [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_last_not_of (const charT* s, size_t pos, size_t n) const
+{
+ size_t xpos = length ();
+ for (; xpos-- > pos; )
+ if (_find (s, data () [xpos], 0, n) == npos)
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+size_t basic_string <charT, traits>::
+find_last_not_of (charT c, size_t pos) const
+{
+ size_t xpos = length ();
+ for (; xpos-- > pos; )
+ if (traits::ne (data () [xpos], c))
+ return xpos;
+ return npos;
+}
+
+template <class charT, class traits>
+int basic_string <charT, traits>::
+compare (const basic_string& str, size_t pos, size_t n) const
+{
+ OUTOFRANGE (pos > length ());
+
+ size_t rlen = length () - pos;
+ if (rlen > n)
+ rlen = n;
+ if (rlen > str.length ())
+ rlen = str.length ();
+ int r = traits::compare (data () + pos, str.data (), rlen);
+ if (r != 0)
+ return r;
+ if (rlen == n)
+ return 0;
+ return (length () - pos) - str.length ();
+}
+
+template <class charT, class traits>
+int basic_string <charT, traits>::
+compare (const charT* s, size_t pos, size_t n) const
+{
+ OUTOFRANGE (pos > length ());
+
+ size_t rlen = length () - pos;
+ if (rlen > n)
+ rlen = n;
+ int r = traits::compare (data () + pos, s, rlen);
+ if (r != 0)
+ return r;
+ return (length () - pos) - n;
+}
+
+#include <iostream.h>
+
+template <class charT, class traits>
+istream &
+operator>> (istream &is, basic_string <charT, traits> &s)
+{
+ int w = is.width (0);
+ if (is.ipfx0 ())
+ {
+ register streambuf *sb = is.rdbuf ();
+ s.resize (0);
+ while (1)
+ {
+ int ch = sb->sbumpc ();
+ if (ch == EOF)
+ {
+ is.setstate (ios::eofbit);
+ break;
+ }
+ else if (traits::is_del (ch))
+ {
+ sb->sungetc ();
+ break;
+ }
+ s += ch;
+ if (--w == 1)
+ break;
+ }
+ }
+
+ is.isfx ();
+ if (s.length () == 0)
+ is.setstate (ios::failbit);
+
+ return is;
+}
+
+template <class charT, class traits>
+ostream &
+operator<< (ostream &o, const basic_string <charT, traits>& s)
+{
+ return o.write (s.data (), s.length ());
+}
+
+template <class charT, class traits>
+istream&
+getline (istream &is, basic_string <charT, traits>& s, charT delim)
+{
+ if (is.ipfx1 ())
+ {
+ _IO_size_t count = 0;
+ streambuf *sb = is.rdbuf ();
+ s.resize (0);
+
+ while (1)
+ {
+ int ch = sb->sbumpc ();
+ if (ch == EOF)
+ {
+ is.setstate (count == 0
+ ? (ios::failbit|ios::eofbit)
+ : ios::eofbit);
+ break;
+ }
+
+ ++count;
+
+ if (ch == delim)
+ break;
+
+ s += ch;
+
+ if (s.length () == s.npos - 1)
+ {
+ is.setstate (ios::failbit);
+ break;
+ }
+ }
+ }
+
+ // We need to be friends with istream to do this.
+ // is._gcount = count;
+ is.isfx ();
+
+ return is;
+}
+} // extern "C++"
diff --git a/gnu/lib/libg++/libstdc++/std/bastring.h b/gnu/lib/libg++/libstdc++/std/bastring.h
new file mode 100644
index 00000000000..6361ef27cca
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/bastring.h
@@ -0,0 +1,574 @@
+// Main templates for the -*- C++ -*- string classes.
+// Copyright (C) 1994, 1995 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2.
+
+#ifndef __BASTRING__
+#define __BASTRING__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <std/stddef.h>
+#include <std/straits.h>
+
+#if _G_USE_EXCEPTIONS
+
+#include <stdexcept>
+#define OUTOFRANGE(cond) \
+ do { if (!(cond)) throw out_of_range (#cond); } while (0)
+#define LENGTHERROR(cond) \
+ do { if (!(cond)) throw length_error (#cond); } while (0)
+
+#else
+
+#include <cassert>
+#define OUTOFRANGE(cond) assert (!(cond))
+#define LENGTHERROR(cond) assert (!(cond))
+
+#endif
+
+extern "C++" {
+class istream; class ostream;
+
+// Should be a nested class basic_string<charT, traits>::Rep, but nested
+// classes don't work well with templates in g++.
+template <class charT, class traits = string_char_traits<charT> >
+struct __bsrep {
+ typedef __bsrep Rep;
+
+ size_t len, res, ref;
+ bool selfish;
+
+ charT* data () { return reinterpret_cast<charT *>(this + 1); }
+ charT& operator[] (size_t s) { return data () [s]; }
+ charT* grab () { if (selfish) return clone (); ++ref; return data (); }
+ void release () { if (--ref == 0) delete this; }
+
+ inline static void * operator new (size_t, size_t);
+ inline static Rep* create (size_t);
+ charT* clone ();
+
+ inline void copy (size_t, const charT *, size_t);
+ inline void move (size_t, const charT *, size_t);
+ inline void set (size_t, const charT, size_t);
+
+#if _G_ALLOC_CONTROL
+ // These function pointers allow you to modify the allocation policy used
+ // by the string classes. By default they expand by powers of two, but
+ // this may be excessive for space-critical applications.
+
+ // Returns true if ALLOCATED is too much larger than LENGTH
+ static bool (*excess_slop) (size_t length, size_t allocated);
+ inline static bool default_excess (size_t, size_t);
+
+ // Returns a good amount of space to allocate for a string of length LENGTH
+ static size_t (*frob_size) (size_t length);
+ inline static size_t default_frob (size_t);
+#else
+ inline static bool excess_slop (size_t, size_t);
+ inline static size_t frob_size (size_t);
+#endif
+
+private:
+ Rep &operator= (const Rep &);
+};
+
+// #include <iterator.h>
+
+template <class charT, class traits = string_char_traits<charT> >
+class basic_string
+{
+private:
+ typedef __bsrep<charT, traits> Rep;
+
+public:
+// types:
+ typedef traits traits_type;
+ typedef charT value_type;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef charT& reference;
+ typedef const charT& const_reference;
+ typedef charT* pointer;
+ typedef const charT* const_pointer;
+ typedef pointer iterator;
+ typedef const_pointer const_iterator;
+#if 0
+ typedef reverse_iterator<iterator, value_type,
+ reference, difference_type> reverse_iterator;
+ typedef reverse_iterator<const_iterator, value_type, const_reference,
+ difference_type> const_reverse_iterator;
+#endif
+ static const size_type npos = static_cast<size_type>(-1);
+
+private:
+ Rep *rep () const { return reinterpret_cast<Rep *>(dat) - 1; }
+ void repup (Rep *p) { rep ()->release (); dat = p->data (); }
+
+public:
+ const charT* data () const
+ { return rep ()->data(); }
+ size_type length () const
+ { return rep ()->len; }
+ size_type size () const
+ { return rep ()->len; }
+ size_type capacity () const
+ { return rep ()->res; }
+ size_type max_size () const
+ { return npos - 1; } // XXX
+ bool empty () const
+ { return size () == 0; }
+
+// _lib.string.cons_ construct/copy/destroy:
+ basic_string& operator= (const basic_string& str)
+ {
+ if (&str != this) { rep ()->release (); dat = str.rep ()->grab (); }
+ return *this;
+ }
+
+ explicit basic_string (): dat (nilRep.grab ()) { }
+ basic_string (const basic_string& str): dat (str.rep ()->grab ()) { }
+ basic_string (const basic_string& str, size_type pos, size_type n = npos)
+ : dat (nilRep.grab ()) { assign (str, pos, n); }
+ basic_string (const charT* s, size_type n)
+ : dat (nilRep.grab ()) { assign (s, n); }
+ basic_string (const charT* s)
+ : dat (nilRep.grab ()) { assign (s); }
+ basic_string (size_type n, charT c)
+ : dat (nilRep.grab ()) { assign (n, c); }
+#if 0
+ template<class InputIterator>
+ basic_string(InputIterator begin, InputIterator end,
+ Allocator& = Allocator());
+#endif
+
+ ~basic_string ()
+ { rep ()->release (); }
+
+ void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; }
+
+ basic_string& append (const basic_string& str, size_type pos = 0,
+ size_type n = npos)
+ { return replace (length (), 0, str, pos, n); }
+ basic_string& append (const charT* s, size_type n)
+ { return replace (length (), 0, s, n); }
+ basic_string& append (const charT* s)
+ { return append (s, traits::length (s)); }
+ basic_string& append (size_type n, charT c)
+ { return replace (length (), 0, n, c); }
+#if 0
+ template<class InputIterator>
+ basic_string& append(InputIterator first, InputIterator last);
+#endif
+
+ basic_string& assign (const basic_string& str, size_type pos = 0,
+ size_type n = npos)
+ { return replace (0, npos, str, pos, n); }
+ basic_string& assign (const charT* s, size_type n)
+ { return replace (0, npos, s, n); }
+ basic_string& assign (const charT* s)
+ { return assign (s, traits::length (s)); }
+ basic_string& assign (size_type n, charT c)
+ { return replace (0, npos, n, c); }
+#if 0
+ template<class InputIterator>
+ basic_string& assign(InputIterator first, InputIterator last);
+#endif
+
+ basic_string& operator= (const charT* s)
+ { return assign (s); }
+ basic_string& operator= (charT c)
+ { return assign (1, c); }
+
+ basic_string& operator+= (const basic_string& rhs)
+ { return append (rhs); }
+ basic_string& operator+= (const charT* s)
+ { return append (s); }
+ basic_string& operator+= (charT c)
+ { return append (1, c); }
+
+ basic_string& insert (size_type pos1, const basic_string& str,
+ size_type pos2 = 0, size_type n = npos)
+ { return replace (pos1, 0, str, pos2, n); }
+ basic_string& insert (size_type pos, const charT* s, size_type n)
+ { return replace (pos, 0, s, n); }
+ basic_string& insert (size_type pos, const charT* s)
+ { return insert (pos, s, traits::length (s)); }
+ basic_string& insert (size_type pos, size_type n, charT c)
+ { return replace (pos, 0, n, c); }
+ iterator insert(iterator p, charT c)
+ { insert (p - begin (), 1, c); return p; }
+ iterator insert(iterator p, size_type n, charT c)
+ { insert (p - begin (), n, c); return p; }
+#if 0
+ template<class InputIterator>
+ void insert(iterator p, InputIterator first, InputIterator last);
+#endif
+
+ basic_string& remove (size_type pos = 0, size_type n = npos)
+ { return replace (pos, n, 0, (charT)0); }
+ basic_string& remove (iterator pos)
+ { return replace (pos - begin (), 1, 0, (charT)0); }
+ basic_string& remove (iterator first, iterator last)
+ { return replace (first - begin (), last - first, 0, (charT)0); }
+
+ basic_string& replace (size_type pos1, size_type n1, const basic_string& str,
+ size_type pos2 = 0, size_type n2 = npos);
+ basic_string& replace (size_type pos, size_type n1, const charT* s,
+ size_type n2);
+ basic_string& replace (size_type pos, size_type n1, const charT* s)
+ { return replace (pos, n1, s, traits::length (s)); }
+ basic_string& replace (size_type pos, size_type n1, size_type n2, charT c);
+ basic_string& replace (size_type pos, size_type n, charT c)
+ { return replace (pos, n, 1, c); }
+ basic_string& replace (iterator i1, iterator i2, const basic_string& str)
+ { return replace (i1 - begin (), i2 - i1, str); }
+ basic_string& replace (iterator i1, iterator i2, const charT* s, size_type n)
+ { return replace (i1 - begin (), i2 - i1, s, n); }
+ basic_string& replace (iterator i1, iterator i2, const charT* s)
+ { return replace (i1 - begin (), i2 - i1, s); }
+ basic_string& replace (iterator i1, iterator i2, size_type n, charT c)
+ { return replace (i1 - begin (), i2 - i1, n, c); }
+#if 0
+ template<class InputIterator>
+ basic_string& replace(iterator i1, iterator i2,
+ InputIterator j1, InputIterator j2);
+#endif
+
+private:
+ static charT eos () { return traits::eos (); }
+ void unique () { if (rep ()->ref > 1) alloc (capacity (), true); }
+ void selfish () { unique (); rep ()->selfish = true; }
+
+public:
+ charT operator[] (size_type pos) const
+ {
+ if (pos == length ())
+ return eos ();
+ return data ()[pos];
+ }
+
+ reference operator[] (size_type pos)
+ { unique (); return (*rep ())[pos]; }
+
+ reference at (size_type pos)
+ {
+ OUTOFRANGE (pos >= length ());
+ return (*this)[pos];
+ }
+ const_reference at (size_type pos) const
+ {
+ OUTOFRANGE (pos >= length ());
+ return data ()[pos];
+ }
+
+private:
+ void terminate () const
+ { traits::assign ((*rep ())[length ()], eos ()); }
+
+public:
+ const charT* c_str () const
+ { terminate (); return data (); }
+ void resize (size_type n, charT c);
+ void resize (size_type n)
+ { resize (n, eos ()); }
+ void reserve (size_type) { }
+
+ size_type copy (charT* s, size_type n, size_type pos = 0);
+
+ size_type find (const basic_string& str, size_type pos = 0) const
+ { return find (str.data(), pos, str.length()); }
+ size_type find (const charT* s, size_type pos, size_type n) const;
+ size_type find (const charT* s, size_type pos = 0) const
+ { return find (s, pos, traits::length (s)); }
+ size_type find (charT c, size_type pos = 0) const;
+
+ size_type rfind (const basic_string& str, size_type pos = npos) const
+ { return rfind (str.data(), pos, str.length()); }
+ size_type rfind (const charT* s, size_type pos, size_type n) const;
+ size_type rfind (const charT* s, size_type pos = npos) const
+ { return rfind (s, pos, traits::length (s)); }
+ size_type rfind (charT c, size_type pos = npos) const;
+
+ size_type find_first_of (const basic_string& str, size_type pos = 0) const
+ { return find_first_of (str.data(), pos, str.length()); }
+ size_type find_first_of (const charT* s, size_type pos, size_type n) const;
+ size_type find_first_of (const charT* s, size_type pos = 0) const
+ { return find_first_of (s, pos, traits::length (s)); }
+ size_type find_first_of (charT c, size_type pos = 0) const
+ { return find (c, pos); }
+
+ size_type find_last_of (const basic_string& str, size_type pos = npos) const
+ { return find_last_of (str.data(), pos, str.length()); }
+ size_type find_last_of (const charT* s, size_type pos, size_type n) const;
+ size_type find_last_of (const charT* s, size_type pos = npos) const
+ { return find_last_of (s, pos, traits::length (s)); }
+ size_type find_last_of (charT c, size_type pos = npos) const
+ { return rfind (c, pos); }
+
+ size_type find_first_not_of (const basic_string& str, size_type pos = 0) const
+ { return find_first_not_of (str.data(), pos, str.length()); }
+ size_type find_first_not_of (const charT* s, size_type pos, size_type n) const;
+ size_type find_first_not_of (const charT* s, size_type pos = 0) const
+ { return find_first_not_of (s, pos, traits::length (s)); }
+ size_type find_first_not_of (charT c, size_type pos = 0) const;
+
+ size_type find_last_not_of (const basic_string& str, size_type pos = npos) const
+ { return find_last_not_of (str.data(), pos, str.length()); }
+ size_type find_last_not_of (const charT* s, size_type pos, size_type n) const;
+ size_type find_last_not_of (const charT* s, size_type pos = npos) const
+ { return find_last_not_of (s, pos, traits::length (s)); }
+ size_type find_last_not_of (charT c, size_type pos = npos) const;
+
+ basic_string substr (size_type pos = 0, size_type n = npos) const
+ { return basic_string (*this, pos, n); }
+
+ int compare (const basic_string& str, size_type pos = 0, size_type n = npos) const;
+ // There is no 'strncmp' equivalent for charT pointers.
+ int compare (const charT* s, size_type pos, size_type n) const;
+ int compare (const charT* s, size_type pos = 0) const
+ { return compare (s, pos, traits::length (s)); }
+
+ iterator begin () { selfish (); return &(*this)[0]; }
+ iterator end () { selfish (); return &(*this)[length ()]; }
+ const_iterator begin () const { return &(*rep ())[0]; }
+ const_iterator end () const { return &(*rep ())[length ()]; }
+
+#if 0
+ reverse_iterator rbegin() { return reverse_iterator (end ()); }
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator (end ()); }
+ reverse_iterator rend() { return reverse_iterator (begin ()); }
+ const_reverse_iterator rend() const
+ { return const reverse_iterator (begin ()); }
+#endif
+
+private:
+ void alloc (size_type size, bool save);
+ static size_type _find (const charT* ptr, charT c, size_type xpos, size_type len);
+ inline bool check_realloc (size_type s) const;
+
+ static Rep nilRep;
+ charT *dat;
+};
+
+template <class charT, class traits>
+inline basic_string <charT, traits>
+operator+ (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ basic_string <charT, traits> str (lhs);
+ str.append (rhs);
+ return str;
+}
+
+template <class charT, class traits>
+inline basic_string <charT, traits>
+operator+ (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ basic_string <charT, traits> str (lhs);
+ str.append (rhs);
+ return str;
+}
+
+template <class charT, class traits>
+inline basic_string <charT, traits>
+operator+ (charT lhs, const basic_string <charT, traits>& rhs)
+{
+ basic_string <charT, traits> str (1, lhs);
+ str.append (rhs);
+ return str;
+}
+
+template <class charT, class traits>
+inline basic_string <charT, traits>
+operator+ (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ basic_string <charT, traits> str (lhs);
+ str.append (rhs);
+ return str;
+}
+
+template <class charT, class traits>
+inline basic_string <charT, traits>
+operator+ (const basic_string <charT, traits>& lhs, charT rhs)
+{
+ basic_string <charT, traits> str (lhs);
+ str.append (1, rhs);
+ return str;
+}
+
+template <class charT, class traits>
+inline bool
+operator== (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ return (lhs.compare (rhs) == 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator== (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ return (rhs.compare (lhs) == 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator== (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ return (lhs.compare (rhs) == 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator!= (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ return (rhs.compare (lhs) != 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator!= (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ return (lhs.compare (rhs) != 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator< (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ return (lhs.compare (rhs) < 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator< (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ return (rhs.compare (lhs) > 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator< (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ return (lhs.compare (rhs) < 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator> (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ return (rhs.compare (lhs) < 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator> (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ return (lhs.compare (rhs) > 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator<= (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ return (rhs.compare (lhs) >= 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator<= (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ return (lhs.compare (rhs) <= 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator>= (const charT* lhs, const basic_string <charT, traits>& rhs)
+{
+ return (rhs.compare (lhs) <= 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator>= (const basic_string <charT, traits>& lhs, const charT* rhs)
+{
+ return (lhs.compare (rhs) >= 0);
+}
+
+// Kludge this until g++ supports the new template overloading semantics.
+#if !defined(FUNCTION_H)
+template <class charT, class traits>
+inline bool
+operator!= (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ return (lhs.compare (rhs) != 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator> (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ return (lhs.compare (rhs) > 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator<= (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ return (lhs.compare (rhs) <= 0);
+}
+
+template <class charT, class traits>
+inline bool
+operator>= (const basic_string <charT, traits>& lhs,
+ const basic_string <charT, traits>& rhs)
+{
+ return (lhs.compare (rhs) >= 0);
+}
+#endif
+
+class istream; class ostream;
+template <class charT, class traits> istream&
+operator>> (istream&, basic_string <charT, traits>&);
+template <class charT, class traits> ostream&
+operator<< (ostream&, const basic_string <charT, traits>&);
+template <class charT, class traits> istream&
+getline (istream&, basic_string <charT, traits>&, charT delim = '\n');
+
+} // extern "C++"
+
+#if !defined (_G_NO_EXTERN_TEMPLATES)
+#include <std/sinst.h>
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cassert.h b/gnu/lib/libg++/libstdc++/std/cassert.h
new file mode 100644
index 00000000000..83f9f4042f3
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cassert.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- assertions header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __ASSERT__
+#define __ASSERT__
+#include <assert.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cctype.h b/gnu/lib/libg++/libstdc++/std/cctype.h
new file mode 100644
index 00000000000..e2765aed50a
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cctype.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- character type header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CCTYPE__
+#define __CCTYPE__
+#include <ctype.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cerrno.h b/gnu/lib/libg++/libstdc++/std/cerrno.h
new file mode 100644
index 00000000000..ce493469597
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cerrno.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- error number header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CERRNO__
+#define __CERRNO__
+#include <errno.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cfloat.h b/gnu/lib/libg++/libstdc++/std/cfloat.h
new file mode 100644
index 00000000000..05a6338740e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cfloat.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- floating point header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CFLOAT__
+#define __CFLOAT__
+#include <float.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cinst.h b/gnu/lib/libg++/libstdc++/std/cinst.h
new file mode 100644
index 00000000000..e41a2bad146
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cinst.h
@@ -0,0 +1,112 @@
+// Forward declarations of -*- C++ -*- complex number instantiations.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification in the 27 May 1994
+// C++ working paper, ANSI document X3J16/94-0098.
+
+#ifndef __CINST__
+#define __CINST__
+
+#ifndef _G_NO_EXTERN_TEMPLATES
+extern "C++" {
+extern template class complex<float>;
+extern template class complex<double>;
+extern template class complex<long double>;
+
+#define __B(type) bool
+#define __C(type) complex<type>
+#define __F(type) type
+#define __I(type) int
+#define __IS(type) istream&
+#define __OS(type) ostream&
+#define __CR(type) complex<type>&
+#define __CCR(type) const complex<type>&
+
+#define __D2(name,type,ret,arg1,arg2) ret(type) name (arg1(type), arg2(type));
+
+#define __S1(name,type,ret,arg1) \
+ extern template ret(type) name (arg1(type));
+#define __S2(name,type,ret,arg1,arg2) \
+ extern template __D2 (name,type,ret,arg1,arg2)
+
+#define __DO1(name,ret,arg1) \
+ __S1(name,float,ret,arg1) \
+ __S1(name,double,ret,arg1) \
+ __S1(name,long double,ret,arg1)
+#define __DO2(name,ret,arg1,arg2) \
+ __S2(name,float,ret,arg1,arg2) \
+ __S2(name,double,ret,arg1,arg2) \
+ __S2(name,long double,ret,arg1,arg2)
+
+#define __DOCCC(name) __DO2(name,__C,__CCR,__CCR)
+#define __DOCCF(name) __DO2(name,__C,__CCR,__F)
+#define __DOCFC(name) __DO2(name,__C,__F,__CCR)
+#define __DOCFF(name) __DO2(name,__C,__F,__F)
+#define __DOBCC(name) __DO2(name,__B,__CCR,__CCR)
+#define __DOBCF(name) __DO2(name,__B,__CCR,__F)
+#define __DOBFC(name) __DO2(name,__B,__F,__CCR)
+#define __DOFC(name) __DO1(name,__F,__CCR)
+#define __DOCC(name) __DO1(name,__C,__CCR)
+
+__DO2(operator+,__C,__CCR,__CCR)
+__DO2(operator+,__C,__CCR,__F)
+__DO2(operator+,__C,__F,__CCR)
+__DO2(operator-,__C,__CCR,__CCR)
+__DO2(operator-,__C,__CCR,__F)
+__DO2(operator-,__C,__F,__CCR)
+__DO2(operator*,__C,__CCR,__CCR)
+__DO2(operator*,__C,__CCR,__F)
+__DO2(operator*,__C,__F,__CCR)
+__DO2(operator/,__C,__CCR,__F)
+__DO1(operator+,__C,__CCR)
+__DO1(operator-,__C,__CCR)
+__DO2(operator==,__B,__CCR,__CCR)
+__DO2(operator==,__B,__CCR,__F)
+__DO2(operator==,__B,__F,__CCR)
+__DO2(operator!=,__B,__CCR,__CCR)
+__DO2(operator!=,__B,__CCR,__F)
+__DO2(operator!=,__B,__F,__CCR)
+__DO1(abs,__F,__CCR)
+__DO1(arg,__F,__CCR)
+__DO2(polar,__C,__F,__F)
+__DO1(conj,__C,__CCR)
+__DO1(norm,__F,__CCR)
+
+#undef __DO1
+#undef __DO2
+#undef __S1
+#undef __S2
+#undef __D2
+#undef __B
+#undef __C
+#undef __F
+#undef __I
+#undef __IS
+#undef __OS
+#undef __CR
+#undef __CCR
+} // extern "C++"
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/ciso646.h b/gnu/lib/libg++/libstdc++/std/ciso646.h
new file mode 100644
index 00000000000..974d15b5742
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/ciso646.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- ISO 646 header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CISO646__
+#define __CISO646__
+#include <iso646.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/climits.h b/gnu/lib/libg++/libstdc++/std/climits.h
new file mode 100644
index 00000000000..45e3d62b492
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/climits.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- integral type limits header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CLIMITS__
+#define __CLIMITS__
+#include <limits.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/clocale.h b/gnu/lib/libg++/libstdc++/std/clocale.h
new file mode 100644
index 00000000000..b67cf31c9d2
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/clocale.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- locale support header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CLOCALE__
+#define __CLOCALE__
+#include <locale.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cmath.h b/gnu/lib/libg++/libstdc++/std/cmath.h
new file mode 100644
index 00000000000..8c6628ed83c
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cmath.h
@@ -0,0 +1,76 @@
+// The -*- C++ -*- math functions header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CMATH__
+#define __CMATH__
+#include <_G_config.h>
+#include <math.h>
+
+#ifdef __GNUG__
+#pragma interface "std/cmath.h"
+#endif
+
+extern "C++" {
+#if 0
+float acos (float);
+float asin (float);
+float atan (float);
+float atan2(float, float);
+float ceil (float);
+float cos (float);
+float cosh (float);
+float exp (float);
+float fabs (float);
+float floor(float);
+float fmod (float, float);
+float frexp(float, int*);
+float modf (float, float*);
+float ldexp(float, int);
+float log (float);
+float log10(float);
+float pow (float, float);
+float pow (float, int);
+float sin (float);
+float sinh (float);
+float sqrt (float);
+float tan (float);
+float tanh (float);
+#endif
+
+inline float abs (float x) { return fabs (x); }
+#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
+inline double abs (double x) { return fabs (x); }
+#endif
+
+#if 0
+double pow(double, int);
+
+long double acos (long double);
+long double asin (long double);
+long double atan (long double);
+long double atan2(long double, long double);
+long double ceil (long double);
+long double cos (long double);
+long double cosh (long double);
+long double exp (long double);
+long double fabs (long double);
+long double floor(long double);
+long double frexp(long double, int*);
+long double fmod (long double, long double);
+long double frexp(long double, int*);
+long double log (long double);
+long double log10(long double);
+long double modf (long double, long double*);
+long double pow (long double, long double);
+long double pow (long double, int);
+long double sin (long double);
+long double sinh (long double);
+long double sqrt (long double);
+long double tan (long double);
+long double tanh (long double);
+#endif
+inline long double abs (long double x) { return fabs (x); }
+
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/complex.h b/gnu/lib/libg++/libstdc++/std/complex.h
new file mode 100644
index 00000000000..bfdd352b462
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/complex.h
@@ -0,0 +1,18 @@
+// Main header for the -*- C++ -*- complex number classes.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __COMPLEX__
+#define __COMPLEX__
+
+#include <std/complext.h>
+
+extern "C++" {
+#define __STD_COMPLEX
+
+// ANSI complex types
+typedef complex<float> float_complex;
+typedef complex<double> double_complex;
+typedef complex<long double> long_double_complex;
+}
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/complext.cc b/gnu/lib/libg++/libstdc++/std/complext.cc
new file mode 100644
index 00000000000..0b63125b2d2
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/complext.cc
@@ -0,0 +1,273 @@
+// Member templates for the -*- C++ -*- complex number classes.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification in the 27 May 1994
+// C++ working paper, ANSI document X3J16/94-0098.
+
+#include <std/complex.h>
+
+extern "C++" {
+template <class FLOAT> complex<FLOAT>
+cos (const complex<FLOAT>& x)
+{
+ return complex<FLOAT> (cos (real (x)) * cosh (imag (x)),
+ - sin (real (x)) * sinh (imag (x)));
+}
+
+template <class FLOAT> complex<FLOAT>
+cosh (const complex<FLOAT>& x)
+{
+ return complex<FLOAT> (cosh (real (x)) * cos (imag (x)),
+ sinh (real (x)) * sin (imag (x)));
+}
+
+template <class FLOAT> complex<FLOAT>
+exp (const complex<FLOAT>& x)
+{
+ return polar (FLOAT (exp (real (x))), imag (x));
+}
+
+template <class FLOAT> complex<FLOAT>
+log (const complex<FLOAT>& x)
+{
+ return complex<FLOAT> (log (abs (x)), arg (x));
+}
+
+template <class FLOAT> complex<FLOAT>
+pow (const complex<FLOAT>& x, const complex<FLOAT>& y)
+{
+ FLOAT logr = log (abs (x));
+ FLOAT t = arg (x);
+
+ return polar (FLOAT (exp (logr * real (y) - imag (y) * t)),
+ FLOAT (imag (y) * logr + real (y) * t));
+}
+
+template <class FLOAT> complex<FLOAT>
+pow (const complex<FLOAT>& x, FLOAT y)
+{
+ return exp (FLOAT (y) * log (x));
+}
+
+template <class FLOAT> complex<FLOAT>
+pow (FLOAT x, const complex<FLOAT>& y)
+{
+ return exp (y * FLOAT (log (x)));
+}
+
+template <class FLOAT> complex<FLOAT>
+sin (const complex<FLOAT>& x)
+{
+ return complex<FLOAT> (sin (real (x)) * cosh (imag (x)),
+ cos (real (x)) * sinh (imag (x)));
+}
+
+template <class FLOAT> complex<FLOAT>
+sinh (const complex<FLOAT>& x)
+{
+ return complex<FLOAT> (sinh (real (x)) * cos (imag (x)),
+ cosh (real (x)) * sin (imag (x)));
+}
+
+#include <iostream.h>
+
+template <class FLOAT> istream&
+operator >> (istream& is, complex<FLOAT>& x)
+{
+ FLOAT re, im = 0;
+ char ch = 0;
+
+ if (is.ipfx0 ())
+ {
+ if (is.peek () == '(')
+ is >> ch;
+ is >> re;
+ if (ch == '(')
+ {
+ is >> ch;
+ if (ch == ',')
+ is >> im >> ch;
+ }
+ }
+ is.isfx ();
+
+ if (ch != 0 && ch != ')')
+ is.setstate (ios::failbit);
+ else if (is.good ())
+ x = complex<FLOAT> (re, im);
+
+ return is;
+}
+
+template <class FLOAT> ostream&
+operator << (ostream& os, const complex<FLOAT>& x)
+{
+ return os << '(' << real (x) << ',' << imag (x) << ')';
+}
+
+// The code below is adapted from f2c's libF77, and is subject to this
+// copyright:
+
+/****************************************************************
+Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the names of AT&T Bell Laboratories or
+Bellcore or any of their entities not be used in advertising or
+publicity pertaining to distribution of the software without
+specific, written prior permission.
+
+AT&T and Bellcore disclaim all warranties with regard to this
+software, including all implied warranties of merchantability
+and fitness. In no event shall AT&T or Bellcore be liable for
+any special, indirect or consequential damages or any damages
+whatsoever resulting from loss of use, data or profits, whether
+in an action of contract, negligence or other tortious action,
+arising out of or in connection with the use or performance of
+this software.
+****************************************************************/
+
+template <class FLOAT> complex<FLOAT>& complex<FLOAT>::
+operator /= (const complex& y)
+{
+ FLOAT ar = abs (y.re);
+ FLOAT ai = abs (y.im);
+ FLOAT nr, ni;
+ FLOAT t, d;
+ if (ar <= ai)
+ {
+ t = y.re / y.im;
+ d = y.im * (1 + t*t);
+ nr = (re * t + im) / d;
+ ni = (im * t - re) / d;
+ }
+ else
+ {
+ t = y.im / y.re;
+ d = y.re * (1 + t*t);
+ nr = (re + im * t) / d;
+ ni = (im - re * t) / d;
+ }
+ re = nr;
+ im = ni;
+ return *this;
+}
+
+template <class FLOAT> complex<FLOAT>
+operator / (const complex<FLOAT>& x, const complex<FLOAT>& y)
+{
+ FLOAT ar = abs (real (y));
+ FLOAT ai = abs (imag (y));
+ FLOAT nr, ni;
+ FLOAT t, d;
+ if (ar <= ai)
+ {
+ t = real (y) / imag (y);
+ d = imag (y) * (1 + t*t);
+ nr = (real (x) * t + imag (x)) / d;
+ ni = (imag (x) * t - real (x)) / d;
+ }
+ else
+ {
+ t = imag (y) / real (y);
+ d = real (y) * (1 + t*t);
+ nr = (real (x) + imag (x) * t) / d;
+ ni = (imag (x) - real (x) * t) / d;
+ }
+ return complex<FLOAT> (nr, ni);
+}
+
+template <class FLOAT> complex<FLOAT>
+operator / (FLOAT x, const complex<FLOAT>& y)
+{
+ FLOAT ar = abs (real (y));
+ FLOAT ai = abs (imag (y));
+ FLOAT nr, ni;
+ FLOAT t, d;
+ if (ar <= ai)
+ {
+ t = real (y) / imag (y);
+ d = imag (y) * (1 + t*t);
+ nr = x * t / d;
+ ni = -x / d;
+ }
+ else
+ {
+ t = imag (y) / real (y);
+ d = real (y) * (1 + t*t);
+ nr = x / d;
+ ni = -x * t / d;
+ }
+ return complex<FLOAT> (nr, ni);
+}
+
+template <class FLOAT> complex<FLOAT>
+pow (const complex<FLOAT>& xin, int y)
+{
+ if (y == 0)
+ return complex<FLOAT> (1.0);
+ complex<FLOAT> r (1.0);
+ complex<FLOAT> x (xin);
+ if (y < 0)
+ {
+ y = -y;
+ x = 1/x;
+ }
+ for (;;)
+ {
+ if (y & 1)
+ r *= x;
+ if (y >>= 1)
+ x *= x;
+ else
+ return r;
+ }
+}
+
+template <class FLOAT> complex<FLOAT>
+sqrt (const complex<FLOAT>& x)
+{
+ FLOAT r = abs (x);
+ FLOAT nr, ni;
+ if (r == 0.0)
+ nr = ni = r;
+ else if (real (x) > 0)
+ {
+ nr = sqrt (0.5 * (r + real (x)));
+ ni = imag (x) / nr / 2;
+ }
+ else
+ {
+ ni = sqrt (0.5 * (r - real (x)));
+ if (imag (x) < 0)
+ ni = - ni;
+ nr = imag (x) / ni / 2;
+ }
+ return complex<FLOAT> (nr, ni);
+}
+} // extern "C++"
diff --git a/gnu/lib/libg++/libstdc++/std/complext.h b/gnu/lib/libg++/libstdc++/std/complext.h
new file mode 100644
index 00000000000..db87dd0988f
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/complext.h
@@ -0,0 +1,317 @@
+// The template and inlines for the -*- C++ -*- complex number classes.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the terms of
+// the GNU General Public License as published by the Free Software
+// Foundation; either version 2, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files compiled
+// with a GNU compiler to produce an executable, this does not cause the
+// resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification in the 27 May 1994
+// C++ working paper, ANSI document X3J16/94-0098.
+
+#ifndef __COMPLEXT__
+#define __COMPLEXT__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <std/cmath.h>
+
+#if ! defined (__GNUG__) && ! defined (__attribute__)
+#define __attribute__ (foo) /* Ignore. */
+#endif
+
+extern "C++" {
+template <class FLOAT>
+class complex
+{
+public:
+ complex (FLOAT r = 0, FLOAT i = 0): re (r), im (i) { }
+ complex& operator += (const complex&);
+ complex& operator -= (const complex&);
+ complex& operator *= (const complex&);
+ complex& operator /= (const complex&);
+ FLOAT real () const { return re; }
+ FLOAT imag () const { return im; }
+private:
+ FLOAT re, im;
+
+ // These functions are specified as friends for purposes of name injection;
+ // they do not actually reference private members.
+ friend FLOAT real (const complex&) __attribute__ ((const));
+ friend FLOAT imag (const complex&) __attribute__ ((const));
+ friend complex operator + (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator + (const complex&, FLOAT) __attribute__ ((const));
+ friend complex operator + (FLOAT, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, FLOAT) __attribute__ ((const));
+ friend complex operator - (FLOAT, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, FLOAT) __attribute__ ((const));
+ friend complex operator * (FLOAT, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, FLOAT) __attribute__ ((const));
+ friend complex operator / (FLOAT, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, FLOAT) __attribute__ ((const));
+ friend bool operator == (FLOAT, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, FLOAT) __attribute__ ((const));
+ friend bool operator != (FLOAT, const complex&) __attribute__ ((const));
+ friend complex polar (FLOAT, FLOAT) __attribute__ ((const));
+ friend complex pow (const complex&, const complex&) __attribute__ ((const));
+ friend complex pow (const complex&, FLOAT) __attribute__ ((const));
+ friend complex pow (const complex&, int) __attribute__ ((const));
+ friend complex pow (FLOAT, const complex&) __attribute__ ((const));
+ friend istream& operator>> (istream&, complex&);
+ friend ostream& operator<< (ostream&, const complex&);
+};
+
+// Declare specializations.
+class complex<float>;
+class complex<double>;
+class complex<long double>;
+
+template <class FLOAT>
+inline complex<FLOAT>&
+complex<FLOAT>::operator += (const complex<FLOAT>& r)
+{
+ re += r.re;
+ im += r.im;
+ return *this;
+}
+
+template <class FLOAT>
+inline complex<FLOAT>&
+complex<FLOAT>::operator -= (const complex<FLOAT>& r)
+{
+ re -= r.re;
+ im -= r.im;
+ return *this;
+}
+
+template <class FLOAT>
+inline complex<FLOAT>&
+complex<FLOAT>::operator *= (const complex<FLOAT>& r)
+{
+ FLOAT f = re * r.re - im * r.im;
+ im = re * r.im + im * r.re;
+ re = f;
+ return *this;
+}
+
+template <class FLOAT> inline FLOAT
+imag (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return x.imag ();
+}
+
+template <class FLOAT> inline FLOAT
+real (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return x.real ();
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator + (const complex<FLOAT>& x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) + real (y), imag (x) + imag (y));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator + (const complex<FLOAT>& x, FLOAT y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) + y, imag (x));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator + (FLOAT x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return complex<FLOAT> (x + real (y), imag (y));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator - (const complex<FLOAT>& x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) - real (y), imag (x) - imag (y));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator - (const complex<FLOAT>& x, FLOAT y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) - y, imag (x));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator - (FLOAT x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return complex<FLOAT> (x - real (y), - imag (y));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator * (const complex<FLOAT>& x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) * real (y) - imag (x) * imag (y),
+ real (x) * imag (y) + imag (x) * real (y));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator * (const complex<FLOAT>& x, FLOAT y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) * y, imag (x) * y);
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator * (FLOAT x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return complex<FLOAT> (x * real (y), x * imag (y));
+}
+
+template <class FLOAT> complex<FLOAT>
+operator / (const complex<FLOAT>& x, FLOAT y) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x) / y, imag (x) / y);
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator + (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return x;
+}
+
+template <class FLOAT> inline complex<FLOAT>
+operator - (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return complex<FLOAT> (-real (x), -imag (x));
+}
+
+template <class FLOAT> inline bool
+operator == (const complex<FLOAT>& x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return real (x) == real (y) && imag (x) == imag (y);
+}
+
+template <class FLOAT> inline bool
+operator == (const complex<FLOAT>& x, FLOAT y) __attribute__ ((const))
+{
+ return real (x) == y && imag (x) == 0;
+}
+
+template <class FLOAT> inline bool
+operator == (FLOAT x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return x == real (y) && imag (y) == 0;
+}
+
+template <class FLOAT> inline bool
+operator != (const complex<FLOAT>& x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return real (x) != real (y) || imag (x) != imag (y);
+}
+
+template <class FLOAT> inline bool
+operator != (const complex<FLOAT>& x, FLOAT y) __attribute__ ((const))
+{
+ return real (x) != y || imag (x) != 0;
+}
+
+template <class FLOAT> inline bool
+operator != (FLOAT x, const complex<FLOAT>& y) __attribute__ ((const))
+{
+ return x != real (y) || imag (y) != 0;
+}
+
+// Some targets don't provide a prototype for hypot when -ansi.
+extern "C" double hypot (double, double) __attribute__ ((const));
+
+template <class FLOAT> inline FLOAT
+abs (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return hypot (real (x), imag (x));
+}
+
+template <class FLOAT> inline FLOAT
+arg (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return atan2 (imag (x), real (x));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+polar (FLOAT r, FLOAT t) __attribute__ ((const))
+{
+ return complex<FLOAT> (r * cos (t), r * sin (t));
+}
+
+template <class FLOAT> inline complex<FLOAT>
+conj (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return complex<FLOAT> (real (x), -imag (x));
+}
+
+template <class FLOAT> inline FLOAT
+norm (const complex<FLOAT>& x) __attribute__ ((const))
+{
+ return real (x) * real (x) + imag (x) * imag (x);
+}
+
+// Declarations of templates in complext.ccI
+
+template <class FLOAT> complex<FLOAT>
+ operator / (const complex<FLOAT>&, const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ operator / (FLOAT, const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ cos (const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ cosh (const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ exp (const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ log (const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ pow (const complex<FLOAT>&, const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ pow (const complex<FLOAT>&, FLOAT) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ pow (const complex<FLOAT>&, int) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ pow (FLOAT, const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ sin (const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ sinh (const complex<FLOAT>&) __attribute__ ((const));
+template <class FLOAT> complex<FLOAT>
+ sqrt (const complex<FLOAT>&) __attribute__ ((const));
+
+class istream;
+class ostream;
+template <class FLOAT> istream& operator >> (istream&, complex<FLOAT>&);
+template <class FLOAT> ostream& operator << (ostream&, const complex<FLOAT>&);
+} // extern "C++"
+
+// Specializations and such
+
+#include <std/fcomplex.h>
+#include <std/dcomplex.h>
+#include <std/ldcomplex.h>
+
+// Declare the instantiations.
+#include <std/cinst.h>
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/csetjmp.h b/gnu/lib/libg++/libstdc++/std/csetjmp.h
new file mode 100644
index 00000000000..4bba048dcb5
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/csetjmp.h
@@ -0,0 +1,8 @@
+// The -*- C++ -*- setjmp/longjmp header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSETJMP__
+#define __CSETJMP__
+#include <setjmp.h>
+#endif
+
diff --git a/gnu/lib/libg++/libstdc++/std/csignal.h b/gnu/lib/libg++/libstdc++/std/csignal.h
new file mode 100644
index 00000000000..6febfb7b2ed
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/csignal.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- signal handling header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSIGNAL__
+#define __CSIGNAL__
+#include <signal.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cstdarg.h b/gnu/lib/libg++/libstdc++/std/cstdarg.h
new file mode 100644
index 00000000000..24c57f06299
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cstdarg.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- variable argument handling header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDARG__
+#define __CSTDARG__
+#include <stdarg.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cstddef.h b/gnu/lib/libg++/libstdc++/std/cstddef.h
new file mode 100644
index 00000000000..0e025e3d163
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cstddef.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- wrapper for the C standard definitions header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDDEF__
+#define __CSTDDEF__
+#include <stddef.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cstdio.h b/gnu/lib/libg++/libstdc++/std/cstdio.h
new file mode 100644
index 00000000000..1fe1456b5bd
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cstdio.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- standard I/O header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDIO__
+#define __CSTDIO__
+#include <stdio.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cstdlib.h b/gnu/lib/libg++/libstdc++/std/cstdlib.h
new file mode 100644
index 00000000000..51dc00a5af0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cstdlib.h
@@ -0,0 +1,23 @@
+// The -*- C++ -*- standard library header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTDLIB__
+#define __CSTDLIB__
+#include <stdlib.h>
+
+#ifdef __GNUG__
+#pragma interface "std/cstdlib.h"
+#endif
+
+extern "C++" {
+
+#if _G_HAS_LABS
+inline long abs(long x) { return labs (x); }
+#else
+inline long abs(long x) { return x >= 0 ? x : -x; }
+#endif
+//inline ldiv_t div(long x, long y) { return ldiv (x, y); }
+
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cstring.h b/gnu/lib/libg++/libstdc++/std/cstring.h
new file mode 100644
index 00000000000..6d493e7501e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cstring.h
@@ -0,0 +1,71 @@
+// The -*- C++ -*- null-terminated string header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CSTRING__
+#define __CSTRING__
+
+#if 0 // Let's not bother with this just yet.
+// The ANSI C prototypes for these functions have a const argument type and
+// non-const return type, so we can't use them.
+
+#define strchr __hide_strchr
+#define strpbrk __hide_strpbrk
+#define strrchr __hide_strrchr
+#define strstr __hide_strstr
+#define memchr __hide_memchr
+#endif // 0
+
+#include_next <string.h>
+
+#if 0 // Let's not bother with this just yet.
+#undef strchr
+#undef strpbrk
+#undef strrchr
+#undef strstr
+#undef memchr
+
+#include <std/cstddef.h>
+
+#ifdef __GNUG__
+#pragma interface "std/cstring.h"
+#endif
+
+extern "C++" {
+extern "C" const char *strchr (const char *, int);
+inline char *
+strchr (char *s, int c)
+{
+ return const_cast<char *> (strchr (static_cast<const char *> (s), c));
+}
+
+extern "C" const char *strpbrk (const char *, const char *);
+inline char *
+strpbrk (char *s1, const char *s2)
+{
+ return const_cast<char *> (strpbrk (static_cast<const char *> (s1), s2));
+}
+
+extern "C" const char *strrchr (const char *, int);
+inline char *
+strrchr (char *s, int c)
+{
+ return const_cast<char *> (strrchr (static_cast<const char *> (s), c));
+}
+
+extern "C" const char *strstr (const char *, const char *);
+inline char *
+strstr (char *s1, const char *s2)
+{
+ return const_cast<char *> (strstr (static_cast<const char *> (s1), s2));
+}
+
+extern "C" const void *memchr (const void *, int, size_t);
+inline void *
+memchr (void *s, int c, size_t n)
+{
+ return const_cast<void *> (memchr (static_cast<const void *> (s), c, n));
+}
+} // extern "C++"
+
+#endif // 0
+#endif // !defined (__CSTRING__)
diff --git a/gnu/lib/libg++/libstdc++/std/ctime.h b/gnu/lib/libg++/libstdc++/std/ctime.h
new file mode 100644
index 00000000000..0184da5929f
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/ctime.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- time header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CTIME__
+#define __CTIME__
+#include <time.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cwchar.h b/gnu/lib/libg++/libstdc++/std/cwchar.h
new file mode 100644
index 00000000000..1674c12b61f
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cwchar.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- wide character header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CWCHAR__
+#define __CWCHAR__
+#include <wchar.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/cwctype.h b/gnu/lib/libg++/libstdc++/std/cwctype.h
new file mode 100644
index 00000000000..81122012bd0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/cwctype.h
@@ -0,0 +1,7 @@
+// The -*- C++ -*- wide character type header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __CWCTYPE__
+#define __CWCTYPE__
+#include <wctype.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/dcomplex.h b/gnu/lib/libg++/libstdc++/std/dcomplex.h
new file mode 100644
index 00000000000..d3e5d311c63
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/dcomplex.h
@@ -0,0 +1,89 @@
+// The -*- C++ -*- double_complex class.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification in the 27 May 1994
+// C++ working paper, ANSI document X3J16/94-0098.
+
+#ifndef __DCOMPLEX__
+#define __DCOMPLEX__
+
+#ifdef __GNUG__
+#pragma interface "dcomplex"
+#endif
+
+extern "C++" {
+class complex<double>
+{
+public:
+ complex (double r = 0, double i = 0): re (r), im (i) { }
+ complex (const complex<float>& r): re (r.real ()), im (r.imag ()) { }
+ explicit complex (const complex<long double>& r);
+
+ complex& operator+= (const complex&);
+ complex& operator-= (const complex&);
+ complex& operator*= (const complex&);
+ complex& operator/= (const complex&);
+
+ double real () const { return re; }
+ double imag () const { return im; }
+private:
+ double re, im;
+
+ // These functions are specified as friends for purposes of name injection;
+ // they do not actually reference private members.
+ friend double real (const complex& x) { return x.real (); }
+ friend double imag (const complex& x) { return x.imag (); }
+ friend complex operator + (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator + (const complex&, double) __attribute__ ((const));
+ friend complex operator + (double, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, double) __attribute__ ((const));
+ friend complex operator - (double, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, double) __attribute__ ((const));
+ friend complex operator * (double, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, double) __attribute__ ((const));
+ friend complex operator / (double, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, double) __attribute__ ((const));
+ friend bool operator == (double, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, double) __attribute__ ((const));
+ friend bool operator != (double, const complex&) __attribute__ ((const));
+ friend complex polar (double, double) __attribute__ ((const));
+ friend complex pow (const complex&, const complex&) __attribute__ ((const));
+ friend complex pow (const complex&, double) __attribute__ ((const));
+ friend complex pow (const complex&, int) __attribute__ ((const));
+ friend complex pow (double, const complex&) __attribute__ ((const));
+ friend istream& operator>> (istream&, complex&);
+ friend ostream& operator<< (ostream&, const complex&);
+};
+
+inline complex<float>::complex (const complex<double>& r)
+: re (r.real ()), im (r.imag ())
+{ }
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/exception.h b/gnu/lib/libg++/libstdc++/std/exception.h
new file mode 100644
index 00000000000..6de65d8fc10
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/exception.h
@@ -0,0 +1,39 @@
+// Exception Handling header for -*- C++ -*-
+// Copyright (C) 1995 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+#ifndef __EXCEPTION__
+#define __EXCEPTION__
+
+extern "C++" {
+// class XUNEXPECTED { to be specified };
+typedef void (*terminate_handler) ();
+typedef void (*unexpected_handler) ();
+
+terminate_handler set_terminate (terminate_handler);
+void terminate (void);
+unexpected_handler set_unexpected (unexpected_handler);
+void unexpected (void);
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/fcomplex.h b/gnu/lib/libg++/libstdc++/std/fcomplex.h
new file mode 100644
index 00000000000..27f3be7a480
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/fcomplex.h
@@ -0,0 +1,85 @@
+// The -*- C++ -*- float_complex class.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification in the 27 May 1994
+// C++ working paper, ANSI document X3J16/94-0098.
+
+#ifndef __FCOMPLEX__
+#define __FCOMPLEX__
+
+#ifdef __GNUG__
+#pragma interface "fcomplex"
+#endif
+
+extern "C++" {
+class complex<float>
+{
+public:
+ complex (float r = 0, float i = 0): re (r), im (i) { }
+ explicit complex (const complex<double>& r);
+ explicit complex (const complex<long double>& r);
+
+ complex& operator+= (const complex&);
+ complex& operator-= (const complex&);
+ complex& operator*= (const complex&);
+ complex& operator/= (const complex&);
+
+ float real () const { return re; }
+ float imag () const { return im; }
+private:
+ float re, im;
+
+ // These functions are specified as friends for purposes of name injection;
+ // they do not actually reference private members.
+ friend float real (const complex& x) { return x.real (); }
+ friend float imag (const complex& x) { return x.imag (); }
+ friend complex operator + (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator + (const complex&, float) __attribute__ ((const));
+ friend complex operator + (float, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, float) __attribute__ ((const));
+ friend complex operator - (float, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, float) __attribute__ ((const));
+ friend complex operator * (float, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, float) __attribute__ ((const));
+ friend complex operator / (float, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, float) __attribute__ ((const));
+ friend bool operator == (float, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, float) __attribute__ ((const));
+ friend bool operator != (float, const complex&) __attribute__ ((const));
+ friend complex polar (float, float) __attribute__ ((const));
+ friend complex pow (const complex&, const complex&) __attribute__ ((const));
+ friend complex pow (const complex&, float) __attribute__ ((const));
+ friend complex pow (const complex&, int) __attribute__ ((const));
+ friend complex pow (float, const complex&) __attribute__ ((const));
+ friend istream& operator>> (istream&, complex&);
+ friend ostream& operator<< (ostream&, const complex&);
+};
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/ldcomplex.h b/gnu/lib/libg++/libstdc++/std/ldcomplex.h
new file mode 100644
index 00000000000..95f90ae7f0e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/ldcomplex.h
@@ -0,0 +1,93 @@
+// The -*- C++ -*- long_double_complex class.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification in the 27 May 1994
+// C++ working paper, ANSI document X3J16/94-0098.
+
+#ifndef __LDCOMPLEX__
+#define __LDCOMPLEX__
+
+#ifdef __GNUG__
+#pragma interface "ldcomplex"
+#endif
+
+extern "C++" {
+class complex<long double>
+{
+public:
+ complex (long double r = 0, long double i = 0): re (r), im (i) { }
+ complex (const complex<float>& r): re (r.real ()), im (r.imag ()) { }
+ complex (const complex<double>& r): re (r.real ()), im (r.imag ()) { }
+
+ complex& operator+= (const complex&);
+ complex& operator-= (const complex&);
+ complex& operator*= (const complex&);
+ complex& operator/= (const complex&);
+
+ long double real () const { return re; }
+ long double imag () const { return im; }
+private:
+ long double re, im;
+
+ // These functions are specified as friends for purposes of name injection;
+ // they do not actually reference private members.
+ friend long double real (const complex& x) { return x.real (); }
+ friend long double imag (const complex& x) { return x.imag (); }
+ friend complex operator + (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator + (const complex&, long double) __attribute__ ((const));
+ friend complex operator + (long double, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator - (const complex&, long double) __attribute__ ((const));
+ friend complex operator - (long double, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator * (const complex&, long double) __attribute__ ((const));
+ friend complex operator * (long double, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, const complex&) __attribute__ ((const));
+ friend complex operator / (const complex&, long double) __attribute__ ((const));
+ friend complex operator / (long double, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator == (const complex&, long double) __attribute__ ((const));
+ friend bool operator == (long double, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, const complex&) __attribute__ ((const));
+ friend bool operator != (const complex&, long double) __attribute__ ((const));
+ friend bool operator != (long double, const complex&) __attribute__ ((const));
+ friend complex polar (long double, long double) __attribute__ ((const));
+ friend complex pow (const complex&, const complex&) __attribute__ ((const));
+ friend complex pow (const complex&, long double) __attribute__ ((const));
+ friend complex pow (const complex&, int) __attribute__ ((const));
+ friend complex pow (long double, const complex&) __attribute__ ((const));
+ friend istream& operator>> (istream&, complex&);
+ friend ostream& operator<< (ostream&, const complex&);
+};
+
+inline complex<float>::complex (const complex<long double>& r)
+: re (r.real ()), im (r.imag ())
+{ }
+
+inline complex<double>::complex (const complex<long double>& r)
+: re (r.real ()), im (r.imag ())
+{ }
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/new.h b/gnu/lib/libg++/libstdc++/std/new.h
new file mode 100644
index 00000000000..cfdfbebdd63
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/new.h
@@ -0,0 +1,34 @@
+// The -*- C++ -*- dynamic memory management header.
+// Copyright (C) 1994 Free Software Foundation
+
+#ifndef __NEW__
+#define __NEW__
+
+#ifdef __GNUG__
+#pragma interface "std/new.h"
+#endif
+
+#include <std/cstddef.h>
+
+extern "C++" {
+typedef void (*new_handler)();
+extern "C" new_handler set_new_handler (new_handler);
+
+#if defined(__GNUG__) && !defined (__STRICT_ANSI__)
+// G++ implementation internals
+extern new_handler __new_handler;
+extern "C" void __default_new_handler (void);
+#endif
+
+// replaceable signatures
+void *operator new (size_t);
+void *operator new[] (size_t);
+void operator delete (void *);
+void operator delete[] (void *);
+
+// default placement versions of operator new
+inline void *operator new(size_t, void *place) { return place; }
+inline void *operator new[](size_t, void *place) { return place; }
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/sinst.h b/gnu/lib/libg++/libstdc++/std/sinst.h
new file mode 100644
index 00000000000..6bd9bfc6d19
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/sinst.h
@@ -0,0 +1,73 @@
+// Forward declarations of -*- C++ -*- string instantiations.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2.
+
+#ifndef __SINST__
+#define __SINST__
+
+extern "C++" {
+#define __S basic_string<char,string_char_traits<char> >
+//#define __W basic_string<wchar_t,string_char_traits<wchar_t> >
+
+extern template class __bsrep<char, string_char_traits<char> >;
+extern template class __S;
+// extern template class __W;
+// extern template class __bsrep<wchar_t, string_char_traits<wchar_t> >;
+
+#define __DOPR(op, ret, c, s) \
+ extern template ret operator op (const s&, const s&); \
+ extern template ret operator op (const c*, const s&); \
+ extern template ret operator op (const s&, const c*); \
+
+#define __DO(op, ret, c, s) \
+ extern template ret operator op (const s&, const s&); \
+ extern template ret operator op (const c*, const s&); \
+ extern template ret operator op (const s&, const c*); \
+ extern template ret operator op (c, const s&); \
+ extern template ret operator op (const s&, c);
+
+__DO (+, __S, char, __S)
+// __DO (+, __W, wchar_t, __W) */
+
+#define __DOB(op) \
+ __DOPR (op, bool, char, __S)
+// __DOPR (op, bool, wchar_t, __W)
+
+__DOB (==)
+__DOB (!=)
+__DOB (<)
+__DOB (>)
+__DOB (<=)
+__DOB (>=)
+
+#undef __S
+//#undef __W
+#undef __DO
+#undef __DOB
+#undef __DOPR
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/stddef.h b/gnu/lib/libg++/libstdc++/std/stddef.h
new file mode 100644
index 00000000000..00cf47e7a02
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/stddef.h
@@ -0,0 +1,25 @@
+// The -*- C++ -*- standard definitions header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __STDDEF__
+#define __STDDEF__
+
+#ifdef __GNUG__
+#pragma interface "std/stddef.h"
+#endif
+
+#include <_G_config.h>
+#include <std/cstddef.h>
+
+extern "C++" {
+const size_t NPOS = (size_t)(-1);
+typedef void fvoid_t();
+
+#ifndef _WINT_T
+#define _WINT_T
+typedef _G_wint_t wint_t;
+#endif
+
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/stdexcept.h b/gnu/lib/libg++/libstdc++/std/stdexcept.h
new file mode 100644
index 00000000000..785bb6a4223
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/stdexcept.h
@@ -0,0 +1,126 @@
+// Methods for Exception Support for -*- C++ -*-
+// Copyright (C) 1994, 1995 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Mike Stump based upon the specification in the 20 September 1994
+// C++ working paper, ANSI document X3J16/94-0158.
+
+#ifndef __STDEXCEPT__
+#define __STDEXCEPT__
+
+#ifdef __GNUG__
+#pragma interface "std/stdexcept.h"
+#endif
+
+#include <typeinfo>
+
+extern "C++" {
+#if 0
+#include <string>
+typedef string __string;
+#else
+typedef const char * __string;
+#endif
+
+class exception {
+public:
+ typedef void (*raise_handler)(exception&);
+ static raise_handler set_raise_handler(raise_handler handler_arg);
+ exception (const __string& what_arg): desc (what_arg) { }
+ virtual ~exception() { }
+ void raise();
+ virtual __string what() const { return desc; }
+protected:
+ exception() { }
+ virtual void do_raise() { }
+private:
+ __string desc;
+};
+
+class logic_error : public exception {
+public:
+ logic_error(const __string& what_arg): exception (what_arg) { }
+ virtual ~logic_error() { }
+};
+
+class domain_error : public logic_error {
+public:
+ domain_error (const __string& what_arg): logic_error (what_arg) { }
+ virtual ~domain_error () { }
+};
+
+class invalid_argument : public logic_error {
+public:
+ invalid_argument (const __string& what_arg): logic_error (what_arg) { }
+ virtual ~invalid_argument () { }
+};
+
+class length_error : public logic_error {
+public:
+ length_error (const __string& what_arg): logic_error (what_arg) { }
+ virtual ~length_error () { }
+};
+
+class out_of_range : public logic_error {
+public:
+ out_of_range (const __string& what_arg): logic_error (what_arg) { }
+ virtual ~out_of_range () { }
+};
+
+class runtime_error : public exception {
+public:
+ runtime_error(const __string& what_arg): exception (what_arg) { }
+ virtual ~runtime_error() { }
+protected:
+ runtime_error(): exception () { }
+};
+
+class range_error : public runtime_error {
+public:
+ range_error (const __string& what_arg): runtime_error (what_arg) { }
+ virtual ~range_error () { }
+};
+
+class overflow_error : public runtime_error {
+public:
+ overflow_error (const __string& what_arg): runtime_error (what_arg) { }
+ virtual ~overflow_error () { }
+};
+
+// These are moved here from typeinfo so that we can compile with -frtti
+class bad_cast : public logic_error {
+public:
+ bad_cast(const __string& what_arg): logic_error (what_arg) { }
+ virtual ~bad_cast() { }
+};
+
+extern bad_cast __bad_cast_object;
+
+class bad_typeid : public logic_error {
+ public:
+ bad_typeid (): logic_error ("bad_typeid") { }
+ virtual ~bad_typeid () { }
+};
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/straits.h b/gnu/lib/libg++/libstdc++/std/straits.h
new file mode 100644
index 00000000000..42fbad37fe9
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/straits.h
@@ -0,0 +1,161 @@
+// Character traits template for the -*- C++ -*- string classes.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Jason Merrill based upon the specification by Takanori Adachi
+// in ANSI X3J16/94-0013R2.
+
+#ifndef __STRING_CHAR_TRAITS__
+#define __STRING_CHAR_TRAITS__
+
+#ifdef __GNUG__
+// For string_char_traits <char>
+#pragma interface "std/straits.h"
+#endif
+
+#include <std/stddef.h>
+
+extern "C++" {
+template <class charT>
+struct string_char_traits {
+ typedef charT char_type; // for users to acquire the basic character type
+
+ // constraints
+
+ static void assign (char_type& c1, const char_type& c2)
+ { c1 = c2; }
+ static bool eq (const char_type& c1, const char_type& c2)
+ { return (c1 == c2); }
+ static bool ne (const char_type& c1, const char_type& c2)
+ { return !(c1 == c2); }
+ static bool lt (const char_type& c1, const char_type& c2)
+ { return (c1 < c2); }
+ static char_type eos () { return char_type(); } // the null character
+ static bool is_del(char_type a) { return 0; }
+ // characteristic function for delimiters of charT
+
+ // speed-up functions
+
+ static int compare (const char_type* s1, const char_type* s2, size_t n)
+ {
+ size_t i;
+ for (i = 0; i < n; ++i)
+ if (ne (s1[i], s2[i]))
+ return lt (s1[i], s2[i]) ? -1 : 1;
+
+ return 0;
+ }
+
+ static size_t length (const char_type* s)
+ {
+ size_t l = 0;
+ while (ne (*s++, eos ()))
+ ++l;
+ return l;
+ }
+
+ static char_type* copy (char_type* s1, const char_type* s2, size_t n)
+ {
+ for (; n--; )
+ assign (s1[n], s2[n]);
+ return s1;
+ }
+
+ static char_type* move (char_type* s1, const char_type* s2, size_t n)
+ {
+ char_type a[n];
+ size_t i;
+ for (i = 0; i < n; ++i)
+ assign (a[i], s2[i]);
+ for (i = 0; i < n; ++i)
+ assign (s1[i], a[i]);
+ return s1;
+ }
+
+ static char_type* set (char_type* s1, const char_type& c, size_t n)
+ {
+ for (; n--; )
+ assign (s1[n], c);
+ return s1;
+ }
+};
+
+class istream;
+class ostream;
+#include <std/cctype.h>
+#include <std/cstring.h>
+
+struct string_char_traits <char> {
+ typedef char char_type;
+
+ static void assign (char_type& c1, const char_type& c2)
+ { c1 = c2; }
+ static bool eq (const char_type & c1, const char_type& c2)
+ { return (c1 == c2); }
+ static bool ne (const char_type& c1, const char_type& c2)
+ { return (c1 != c2); }
+ static bool lt (const char_type& c1, const char_type& c2)
+ { return (c1 < c2); }
+ static char_type eos () { return 0; }
+ static bool is_del(char_type a) { return isspace(a); }
+
+ static int compare (const char_type* s1, const char_type* s2, size_t n)
+ { return memcmp (s1, s2, n); }
+ static size_t length (const char_type* s)
+ { return strlen (s); }
+ static char_type* copy (char_type* s1, const char_type* s2, size_t n)
+ { return (char_type*) memcpy (s1, s2, n); }
+ static char_type* move (char_type* s1, const char_type* s2, size_t n)
+ { return (char_type*) memmove (s1, s2, n); }
+ static char_type* set (char_type* s1, const char_type& c, size_t n)
+ { return (char_type*) memset (s1, c, n); }
+};
+
+#if 0
+#include <std/cwctype.h>
+struct string_char_traits <wchar_t> {
+ typedef wchar_t char_type;
+
+ static void assign (char_type& c1, const char_type& c2)
+ { c1 = c2; }
+ static bool eq (const char_type & c1, const char_type& c2)
+ { return (c1 == c2); }
+ static bool ne (const char_type& c1, const char_type& c2)
+ { return (c1 != c2); }
+ static bool lt (const char_type& c1, const char_type& c2)
+ { return (c1 < c2); }
+ static char_type eos () { return 0; }
+ static bool is_del(char_type a) { return iswspace(a); }
+
+ static int compare (const char_type* s1, const char_type* s2, size_t n)
+ { return wmemcmp (s1, s2, n); }
+ static size_t length (const char_type* s)
+ { return wcslen (s); }
+ static char_type* copy (char_type* s1, const char_type* s2, size_t n)
+ { return wmemcpy (s1, s2, n); }
+ static char_type* set (char_type* s1, const char_type& c, size_t n)
+ { return wmemset (s1, c, n); }
+};
+#endif
+} // extern "C++"
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/string.h b/gnu/lib/libg++/libstdc++/std/string.h
new file mode 100644
index 00000000000..77cc801be16
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/string.h
@@ -0,0 +1,13 @@
+// Main header for the -*- C++ -*- string classes.
+
+#ifndef __STRING__
+#define __STRING__
+
+#include <std/bastring.h>
+
+extern "C++" {
+typedef basic_string <char, string_char_traits <char> > string;
+// typedef basic_string <wchar_t, string_char_traits <wchar_t> > wstring;
+} // extern "C++"
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/std/typeinfo.h b/gnu/lib/libg++/libstdc++/std/typeinfo.h
new file mode 100644
index 00000000000..44f833cd685
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/std/typeinfo.h
@@ -0,0 +1,245 @@
+// RTTI support for -*- C++ -*-
+// Copyright (C) 1994, 1995 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Kung Hsu based upon the specification in the 20 September 1994
+// C++ working paper, ANSI document X3J16/94-0158.
+
+#ifndef __TYPEINFO__
+#define __TYPEINFO__
+
+#ifdef __GNUG__
+#pragma interface "std/typeinfo.h"
+#endif
+
+extern "C" void* __throw_type_match_rtti (void *, void *, void *);
+
+extern "C++" {
+class type_info {
+private:
+ // assigning type_info is not supported. made private.
+ type_info& operator=(const type_info&);
+ type_info(const type_info&);
+
+public:
+ enum node_type {
+ _RTTI_BUILTIN_TYPE, // builtin type
+ _RTTI_USER_TYPE, // user defined type
+ _RTTI_CLASS_TYPE, // class type
+ _RTTI_POINTER_TYPE, // pointer type
+ _RTTI_ATTR_TYPE, // attribute type for const and volatile
+ _RTTI_FUNC_TYPE, // function type
+ _RTTI_PTMF_TYPE, // pointer to member function type
+ _RTTI_PTMD_TYPE // pointer to member data type
+ };
+
+ // return node type of the object
+ virtual node_type __rtti_get_node_type() const { return _RTTI_BUILTIN_TYPE; }
+
+ // get_name will return the name of the type, NULL if no name (like builtin)
+ virtual const char * __rtti_get_name() const { return 0; }
+
+ // compare if type represented by the type_info are the same type
+ virtual int __rtti_compare(const type_info&) const { return 0; }
+
+ // argument passed is the desired type,
+ // for class type, if the type can be converted to the desired type,
+ // it will be, and returned, else 0 is returned. If the match
+ // succeeds, the return value will be adjusted to point to the sub-object.
+ virtual void* __rtti_match(const type_info&, int, void *) const {
+ // This should never be called.
+ return 0;
+ };
+
+ // destructor
+ virtual ~type_info() {}
+ type_info() {}
+
+ bool before(const type_info& arg);
+ const char* name() const
+ { return __rtti_get_name(); }
+ bool operator==(const type_info& arg) const
+ { return __rtti_compare(arg) == 0; }
+ bool operator!=(const type_info& arg) const
+ { return __rtti_compare(arg) != 0; }
+};
+
+// type_info for builtin type
+
+class __builtin_type_info : public type_info {
+public:
+ enum builtin_type_val {
+ _RTTI_BI_BOOL = 1, _RTTI_BI_CHAR, _RTTI_BI_SHORT, _RTTI_BI_INT,
+ _RTTI_BI_LONG, _RTTI_BI_LONGLONG, _RTTI_BI_FLOAT,
+ _RTTI_BI_DOUBLE, _RTTI_BI_LDOUBLE, _RTTI_BI_UCHAR,
+ _RTTI_BI_USHORT, _RTTI_BI_UINT, _RTTI_BI_ULONG,
+ _RTTI_BI_ULONGLONG, _RTTI_BI_SCHAR, _RTTI_BI_WCHAR, _RTTI_BI_VOID
+ };
+
+ builtin_type_val b_type;
+
+ __builtin_type_info (builtin_type_val bt) : b_type (bt) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_BUILTIN_TYPE; }
+ const char *__rtti_get_name () const
+ { return (const char *)0; }
+ int __rtti_compare (const type_info& arg) const
+ { return (arg.__rtti_get_node_type () == _RTTI_BUILTIN_TYPE &&
+ ((__builtin_type_info&)arg).b_type == b_type) ? 0 : -1; }
+};
+
+// serice function for comparing types by name.
+
+inline int __fast_compare (const char *n1, const char *n2) {
+ int c;
+ if (n1 == n2) return 0;
+ if (n1 == 0) return *n2;
+ else if (n2 == 0) return *n1;
+
+ c = (int)*n1++ - (int)*n2++;
+ return c == 0 ? strcmp (n1, n2) : c;
+};
+
+// type_info for user type.
+
+class __user_type_info : public type_info {
+ private:
+ const char *_name;
+
+public:
+ __user_type_info (const char *nm) : _name (nm) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_USER_TYPE; }
+ const char *__rtti_get_name () const
+ { return _name; }
+ int __rtti_compare (const type_info& arg) const
+ { return (arg.__rtti_get_node_type () == __rtti_get_node_type() &&
+ __fast_compare (_name, arg.__rtti_get_name ()) == 0) ? 0 : -1; }
+};
+
+// type_info for a class.
+
+class __class_type_info : public __user_type_info {
+private:
+ enum access_mode {
+ _RTTI_ACCESS_PUBLIC, _RTTI_ACCESS_PROTECTED, _RTTI_ACCESS_PRIVATE
+ };
+ type_info **base_list;
+ int *offset_list;
+ int *is_virtual_list;
+ access_mode *access_list;
+ int n_bases;
+
+public:
+ __class_type_info (const char *name, type_info **bl, int *off,
+ int *is_vir, access_mode *acc, int bn)
+ : __user_type_info (name), base_list (bl), offset_list(off),
+ is_virtual_list(is_vir), access_list(acc), n_bases (bn) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_CLASS_TYPE; }
+
+ // inherit __rtti_compare from __user_type_info
+
+ // This is a little complex defined in typeinfo.cc
+ void* __rtti_match(const type_info&, int, void *) const;
+};
+
+// type info for pointer type.
+
+class __pointer_type_info : public type_info {
+private:
+ type_info& type;
+
+public:
+ __pointer_type_info (type_info& ti) : type (ti) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_POINTER_TYPE; }
+ const char *__rtti_get_name () const
+ { return (const char *)0; }
+ int __rtti_compare (const type_info& arg) const
+ { return (arg.__rtti_get_node_type () == __rtti_get_node_type() &&
+ type.__rtti_compare ( ((__pointer_type_info&)arg).type) == 0) ? 0 : -1; }
+ void* __rtti_match(const type_info& catch_type, int, void *objptr) const;
+};
+
+// type info for attributes
+
+class __attr_type_info : public type_info {
+public:
+ enum attr_val {
+ _RTTI_ATTR_CONST = 1, _RTTI_ATTR_VOLATILE, _RTTI_ATTR_CONSTVOL
+ };
+
+ attr_val attr;
+ type_info& type;
+
+ __attr_type_info (attr_val a, type_info& t) : attr (a), type(t) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_ATTR_TYPE; }
+ const char *__rtti_get_name () const
+ { return (const char *)0; }
+ int __rtti_compare (const type_info& arg) const
+ { return (arg.__rtti_get_node_type () == _RTTI_ATTR_TYPE &&
+ attr == ((__attr_type_info&)arg).attr &&
+ type.__rtti_compare ( ((__attr_type_info&)arg).type ) == 0)
+ ? 0 : -1; }
+};
+
+// type info for function.
+
+class __func_type_info : public __user_type_info {
+public:
+ __func_type_info (const char *name) : __user_type_info (name) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_FUNC_TYPE; }
+};
+
+// type info for pointer to member function.
+
+class __ptmf_type_info : public __user_type_info {
+public:
+ __ptmf_type_info (const char *name) : __user_type_info (name) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_PTMF_TYPE; }
+};
+
+// type info for pointer to data member.
+
+class __ptmd_type_info : public type_info {
+ type_info& classtype;
+ type_info& type;
+public:
+ __ptmd_type_info (type_info& tc, type_info& t) : classtype (tc), type (t) {}
+ node_type __rtti_get_node_type () const
+ { return _RTTI_PTMD_TYPE; }
+ int __rtti_compare (const type_info& arg) const
+ { return (arg.__rtti_get_node_type () == _RTTI_PTMD_TYPE &&
+ classtype.__rtti_compare ( ((__ptmd_type_info&)arg).classtype ) == 0 &&
+ type.__rtti_compare ( ((__ptmd_type_info&)arg).type ) == 0)
+ ? 0 : -1; }
+};
+} // extern "C++"
+
+#include <stdexcept>
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stddef b/gnu/lib/libg++/libstdc++/stddef
new file mode 100644
index 00000000000..9bfd4a91782
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stddef
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __STDDEF__
+#include <std/stddef.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stddefi.cc b/gnu/lib/libg++/libstdc++/stddefi.cc
new file mode 100644
index 00000000000..b49c42c945c
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stddefi.cc
@@ -0,0 +1,7 @@
+// Implementation file for the -*- C++ -*- standard definitions header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifdef __GNUG__
+#pragma implementation "std/stddef.h"
+#endif
+#include <std/stddef.h>
diff --git a/gnu/lib/libg++/libstdc++/stdexcept b/gnu/lib/libg++/libstdc++/stdexcept
new file mode 100644
index 00000000000..560c53dd888
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stdexcept
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __STDEXCEPT__
+#include <std/stdexcept.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stdexcepti.cc b/gnu/lib/libg++/libstdc++/stdexcepti.cc
new file mode 100644
index 00000000000..4025f5ba187
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stdexcepti.cc
@@ -0,0 +1,8 @@
+// Implementation file for Exception Support for -*- C++ -*-
+// This file is part of the GNU ANSI C++ Library.
+
+#ifdef __GNUG__
+#pragma implementation "std/stdexcept.h"
+#endif
+
+#include <stdexcept>
diff --git a/gnu/lib/libg++/libstdc++/stl.h b/gnu/lib/libg++/libstdc++/stl.h
new file mode 100644
index 00000000000..4b270742c9c
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl.h
@@ -0,0 +1,15 @@
+// -*- C++ -*- compatibility header.
+// This file is part of the GNU ANSI C++ Library.
+
+#include <algorithm>
+#include <deque>
+#include <functional>
+#include <iterator>
+#include <list>
+#include <map>
+#include <memory>
+#include <numeric>
+#include <set>
+#include <stack>
+#include <utility>
+#include <vector>
diff --git a/gnu/lib/libg++/libstdc++/stl/algo.h b/gnu/lib/libg++/libstdc++/stl/algo.h
new file mode 100644
index 00000000000..e038d715a25
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/algo.h
@@ -0,0 +1,2386 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef ALGO_H
+#define ALGO_H
+
+#include <stdlib.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+#include <pair.h>
+#include <iterator.h>
+#include <algobase.h>
+#include <heap.h>
+#include <tempbuf.h>
+
+template <class T>
+inline const T& __median(const T& a, const T& b, const T& c) {
+ if (a < b)
+ if (b < c)
+ return b;
+ else if (a < c)
+ return c;
+ else
+ return a;
+ else if (a < c)
+ return a;
+ else if (b < c)
+ return c;
+ else
+ return b;
+}
+
+template <class T, class Compare>
+inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
+ if (comp(a, b))
+ if (comp(b, c))
+ return b;
+ else if (comp(a, c))
+ return c;
+ else
+ return a;
+ else if (comp(a, c))
+ return a;
+ else if (comp(b, c))
+ return c;
+ else
+ return b;
+}
+
+template <class InputIterator, class Function>
+Function for_each(InputIterator first, InputIterator last, Function f) {
+ while (first != last) f(*first++);
+ return f;
+}
+
+template <class InputIterator, class T>
+InputIterator find(InputIterator first, InputIterator last, const T& value) {
+ while (first != last && *first != value) ++first;
+ return first;
+}
+
+template <class InputIterator, class Predicate>
+InputIterator find_if(InputIterator first, InputIterator last,
+ Predicate pred) {
+ while (first != last && !pred(*first)) ++first;
+ return first;
+}
+
+template <class ForwardIterator>
+ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
+ if (first == last) return last;
+ ForwardIterator next = first;
+ while(++next != last) {
+ if (*first == *next) return first;
+ first = next;
+ }
+ return last;
+}
+
+template <class ForwardIterator, class BinaryPredicate>
+ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
+ BinaryPredicate binary_pred) {
+ if (first == last) return last;
+ ForwardIterator next = first;
+ while(++next != last) {
+ if (binary_pred(*first, *next)) return first;
+ first = next;
+ }
+ return last;
+}
+
+template <class InputIterator, class T, class Size>
+void count(InputIterator first, InputIterator last, const T& value,
+ Size& n) {
+ while (first != last)
+ if (*first++ == value) ++n;
+}
+
+template <class InputIterator, class Predicate, class Size>
+void count_if(InputIterator first, InputIterator last, Predicate pred,
+ Size& n) {
+ while (first != last)
+ if (pred(*first++)) ++n;
+}
+
+template <class ForwardIterator1, class ForwardIterator2, class Distance1,
+ class Distance2>
+ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2,
+ Distance1*, Distance2*) {
+ Distance1 d1 = 0;
+ distance(first1, last1, d1);
+ Distance2 d2 = 0;
+ distance(first2, last2, d2);
+
+ if (d1 < d2) return last1;
+
+ ForwardIterator1 current1 = first1;
+ ForwardIterator2 current2 = first2;
+
+ while (current2 != last2)
+ if (*current1++ != *current2++)
+ if (d1-- == d2)
+ return last1;
+ else {
+ current1 = ++first1;
+ current2 = first2;
+ }
+ return (current2 == last2) ? first1 : last1;
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2)
+{
+ return __search(first1, last1, first2, last2, distance_type(first1),
+ distance_type(first2));
+}
+
+template <class ForwardIterator1, class ForwardIterator2,
+ class BinaryPredicate, class Distance1, class Distance2>
+ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2,
+ BinaryPredicate binary_pred, Distance1*, Distance2*) {
+ Distance1 d1 = 0;
+ distance(first1, last1, d1);
+ Distance2 d2 = 0;
+ distance(first2, last2, d2);
+
+ if (d1 < d2) return last1;
+
+ ForwardIterator1 current1 = first1;
+ ForwardIterator2 current2 = first2;
+
+ while (current2 != last2)
+ if (!binary_pred(*current1++, *current2++))
+ if (d1-- == d2)
+ return last1;
+ else {
+ current1 = ++first1;
+ current2 = first2;
+ }
+ return (current2 == last2) ? first1 : last1;
+}
+
+template <class ForwardIterator1, class ForwardIterator2,
+ class BinaryPredicate>
+inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
+ ForwardIterator2 first2, ForwardIterator2 last2,
+ BinaryPredicate binary_pred) {
+ return __search(first1, last1, first2, last2, binary_pred,
+ distance_type(first1), distance_type(first2));
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
+ ForwardIterator2 first2) {
+ while (first1 != last1) iter_swap(first1++, first2++);
+ return first2;
+}
+
+template <class InputIterator, class OutputIterator, class UnaryOperation>
+OutputIterator transform(InputIterator first, InputIterator last,
+ OutputIterator result, UnaryOperation op) {
+ while (first != last) *result++ = op(*first++);
+ return result;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+ class BinaryOperation>
+OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, OutputIterator result,
+ BinaryOperation binary_op) {
+ while (first1 != last1) *result++ = binary_op(*first1++, *first2++);
+ return result;
+}
+
+template <class ForwardIterator, class T>
+void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
+ const T& new_value) {
+ while (first != last) {
+ if (*first == old_value) *first = new_value;
+ ++first;
+ }
+}
+
+template <class ForwardIterator, class Predicate, class T>
+void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
+ const T& new_value) {
+ while (first != last) {
+ if (pred(*first)) *first = new_value;
+ ++first;
+ }
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator replace_copy(InputIterator first, InputIterator last,
+ OutputIterator result, const T& old_value,
+ const T& new_value) {
+ while (first != last) {
+ *result++ = *first == old_value ? new_value : *first;
+ ++first;
+ }
+ return result;
+}
+
+template <class Iterator, class OutputIterator, class Predicate, class T>
+OutputIterator replace_copy_if(Iterator first, Iterator last,
+ OutputIterator result, Predicate pred,
+ const T& new_value) {
+ while (first != last) {
+ *result++ = pred(*first) ? new_value : *first;
+ ++first;
+ }
+ return result;
+}
+
+template <class ForwardIterator, class Generator>
+void generate(ForwardIterator first, ForwardIterator last, Generator gen) {
+ while (first != last) *first++ = gen();
+}
+
+template <class OutputIterator, class Size, class Generator>
+OutputIterator generate_n(OutputIterator first, Size n, Generator gen) {
+ while (n-- > 0) *first++ = gen();
+ return first;
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator remove_copy(InputIterator first, InputIterator last,
+ OutputIterator result, const T& value) {
+ while (first != last) {
+ if (*first != value) *result++ = *first;
+ ++first;
+ }
+ return result;
+}
+
+template <class InputIterator, class OutputIterator, class Predicate>
+OutputIterator remove_copy_if(InputIterator first, InputIterator last,
+ OutputIterator result, Predicate pred) {
+ while (first != last) {
+ if (!pred(*first)) *result++ = *first;
+ ++first;
+ }
+ return result;
+}
+
+template <class ForwardIterator, class T>
+ForwardIterator remove(ForwardIterator first, ForwardIterator last,
+ const T& value) {
+ first = find(first, last, value);
+ ForwardIterator next = first;
+ return first == last ? first : remove_copy(++next, last, first, value);
+}
+
+template <class ForwardIterator, class Predicate>
+ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
+ Predicate pred) {
+ first = find_if(first, last, pred);
+ ForwardIterator next = first;
+ return first == last ? first : remove_copy_if(++next, last, first, pred);
+}
+
+template <class InputIterator, class ForwardIterator>
+ForwardIterator __unique_copy(InputIterator first, InputIterator last,
+ ForwardIterator result, forward_iterator_tag) {
+ *result = *first;
+ while (++first != last)
+ if (*result != *first) *++result = *first;
+ return ++result;
+}
+
+template <class InputIterator, class BidirectionalIterator>
+inline BidirectionalIterator __unique_copy(InputIterator first,
+ InputIterator last,
+ BidirectionalIterator result,
+ bidirectional_iterator_tag) {
+ return __unique_copy(first, last, result, forward_iterator_tag());
+}
+
+template <class InputIterator, class RandomAccessIterator>
+inline RandomAccessIterator __unique_copy(InputIterator first,
+ InputIterator last,
+ RandomAccessIterator result,
+ random_access_iterator_tag) {
+ return __unique_copy(first, last, result, forward_iterator_tag());
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator __unique_copy(InputIterator first, InputIterator last,
+ OutputIterator result, T*) {
+ T value = *first;
+ *result = value;
+ while (++first != last)
+ if (value != *first) {
+ value = *first;
+ *++result = value;
+ }
+ return ++result;
+}
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
+ OutputIterator result,
+ output_iterator_tag) {
+ return __unique_copy(first, last, result, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator unique_copy(InputIterator first, InputIterator last,
+ OutputIterator result) {
+ if (first == last) return result;
+ return __unique_copy(first, last, result, iterator_category(result));
+}
+template <class InputIterator, class ForwardIterator, class BinaryPredicate>
+ForwardIterator __unique_copy(InputIterator first, InputIterator last,
+ ForwardIterator result,
+ BinaryPredicate binary_pred,
+ forward_iterator_tag) {
+ *result = *first;
+ while (++first != last)
+ if (!binary_pred(*result, *first)) *++result = *first;
+ return ++result;
+}
+
+template <class InputIterator, class BidirectionalIterator,
+ class BinaryPredicate>
+inline BidirectionalIterator __unique_copy(InputIterator first,
+ InputIterator last,
+ BidirectionalIterator result,
+ BinaryPredicate binary_pred,
+ bidirectional_iterator_tag) {
+ return __unique_copy(first, last, result, binary_pred,
+ forward_iterator_tag());
+}
+
+template <class InputIterator, class RandomAccessIterator,
+ class BinaryPredicate>
+inline RandomAccessIterator __unique_copy(InputIterator first,
+ InputIterator last,
+ RandomAccessIterator result,
+ BinaryPredicate binary_pred,
+ random_access_iterator_tag) {
+ return __unique_copy(first, last, result, binary_pred,
+ forward_iterator_tag());
+}
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate,
+ class T>
+OutputIterator __unique_copy(InputIterator first, InputIterator last,
+ OutputIterator result,
+ BinaryPredicate binary_pred, T*) {
+ T value = *first;
+ *result = value;
+ while (++first != last)
+ if (!binary_pred(value, *first)) {
+ value = *first;
+ *++result = value;
+ }
+ return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate>
+inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
+ OutputIterator result,
+ BinaryPredicate binary_pred,
+ output_iterator_tag) {
+ return __unique_copy(first, last, result, binary_pred, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate>
+inline OutputIterator unique_copy(InputIterator first, InputIterator last,
+ OutputIterator result,
+ BinaryPredicate binary_pred) {
+ if (first == last) return result;
+ return __unique_copy(first, last, result, binary_pred,
+ iterator_category(result));
+}
+
+template <class ForwardIterator>
+ForwardIterator unique(ForwardIterator first, ForwardIterator last) {
+ first = adjacent_find(first, last);
+ return unique_copy(first, last, first);
+}
+
+template <class ForwardIterator, class BinaryPredicate>
+ForwardIterator unique(ForwardIterator first, ForwardIterator last,
+ BinaryPredicate binary_pred) {
+ first = adjacent_find(first, last, binary_pred);
+ return unique_copy(first, last, first, binary_pred);
+}
+
+template <class BidirectionalIterator>
+void __reverse(BidirectionalIterator first, BidirectionalIterator last,
+ bidirectional_iterator_tag) {
+ while (true)
+ if (first == last || first == --last)
+ return;
+ else
+ iter_swap(first++, last);
+}
+
+template <class RandomAccessIterator>
+void __reverse(RandomAccessIterator first, RandomAccessIterator last,
+ random_access_iterator_tag) {
+ while (first < last) iter_swap(first++, --last);
+}
+
+template <class BidirectionalIterator>
+inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
+ __reverse(first, last, iterator_category(first));
+}
+
+template <class BidirectionalIterator, class OutputIterator>
+OutputIterator reverse_copy(BidirectionalIterator first,
+ BidirectionalIterator last,
+ OutputIterator result) {
+ while (first != last) *result++ = *--last;
+ return result;
+}
+
+template <class ForwardIterator, class Distance>
+void __rotate(ForwardIterator first, ForwardIterator middle,
+ ForwardIterator last, Distance*, forward_iterator_tag) {
+ for (ForwardIterator i = middle; ;) {
+ iter_swap(first++, i++);
+ if (first == middle) {
+ if (i == last) return;
+ middle = i;
+ } else if (i == last)
+ i = middle;
+ }
+}
+
+template <class BidirectionalIterator, class Distance>
+void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
+ BidirectionalIterator last, Distance*,
+ bidirectional_iterator_tag) {
+ reverse(first, middle);
+ reverse(middle, last);
+ reverse(first, last);
+}
+
+template <class EuclideanRingElement>
+EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
+{
+ while (n != 0) {
+ EuclideanRingElement t = m % n;
+ m = n;
+ n = t;
+ }
+ return m;
+}
+
+template <class RandomAccessIterator, class Distance, class T>
+void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
+ RandomAccessIterator initial, Distance shift, T*) {
+ T value = *initial;
+ RandomAccessIterator ptr1 = initial;
+ RandomAccessIterator ptr2 = ptr1 + shift;
+ while (ptr2 != initial) {
+ *ptr1 = *ptr2;
+ ptr1 = ptr2;
+ if (last - ptr2 > shift)
+ ptr2 += shift;
+ else
+ ptr2 = first + (shift - (last - ptr2));
+ }
+ *ptr1 = value;
+}
+
+template <class RandomAccessIterator, class Distance>
+void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
+ RandomAccessIterator last, Distance*,
+ random_access_iterator_tag) {
+ Distance n = __gcd(last - first, middle - first);
+ while (n--)
+ __rotate_cycle(first, last, first + n, middle - first,
+ value_type(first));
+}
+
+template <class ForwardIterator>
+inline void rotate(ForwardIterator first, ForwardIterator middle,
+ ForwardIterator last) {
+ if (first == middle || middle == last) return;
+ __rotate(first, middle, last, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class OutputIterator>
+OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
+ ForwardIterator last, OutputIterator result) {
+ return copy(first, middle, copy(middle, last, result));
+}
+
+unsigned long __long_random(unsigned long);
+
+template <class RandomAccessIterator, class Distance>
+void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+ Distance*) {
+ if (first == last) return;
+ for (RandomAccessIterator i = first + 1; i != last; ++i)
+ iter_swap(i, first + Distance(__long_random((i - first) + 1)));
+}
+
+template <class RandomAccessIterator>
+inline void random_shuffle(RandomAccessIterator first,
+ RandomAccessIterator last) {
+ __random_shuffle(first, last, distance_type(first));
+}
+
+template <class RandomAccessIterator, class RandomNumberGenerator>
+void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+ RandomNumberGenerator& __rand) {
+ if (first == last) return;
+ for (RandomAccessIterator i = first + 1; i != last; ++i)
+ iter_swap(i, first + __rand((i - first) + 1));
+}
+
+template <class BidirectionalIterator, class Predicate>
+BidirectionalIterator partition(BidirectionalIterator first,
+ BidirectionalIterator last, Predicate pred) {
+ while (true) {
+ while (true)
+ if (first == last)
+ return first;
+ else if (pred(*first))
+ ++first;
+ else
+ break;
+ --last;
+ while (true)
+ if (first == last)
+ return first;
+ else if (!pred(*last))
+ --last;
+ else
+ break;
+ iter_swap(first, last);
+ ++first;
+ }
+}
+
+template <class ForwardIterator, class Predicate, class Distance>
+ForwardIterator __inplace_stable_partition(ForwardIterator first,
+ ForwardIterator last,
+ Predicate pred, Distance len) {
+ if (len == 1) return pred(*first) ? last : first;
+ ForwardIterator middle = first;
+ advance(middle, len / 2);
+ ForwardIterator
+ first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
+ ForwardIterator
+ second_cut = __inplace_stable_partition(middle, last, pred,
+ len - len / 2);
+ rotate(first_cut, middle, second_cut);
+ len = 0;
+ distance(middle, second_cut, len);
+ advance(first_cut, len);
+ return first_cut;
+}
+
+template <class ForwardIterator, class Pointer, class Predicate,
+ class Distance, class T>
+ForwardIterator __stable_partition_adaptive(ForwardIterator first,
+ ForwardIterator last,
+ Predicate pred, Distance len,
+ Pointer buffer,
+ Distance buffer_size,
+ Distance& fill_pointer, T*) {
+ if (len <= buffer_size) {
+ len = 0;
+ ForwardIterator result1 = first;
+ Pointer result2 = buffer;
+ while (first != last && len < fill_pointer)
+ if (pred(*first))
+ *result1++ = *first++;
+ else {
+ *result2++ = *first++;
+ ++len;
+ }
+ if (first != last) {
+ raw_storage_iterator<Pointer, T> result3 = result2;
+ while (first != last)
+ if (pred(*first))
+ *result1++ = *first++;
+ else {
+ *result3++ = *first++;
+ ++len;
+ }
+ fill_pointer = len;
+ }
+ copy(buffer, buffer + len, result1);
+ return result1;
+ }
+ ForwardIterator middle = first;
+ advance(middle, len / 2);
+ ForwardIterator first_cut = __stable_partition_adaptive
+ (first, middle, pred, len / 2, buffer, buffer_size, fill_pointer,
+ (T*)0);
+ ForwardIterator second_cut = __stable_partition_adaptive
+ (middle, last, pred, len - len / 2, buffer, buffer_size,
+ fill_pointer, (T*)0);
+ rotate(first_cut, middle, second_cut);
+ len = 0;
+ distance(middle, second_cut, len);
+ advance(first_cut, len);
+ return first_cut;
+}
+
+template <class ForwardIterator, class Predicate, class Pointer,
+ class Distance>
+ForwardIterator __stable_partition(ForwardIterator first, ForwardIterator last,
+ Predicate pred, Distance len,
+ pair<Pointer, Distance> p) {
+ if (p.first == 0)
+ return __inplace_stable_partition(first, last, pred, len);
+ Distance fill_pointer = 0;
+ ForwardIterator result =
+ __stable_partition_adaptive(first, last, pred, len, p.first, p.second,
+ fill_pointer, value_type(first));
+ destroy(p.first, p.first + fill_pointer);
+ return_temporary_buffer(p.first);
+ return result;
+}
+
+template <class ForwardIterator, class Predicate, class Distance>
+inline ForwardIterator __stable_partition_aux(ForwardIterator first,
+ ForwardIterator last,
+ Predicate pred, Distance*) {
+ Distance len = 0;
+ distance(first, last, len);
+ return __stable_partition(first, last, pred, len,
+ get_temporary_buffer(len, value_type(first)));
+}
+
+template <class ForwardIterator, class Predicate>
+inline ForwardIterator stable_partition(ForwardIterator first,
+ ForwardIterator last,
+ Predicate pred) {
+ return __stable_partition_aux(first, last, pred, distance_type(first));
+}
+
+template <class RandomAccessIterator, class T>
+RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
+ RandomAccessIterator last,
+ T pivot) {
+ while (1) {
+ while (*first < pivot) ++first;
+ --last;
+ while (pivot < *last) --last;
+ if (!(first < last)) return first;
+ iter_swap(first, last);
+ ++first;
+ }
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+RandomAccessIterator __unguarded_partition(RandomAccessIterator first,
+ RandomAccessIterator last,
+ T pivot, Compare comp) {
+ while (1) {
+ while (comp(*first, pivot)) ++first;
+ --last;
+ while (comp(pivot, *last)) --last;
+ if (!(first < last)) return first;
+ iter_swap(first, last);
+ ++first;
+ }
+}
+
+const int __stl_threshold = 16;
+
+template <class RandomAccessIterator, class T>
+void __quick_sort_loop_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*) {
+ while (last - first > __stl_threshold) {
+ RandomAccessIterator cut = __unguarded_partition
+ (first, last, T(__median(*first, *(first + (last - first)/2),
+ *(last - 1))));
+ if (cut - first >= last - cut) {
+ __quick_sort_loop(cut, last);
+ last = cut;
+ } else {
+ __quick_sort_loop(first, cut);
+ first = cut;
+ }
+ }
+}
+
+template <class RandomAccessIterator>
+inline void __quick_sort_loop(RandomAccessIterator first,
+ RandomAccessIterator last) {
+ __quick_sort_loop_aux(first, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __quick_sort_loop_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*, Compare comp) {
+ while (last - first > __stl_threshold) {
+ RandomAccessIterator cut = __unguarded_partition
+ (first, last, T(__median(*first, *(first + (last - first)/2),
+ *(last - 1), comp)), comp);
+ if (cut - first >= last - cut) {
+ __quick_sort_loop(cut, last, comp);
+ last = cut;
+ } else {
+ __quick_sort_loop(first, cut, comp);
+ first = cut;
+ }
+ }
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void __quick_sort_loop(RandomAccessIterator first,
+ RandomAccessIterator last, Compare comp) {
+ __quick_sort_loop_aux(first, last, value_type(first), comp);
+}
+
+template <class RandomAccessIterator, class T>
+void __unguarded_linear_insert(RandomAccessIterator last, T value) {
+ RandomAccessIterator next = last;
+ --next;
+ while (value < *next) {
+ *last = *next;
+ last = next--;
+ }
+ *last = value;
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __unguarded_linear_insert(RandomAccessIterator last, T value,
+ Compare comp) {
+ RandomAccessIterator next = last;
+ --next;
+ while (comp(value , *next)) {
+ *last = *next;
+ last = next--;
+ }
+ *last = value;
+}
+
+template <class RandomAccessIterator, class T>
+inline void __linear_insert(RandomAccessIterator first,
+ RandomAccessIterator last, T*) {
+ T value = *last;
+ if (value < *first) {
+ copy_backward(first, last, last + 1);
+ *first = value;
+ } else
+ __unguarded_linear_insert(last, value);
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+inline void __linear_insert(RandomAccessIterator first,
+ RandomAccessIterator last, T*, Compare comp) {
+ T value = *last;
+ if (comp(value, *first)) {
+ copy_backward(first, last, last + 1);
+ *first = value;
+ } else
+ __unguarded_linear_insert(last, value, comp);
+}
+
+template <class RandomAccessIterator>
+void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
+ if (first == last) return;
+ for (RandomAccessIterator i = first + 1; i != last; ++i)
+ __linear_insert(first, i, value_type(first));
+}
+
+template <class RandomAccessIterator, class Compare>
+void __insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last, Compare comp) {
+ if (first == last) return;
+ for (RandomAccessIterator i = first + 1; i != last; ++i)
+ __linear_insert(first, i, value_type(first), comp);
+}
+
+template <class RandomAccessIterator, class T>
+void __unguarded_insertion_sort_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*) {
+ for (RandomAccessIterator i = first; i != last; ++i)
+ __unguarded_linear_insert(i, T(*i));
+}
+
+template <class RandomAccessIterator>
+inline void __unguarded_insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last) {
+ __unguarded_insertion_sort_aux(first, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __unguarded_insertion_sort_aux(RandomAccessIterator first,
+ RandomAccessIterator last,
+ T*, Compare comp) {
+ for (RandomAccessIterator i = first; i != last; ++i)
+ __unguarded_linear_insert(i, T(*i), comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void __unguarded_insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last,
+ Compare comp) {
+ __unguarded_insertion_sort_aux(first, last, value_type(first), comp);
+}
+
+template <class RandomAccessIterator>
+void __final_insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last) {
+ if (last - first > __stl_threshold) {
+ __insertion_sort(first, first + __stl_threshold);
+ __unguarded_insertion_sort(first + __stl_threshold, last);
+ } else
+ __insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator, class Compare>
+void __final_insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last, Compare comp) {
+ if (last - first > __stl_threshold) {
+ __insertion_sort(first, first + __stl_threshold, comp);
+ __unguarded_insertion_sort(first + __stl_threshold, last, comp);
+ } else
+ __insertion_sort(first, last, comp);
+}
+
+template <class RandomAccessIterator>
+void sort(RandomAccessIterator first, RandomAccessIterator last) {
+ __quick_sort_loop(first, last);
+ __final_insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator, class Compare>
+void sort(RandomAccessIterator first, RandomAccessIterator last,
+ Compare comp) {
+ __quick_sort_loop(first, last, comp);
+ __final_insertion_sort(first, last, comp);
+}
+
+template <class RandomAccessIterator>
+void __inplace_stable_sort(RandomAccessIterator first,
+ RandomAccessIterator last) {
+ if (last - first < 15) {
+ __insertion_sort(first, last);
+ return;
+ }
+ RandomAccessIterator middle = first + (last - first) / 2;
+ __inplace_stable_sort(first, middle);
+ __inplace_stable_sort(middle, last);
+ __merge_without_buffer(first, middle, last, middle - first, last - middle);
+}
+
+template <class RandomAccessIterator, class Compare>
+void __inplace_stable_sort(RandomAccessIterator first,
+ RandomAccessIterator last, Compare comp) {
+ if (last - first < 15) {
+ __insertion_sort(first, last, comp);
+ return;
+ }
+ RandomAccessIterator middle = first + (last - first) / 2;
+ __inplace_stable_sort(first, middle, comp);
+ __inplace_stable_sort(middle, last, comp);
+ __merge_without_buffer(first, middle, last, middle - first,
+ last - middle, comp);
+}
+
+template <class RandomAccessIterator1, class RandomAccessIterator2,
+ class Distance>
+void __merge_sort_loop(RandomAccessIterator1 first,
+ RandomAccessIterator1 last,
+ RandomAccessIterator2 result, Distance step_size) {
+ Distance two_step = 2 * step_size;
+
+ while (last - first >= two_step) {
+ result = merge(first, first + step_size,
+ first + step_size, first + two_step, result);
+ first += two_step;
+ }
+ step_size = min(Distance(last - first), step_size);
+
+ merge(first, first + step_size, first + step_size, last, result);
+}
+
+template <class RandomAccessIterator1, class RandomAccessIterator2,
+ class Distance, class Compare>
+void __merge_sort_loop(RandomAccessIterator1 first,
+ RandomAccessIterator1 last,
+ RandomAccessIterator2 result, Distance step_size,
+ Compare comp) {
+ Distance two_step = 2 * step_size;
+
+ while (last - first >= two_step) {
+ result = merge(first, first + step_size,
+ first + step_size, first + two_step, result, comp);
+ first += two_step;
+ }
+ step_size = min(Distance(last - first), step_size);
+
+ merge(first, first + step_size, first + step_size, last, result, comp);
+}
+
+const int __stl_chunk_size = 7;
+
+template <class RandomAccessIterator, class Distance>
+void __chunk_insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last, Distance chunk_size) {
+ while (last - first >= chunk_size) {
+ __insertion_sort(first, first + chunk_size);
+ first += chunk_size;
+ }
+ __insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator, class Distance, class Compare>
+void __chunk_insertion_sort(RandomAccessIterator first,
+ RandomAccessIterator last,
+ Distance chunk_size, Compare comp) {
+ while (last - first >= chunk_size) {
+ __insertion_sort(first, first + chunk_size, comp);
+ first += chunk_size;
+ }
+ __insertion_sort(first, last, comp);
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, class T>
+void __merge_sort_with_buffer(RandomAccessIterator first,
+ RandomAccessIterator last,
+ Pointer buffer, Distance*, T*) {
+ Distance len = last - first;
+ Pointer buffer_last = buffer + len;
+
+ Distance step_size = __stl_chunk_size;
+ __chunk_insertion_sort(first, last, step_size);
+
+ while (step_size < len) {
+ __merge_sort_loop(first, last, buffer, step_size);
+ step_size *= 2;
+ __merge_sort_loop(buffer, buffer_last, first, step_size);
+ step_size *= 2;
+ }
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, class T,
+ class Compare>
+void __merge_sort_with_buffer(RandomAccessIterator first,
+ RandomAccessIterator last, Pointer buffer,
+ Distance*, T*, Compare comp) {
+ Distance len = last - first;
+ Pointer buffer_last = buffer + len;
+
+ Distance step_size = __stl_chunk_size;
+ __chunk_insertion_sort(first, last, step_size, comp);
+
+ while (step_size < len) {
+ __merge_sort_loop(first, last, buffer, step_size, comp);
+ step_size *= 2;
+ __merge_sort_loop(buffer, buffer_last, first, step_size, comp);
+ step_size *= 2;
+ }
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, class T>
+void __stable_sort_adaptive(RandomAccessIterator first,
+ RandomAccessIterator last, Pointer buffer,
+ Distance buffer_size, T*) {
+ Distance len = (last - first + 1) / 2;
+ RandomAccessIterator middle = first + len;
+ if (len > buffer_size) {
+ __stable_sort_adaptive(first, middle, buffer, buffer_size, (T*)0);
+ __stable_sort_adaptive(middle, last, buffer, buffer_size, (T*)0);
+ } else {
+ __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, (T*)0);
+ __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, (T*)0);
+ }
+ __merge_adaptive(first, middle, last, Distance(middle - first),
+ Distance(last - middle), buffer, buffer_size, (T*)0);
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, class T,
+ class Compare>
+void __stable_sort_adaptive(RandomAccessIterator first,
+ RandomAccessIterator last, Pointer buffer,
+ Distance buffer_size, T*, Compare comp) {
+ Distance len = (last - first + 1) / 2;
+ RandomAccessIterator middle = first + len;
+ if (len > buffer_size) {
+ __stable_sort_adaptive(first, middle, buffer, buffer_size, (T*)0, comp);
+ __stable_sort_adaptive(middle, last, buffer, buffer_size, (T*)0, comp);
+ } else {
+ __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, (T*)0,
+ comp);
+ __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, (T*)0,
+ comp);
+ }
+ __merge_adaptive(first, middle, last, Distance(middle - first),
+ Distance(last - middle), buffer, buffer_size, (T*)0, comp);
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, class T>
+inline void __stable_sort(RandomAccessIterator first,
+ RandomAccessIterator last,
+ pair<Pointer, Distance> p, T*) {
+ if (p.first == 0) {
+ __inplace_stable_sort(first, last);
+ return;
+ }
+ Distance len = min(p.second, last - first);
+ copy(first, first + len, raw_storage_iterator<Pointer, T>(p.first));
+ __stable_sort_adaptive(first, last, p.first, p.second, (T*)0);
+ destroy(p.first, p.first + len);
+ return_temporary_buffer(p.first);
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, class T,
+ class Compare>
+inline void __stable_sort(RandomAccessIterator first,
+ RandomAccessIterator last,
+ pair<Pointer, Distance> p, T*, Compare comp) {
+ if (p.first == 0) {
+ __inplace_stable_sort(first, last, comp);
+ return;
+ }
+ Distance len = min(p.second, last - first);
+ copy(first, first + len, raw_storage_iterator<Pointer, T>(p.first));
+ __stable_sort_adaptive(first, last, p.first, p.second, (T*)0, comp);
+ destroy(p.first, p.first + len);
+ return_temporary_buffer(p.first);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+inline void __stable_sort_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*, Distance*) {
+ __stable_sort(first, last, get_temporary_buffer(Distance(last - first),
+ (T*)0), (T*)0);
+}
+
+template <class RandomAccessIterator, class T, class Distance, class Compare>
+inline void __stable_sort_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*, Distance*,
+ Compare comp) {
+ __stable_sort(first, last, get_temporary_buffer(Distance(last - first),
+ (T*)0), (T*)0, comp);
+}
+
+template <class RandomAccessIterator>
+inline void stable_sort(RandomAccessIterator first,
+ RandomAccessIterator last) {
+ __stable_sort_aux(first, last, value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void stable_sort(RandomAccessIterator first,
+ RandomAccessIterator last, Compare comp) {
+ __stable_sort_aux(first, last, value_type(first), distance_type(first),
+ comp);
+}
+
+template <class RandomAccessIterator, class T>
+void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
+ RandomAccessIterator last, T*) {
+ make_heap(first, middle);
+ for (RandomAccessIterator i = middle; i < last; ++i)
+ if (*i < *first)
+ __pop_heap(first, middle, i, T(*i), distance_type(first));
+ sort_heap(first, middle);
+}
+
+template <class RandomAccessIterator>
+inline void partial_sort(RandomAccessIterator first,
+ RandomAccessIterator middle,
+ RandomAccessIterator last) {
+ __partial_sort(first, middle, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
+ RandomAccessIterator last, T*, Compare comp) {
+ make_heap(first, middle, comp);
+ for (RandomAccessIterator i = middle; i < last; ++i)
+ if (comp(*i, *first))
+ __pop_heap(first, middle, i, T(*i), comp, distance_type(first));
+ sort_heap(first, middle, comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void partial_sort(RandomAccessIterator first,
+ RandomAccessIterator middle,
+ RandomAccessIterator last, Compare comp) {
+ __partial_sort(first, middle, last, value_type(first), comp);
+}
+
+template <class InputIterator, class RandomAccessIterator, class Distance,
+ class T>
+RandomAccessIterator __partial_sort_copy(InputIterator first,
+ InputIterator last,
+ RandomAccessIterator result_first,
+ RandomAccessIterator result_last,
+ Distance*, T*) {
+ if (result_first == result_last) return result_last;
+ RandomAccessIterator result_real_last = result_first;
+ while(first != last && result_real_last != result_last)
+ *result_real_last++ = *first++;
+ make_heap(result_first, result_real_last);
+ while (first != last) {
+ if (*first < *result_first)
+ __adjust_heap(result_first, Distance(0),
+ Distance(result_real_last - result_first), T(*first));
+ ++first;
+ }
+ sort_heap(result_first, result_real_last);
+ return result_real_last;
+}
+
+template <class InputIterator, class RandomAccessIterator>
+inline RandomAccessIterator
+partial_sort_copy(InputIterator first, InputIterator last,
+ RandomAccessIterator result_first,
+ RandomAccessIterator result_last) {
+ return __partial_sort_copy(first, last, result_first, result_last,
+ distance_type(result_first), value_type(first));
+}
+
+template <class InputIterator, class RandomAccessIterator, class Compare,
+ class Distance, class T>
+RandomAccessIterator __partial_sort_copy(InputIterator first,
+ InputIterator last,
+ RandomAccessIterator result_first,
+ RandomAccessIterator result_last,
+ Compare comp, Distance*, T*) {
+ if (result_first == result_last) return result_last;
+ RandomAccessIterator result_real_last = result_first;
+ while(first != last && result_real_last != result_last)
+ *result_real_last++ = *first++;
+ make_heap(result_first, result_real_last, comp);
+ while (first != last) {
+ if (comp(*first, *result_first))
+ __adjust_heap(result_first, Distance(0),
+ Distance(result_real_last - result_first), T(*first),
+ comp);
+ ++first;
+ }
+ sort_heap(result_first, result_real_last, comp);
+ return result_real_last;
+}
+
+template <class InputIterator, class RandomAccessIterator, class Compare>
+inline RandomAccessIterator
+partial_sort_copy(InputIterator first, InputIterator last,
+ RandomAccessIterator result_first,
+ RandomAccessIterator result_last, Compare comp) {
+ return __partial_sort_copy(first, last, result_first, result_last, comp,
+ distance_type(result_first), value_type(first));
+}
+
+template <class RandomAccessIterator, class T>
+void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+ RandomAccessIterator last, T*) {
+ while (last - first > 3) {
+ RandomAccessIterator cut = __unguarded_partition
+ (first, last, T(__median(*first, *(first + (last - first)/2),
+ *(last - 1))));
+ if (cut <= nth)
+ first = cut;
+ else
+ last = cut;
+ }
+ __insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator>
+inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+ RandomAccessIterator last) {
+ __nth_element(first, nth, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+ RandomAccessIterator last, T*, Compare comp) {
+ while (last - first > 3) {
+ RandomAccessIterator cut = __unguarded_partition
+ (first, last, T(__median(*first, *(first + (last - first)/2),
+ *(last - 1), comp)), comp);
+ if (cut <= nth)
+ first = cut;
+ else
+ last = cut;
+ }
+ __insertion_sort(first, last, comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+ RandomAccessIterator last, Compare comp) {
+ __nth_element(first, nth, last, value_type(first), comp);
+}
+
+template <class ForwardIterator, class T, class Distance>
+ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
+ const T& value, Distance*,
+ forward_iterator_tag) {
+ Distance len = 0;
+ distance(first, last, len);
+ Distance half;
+ ForwardIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first;
+ advance(middle, half);
+ if (*middle < value) {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ } else
+ len = half;
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T, class Distance>
+inline ForwardIterator __lower_bound(ForwardIterator first,
+ ForwardIterator last,
+ const T& value, Distance*,
+ bidirectional_iterator_tag) {
+ return __lower_bound(first, last, value, (Distance*)0,
+ forward_iterator_tag());
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+RandomAccessIterator __lower_bound(RandomAccessIterator first,
+ RandomAccessIterator last, const T& value,
+ Distance*, random_access_iterator_tag) {
+ Distance len = last - first;
+ Distance half;
+ RandomAccessIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first + half;
+ if (*middle < value) {
+ first = middle + 1;
+ len = len - half - 1;
+ } else
+ len = half;
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T>
+inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
+ const T& value) {
+ return __lower_bound(first, last, value, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
+ const T& value, Compare comp, Distance*,
+ forward_iterator_tag) {
+ Distance len = 0;
+ distance(first, last, len);
+ Distance half;
+ ForwardIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first;
+ advance(middle, half);
+ if (comp(*middle, value)) {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ } else
+ len = half;
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+inline ForwardIterator __lower_bound(ForwardIterator first,
+ ForwardIterator last,
+ const T& value, Compare comp, Distance*,
+ bidirectional_iterator_tag) {
+ return __lower_bound(first, last, value, comp, (Distance*)0,
+ forward_iterator_tag());
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+RandomAccessIterator __lower_bound(RandomAccessIterator first,
+ RandomAccessIterator last,
+ const T& value, Compare comp, Distance*,
+ random_access_iterator_tag) {
+ Distance len = last - first;
+ Distance half;
+ RandomAccessIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first + half;
+ if (comp(*middle, value)) {
+ first = middle + 1;
+ len = len - half - 1;
+ } else
+ len = half;
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T, class Compare>
+inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
+ const T& value, Compare comp) {
+ return __lower_bound(first, last, value, comp, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Distance>
+ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
+ const T& value, Distance*,
+ forward_iterator_tag) {
+ Distance len = 0;
+ distance(first, last, len);
+ Distance half;
+ ForwardIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first;
+ advance(middle, half);
+ if (value < *middle)
+ len = half;
+ else {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T, class Distance>
+inline ForwardIterator __upper_bound(ForwardIterator first,
+ ForwardIterator last,
+ const T& value, Distance*,
+ bidirectional_iterator_tag) {
+ return __upper_bound(first, last, value, (Distance*)0,
+ forward_iterator_tag());
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+RandomAccessIterator __upper_bound(RandomAccessIterator first,
+ RandomAccessIterator last, const T& value,
+ Distance*, random_access_iterator_tag) {
+ Distance len = last - first;
+ Distance half;
+ RandomAccessIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first + half;
+ if (value < *middle)
+ len = half;
+ else {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T>
+inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
+ const T& value) {
+ return __upper_bound(first, last, value, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
+ const T& value, Compare comp, Distance*,
+ forward_iterator_tag) {
+ Distance len = 0;
+ distance(first, last, len);
+ Distance half;
+ ForwardIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first;
+ advance(middle, half);
+ if (comp(value, *middle))
+ len = half;
+ else {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+inline ForwardIterator __upper_bound(ForwardIterator first,
+ ForwardIterator last,
+ const T& value, Compare comp, Distance*,
+ bidirectional_iterator_tag) {
+ return __upper_bound(first, last, value, comp, (Distance*)0,
+ forward_iterator_tag());
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+RandomAccessIterator __upper_bound(RandomAccessIterator first,
+ RandomAccessIterator last,
+ const T& value, Compare comp, Distance*,
+ random_access_iterator_tag) {
+ Distance len = last - first;
+ Distance half;
+ RandomAccessIterator middle;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first + half;
+ if (comp(value, *middle))
+ len = half;
+ else {
+ first = middle + 1;
+ len = len - half - 1;
+ }
+ }
+ return first;
+}
+
+template <class ForwardIterator, class T, class Compare>
+inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
+ const T& value, Compare comp) {
+ return __upper_bound(first, last, value, comp, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Distance>
+pair<ForwardIterator, ForwardIterator>
+__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+ Distance*, forward_iterator_tag) {
+ Distance len = 0;
+ distance(first, last, len);
+ Distance half;
+ ForwardIterator middle, left, right;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first;
+ advance(middle, half);
+ if (*middle < value) {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ } else if (value < *middle)
+ len = half;
+ else {
+ left = lower_bound(first, middle, value);
+ advance(first, len);
+ right = upper_bound(++middle, first, value);
+ return pair<ForwardIterator, ForwardIterator>(left, right);
+ }
+ }
+ return pair<ForwardIterator, ForwardIterator>(first, first);
+}
+
+template <class ForwardIterator, class T, class Distance>
+inline pair<ForwardIterator, ForwardIterator>
+__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+ Distance*, bidirectional_iterator_tag) {
+ return __equal_range(first, last, value, (Distance*)0,
+ forward_iterator_tag());
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+pair<RandomAccessIterator, RandomAccessIterator>
+__equal_range(RandomAccessIterator first, RandomAccessIterator last,
+ const T& value, Distance*, random_access_iterator_tag) {
+ Distance len = last - first;
+ Distance half;
+ RandomAccessIterator middle, left, right;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first + half;
+ if (*middle < value) {
+ first = middle + 1;
+ len = len - half - 1;
+ } else if (value < *middle)
+ len = half;
+ else {
+ left = lower_bound(first, middle, value);
+ right = upper_bound(++middle, first + len, value);
+ return pair<RandomAccessIterator, RandomAccessIterator>(left,
+ right);
+ }
+ }
+ return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
+}
+
+template <class ForwardIterator, class T>
+inline pair<ForwardIterator, ForwardIterator>
+equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
+ return __equal_range(first, last, value, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+pair<ForwardIterator, ForwardIterator>
+__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+ Compare comp, Distance*, forward_iterator_tag) {
+ Distance len = 0;
+ distance(first, last, len);
+ Distance half;
+ ForwardIterator middle, left, right;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first;
+ advance(middle, half);
+ if (comp(*middle, value)) {
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ } else if (comp(value, *middle))
+ len = half;
+ else {
+ left = lower_bound(first, middle, value, comp);
+ advance(first, len);
+ right = upper_bound(++middle, first, value, comp);
+ return pair<ForwardIterator, ForwardIterator>(left, right);
+ }
+ }
+ return pair<ForwardIterator, ForwardIterator>(first, first);
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+inline pair<ForwardIterator, ForwardIterator>
+__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+ Compare comp, Distance*, bidirectional_iterator_tag) {
+ return __equal_range(first, last, value, comp, (Distance*)0,
+ forward_iterator_tag());
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+pair<RandomAccessIterator, RandomAccessIterator>
+__equal_range(RandomAccessIterator first, RandomAccessIterator last,
+ const T& value, Compare comp, Distance*,
+ random_access_iterator_tag) {
+ Distance len = last - first;
+ Distance half;
+ RandomAccessIterator middle, left, right;
+
+ while (len > 0) {
+ half = len / 2;
+ middle = first + half;
+ if (comp(*middle, value)) {
+ first = middle + 1;
+ len = len - half - 1;
+ } else if (comp(value, *middle))
+ len = half;
+ else {
+ left = lower_bound(first, middle, value, comp);
+ right = upper_bound(++middle, first + len, value, comp);
+ return pair<RandomAccessIterator, RandomAccessIterator>(left,
+ right);
+ }
+ }
+ return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
+}
+
+template <class ForwardIterator, class T, class Compare>
+inline pair<ForwardIterator, ForwardIterator>
+equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+ Compare comp) {
+ return __equal_range(first, last, value, comp, distance_type(first),
+ iterator_category(first));
+}
+
+template <class ForwardIterator, class T>
+bool binary_search(ForwardIterator first, ForwardIterator last,
+ const T& value) {
+ ForwardIterator i = lower_bound(first, last, value);
+ return i != last && !(value < *i);
+}
+
+template <class ForwardIterator, class T, class Compare>
+bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
+ Compare comp) {
+ ForwardIterator i = lower_bound(first, last, value, comp);
+ return i != last && !comp(value, *i);
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result) {
+ while (first1 != last1 && first2 != last2)
+ if (*first2 < *first1)
+ *result++ = *first2++;
+ else
+ *result++ = *first1++;
+ return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+ class Compare>
+OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result, Compare comp) {
+ while (first1 != last1 && first2 != last2)
+ if (comp(*first2, *first1))
+ *result++ = *first2++;
+ else
+ *result++ = *first1++;
+ return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class BidirectionalIterator, class Distance>
+void __merge_without_buffer(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last,
+ Distance len1, Distance len2) {
+ if (len1 == 0 || len2 == 0) return;
+ if (len1 + len2 == 2) {
+ if (*middle < *first) iter_swap(first, middle);
+ return;
+ }
+ BidirectionalIterator first_cut = first;
+ BidirectionalIterator second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2) {
+ len11 = len1 / 2;
+ advance(first_cut, len11);
+ second_cut = lower_bound(middle, last, *first_cut);
+ distance(middle, second_cut, len22);
+ } else {
+ len22 = len2 / 2;
+ advance(second_cut, len22);
+ first_cut = upper_bound(first, middle, *second_cut);
+ distance(first, first_cut, len11);
+ }
+ rotate(first_cut, middle, second_cut);
+ BidirectionalIterator new_middle = first_cut;
+ advance(new_middle, len22);
+ __merge_without_buffer(first, first_cut, new_middle, len11, len22);
+ __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
+ len2 - len22);
+}
+
+template <class BidirectionalIterator, class Distance, class Compare>
+void __merge_without_buffer(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last,
+ Distance len1, Distance len2, Compare comp) {
+ if (len1 == 0 || len2 == 0) return;
+ if (len1 + len2 == 2) {
+ if (comp(*middle, *first)) iter_swap(first, middle);
+ return;
+ }
+ BidirectionalIterator first_cut = first;
+ BidirectionalIterator second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2) {
+ len11 = len1 / 2;
+ advance(first_cut, len11);
+ second_cut = lower_bound(middle, last, *first_cut, comp);
+ distance(middle, second_cut, len22);
+ } else {
+ len22 = len2 / 2;
+ advance(second_cut, len22);
+ first_cut = upper_bound(first, middle, *second_cut, comp);
+ distance(first, first_cut, len11);
+ }
+ rotate(first_cut, middle, second_cut);
+ BidirectionalIterator new_middle = first_cut;
+ advance(new_middle, len22);
+ __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
+ __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
+ len2 - len22, comp);
+}
+
+
+template <class InputIterator, class OutputIterator>
+OutputIterator __borland_bugfix_copy(InputIterator first, InputIterator last,
+ OutputIterator result) {
+// this is used in __rotate_adaptive to work around some obscure Borland
+// bug. It is the same as copy, but with a different (and appropriate) name.
+ while (first != last) *result++ = *first++;
+ return result;
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+ class Distance>
+BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
+ BidirectionalIterator1 middle,
+ BidirectionalIterator1 last,
+ Distance len1, Distance len2,
+ BidirectionalIterator2 buffer,
+ Distance buffer_size) {
+ BidirectionalIterator2 buffer_end;
+ if (len1 > len2 && len2 <= buffer_size) {
+ buffer_end = __borland_bugfix_copy(middle, last, buffer);
+ copy_backward(first, middle, last);
+ return copy(buffer, buffer_end, first);
+ } else if (len1 <= buffer_size) {
+ buffer_end = __borland_bugfix_copy(first, middle, buffer);
+ copy(middle, last, first);
+ return copy_backward(buffer, buffer_end, last);
+ } else {
+ rotate(first, middle, last);
+ advance(first, len2);
+ return first;
+ }
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+ class BidirectionalIterator3>
+BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
+ BidirectionalIterator1 last1,
+ BidirectionalIterator2 first2,
+ BidirectionalIterator2 last2,
+ BidirectionalIterator3 result) {
+ if (first1 == last1) return copy_backward(first2, last2, result);
+ if (first2 == last2) return copy_backward(first1, last1, result);
+ --last1;
+ --last2;
+ while (true) {
+ if (*last2 < *last1) {
+ *--result = *last1;
+ if (first1 == last1) return copy_backward(first2, ++last2, result);
+ --last1;
+ } else {
+ *--result = *last2;
+ if (first2 == last2) return copy_backward(first1, ++last1, result);
+ --last2;
+ }
+ }
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+ class BidirectionalIterator3, class Compare>
+BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
+ BidirectionalIterator1 last1,
+ BidirectionalIterator2 first2,
+ BidirectionalIterator2 last2,
+ BidirectionalIterator3 result,
+ Compare comp) {
+ if (first1 == last1) return copy_backward(first2, last2, result);
+ if (first2 == last2) return copy_backward(first1, last1, result);
+ --last1;
+ --last2;
+ while (true) {
+ if (comp(*last2, *last1)) {
+ *--result = *last1;
+ if (first1 == last1) return copy_backward(first2, ++last2, result);
+ --last1;
+ } else {
+ *--result = *last2;
+ if (first2 == last2) return copy_backward(first1, ++last1, result);
+ --last2;
+ }
+ }
+}
+
+template <class BidirectionalIterator, class Distance, class Pointer, class T>
+void __merge_adaptive(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, Distance len1, Distance len2,
+ Pointer buffer, Distance buffer_size, T*) {
+ if (len1 <= len2 && len1 <= buffer_size) {
+ Pointer end_buffer = copy(first, middle, buffer);
+ merge(buffer, end_buffer, middle, last, first);
+ } else if (len2 <= buffer_size) {
+ Pointer end_buffer = copy(middle, last, buffer);
+ __merge_backward(first, middle, buffer, end_buffer, last);
+ } else {
+ BidirectionalIterator first_cut = first;
+ BidirectionalIterator second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2) {
+ len11 = len1 / 2;
+ advance(first_cut, len11);
+ second_cut = lower_bound(middle, last, *first_cut);
+ distance(middle, second_cut, len22);
+ } else {
+ len22 = len2 / 2;
+ advance(second_cut, len22);
+ first_cut = upper_bound(first, middle, *second_cut);
+ distance(first, first_cut, len11);
+ }
+ BidirectionalIterator new_middle =
+ __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
+ len22, buffer, buffer_size);
+ __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
+ buffer_size, (T*)0);
+ __merge_adaptive(new_middle, second_cut, last, len1 - len11,
+ len2 - len22, buffer, buffer_size, (T*)0);
+ }
+}
+
+template <class BidirectionalIterator, class Distance, class Pointer, class T,
+ class Compare>
+void __merge_adaptive(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, Distance len1, Distance len2,
+ Pointer buffer, Distance buffer_size, T*, Compare comp) {
+ if (len1 <= len2 && len1 <= buffer_size) {
+ Pointer end_buffer = copy(first, middle, buffer);
+ merge(buffer, end_buffer, middle, last, first, comp);
+ } else if (len2 <= buffer_size) {
+ Pointer end_buffer = copy(middle, last, buffer);
+ __merge_backward(first, middle, buffer, end_buffer, last, comp);
+ } else {
+ BidirectionalIterator first_cut = first;
+ BidirectionalIterator second_cut = middle;
+ Distance len11 = 0;
+ Distance len22 = 0;
+ if (len1 > len2) {
+ len11 = len1 / 2;
+ advance(first_cut, len11);
+ second_cut = lower_bound(middle, last, *first_cut, comp);
+ distance(middle, second_cut, len22);
+ } else {
+ len22 = len2 / 2;
+ advance(second_cut, len22);
+ first_cut = upper_bound(first, middle, *second_cut, comp);
+ distance(first, first_cut, len11);
+ }
+ BidirectionalIterator new_middle =
+ __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
+ len22, buffer, buffer_size);
+ __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
+ buffer_size, (T*)0, comp);
+ __merge_adaptive(new_middle, second_cut, last, len1 - len11,
+ len2 - len22, buffer, buffer_size, (T*)0, comp);
+ }
+}
+
+template <class BidirectionalIterator, class Distance, class Pointer, class T>
+void __inplace_merge(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, Distance len1, Distance len2,
+ pair<Pointer, Distance> p, T*) {
+ if (p.first == 0) {
+ __merge_without_buffer(first, middle, last, len1, len2);
+ return;
+ }
+ Distance len = min(p.second, len1 + len2);
+ fill_n(raw_storage_iterator<Pointer, T>(p.first), len, *first);
+ __merge_adaptive(first, middle, last, len1, len2, p.first, p.second, (T*)0);
+ destroy(p.first, p.first + len);
+ return_temporary_buffer(p.first);
+}
+
+template <class BidirectionalIterator, class Distance, class Pointer, class T,
+ class Compare>
+void __inplace_merge(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, Distance len1, Distance len2,
+ pair<Pointer, Distance> p, T*, Compare comp) {
+ if (p.first == 0) {
+ __merge_without_buffer(first, middle, last, len1, len2, comp);
+ return;
+ }
+ Distance len = min(p.second, len1 + len2);
+ fill_n(raw_storage_iterator<Pointer, T>(p.first), len, *first);
+ __merge_adaptive(first, middle, last, len1, len2, p.first, p.second, (T*)0,
+ comp);
+ destroy(p.first, p.first + len);
+ return_temporary_buffer(p.first);
+}
+
+template <class BidirectionalIterator, class T, class Distance>
+inline void __inplace_merge_aux(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, T*, Distance*) {
+ Distance len1 = 0;
+ distance(first, middle, len1);
+ Distance len2 = 0;
+ distance(middle, last, len2);
+ __inplace_merge(first, middle, last, len1, len2,
+ get_temporary_buffer(len1 + len2, (T*)0), (T*)0);
+}
+
+template <class BidirectionalIterator, class T, class Distance, class Compare>
+inline void __inplace_merge_aux(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, T*, Distance*,
+ Compare comp) {
+ Distance len1 = 0;
+ distance(first, middle, len1);
+ Distance len2 = 0;
+ distance(middle, last, len2);
+ __inplace_merge(first, middle, last, len1, len2,
+ get_temporary_buffer(len1 + len2, (T*)0), (T*)0,
+ comp);
+}
+
+template <class BidirectionalIterator>
+inline void inplace_merge(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last) {
+ if (first == middle || middle == last) return;
+ __inplace_merge_aux(first, middle, last, value_type(first),
+ distance_type(first));
+}
+
+template <class BidirectionalIterator, class Compare>
+inline void inplace_merge(BidirectionalIterator first,
+ BidirectionalIterator middle,
+ BidirectionalIterator last, Compare comp) {
+ if (first == middle || middle == last) return;
+ __inplace_merge_aux(first, middle, last, value_type(first),
+ distance_type(first), comp);
+}
+
+template <class InputIterator1, class InputIterator2>
+bool includes(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2) {
+ while (first1 != last1 && first2 != last2)
+ if (*first2 < *first1)
+ return false;
+ else if(*first1 < *first2)
+ ++first1;
+ else
+ ++first1, ++first2;
+
+ return first2 == last2;
+}
+
+template <class InputIterator1, class InputIterator2, class Compare>
+bool includes(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2, Compare comp) {
+ while (first1 != last1 && first2 != last2)
+ if (comp(*first2, *first1))
+ return false;
+ else if(comp(*first1, *first2))
+ ++first1;
+ else
+ ++first1, ++first2;
+
+ return first2 == last2;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result) {
+ while (first1 != last1 && first2 != last2)
+ if (*first1 < *first2)
+ *result++ = *first1++;
+ else if (*first2 < *first1)
+ *result++ = *first2++;
+ else {
+ *result++ = *first1++;
+ first2++;
+ }
+ return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+ class Compare>
+OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result, Compare comp) {
+ while (first1 != last1 && first2 != last2)
+ if (comp(*first1, *first2))
+ *result++ = *first1++;
+ else if (comp(*first2, *first1))
+ *result++ = *first2++;
+ else {
+ *result++ = *first1++;
+ ++first2;
+ }
+ return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result) {
+ while (first1 != last1 && first2 != last2)
+ if (*first1 < *first2)
+ ++first1;
+ else if (*first2 < *first1)
+ ++first2;
+ else {
+ *result++ = *first1++;
+ ++first2;
+ }
+ return result;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+ class Compare>
+OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result, Compare comp) {
+ while (first1 != last1 && first2 != last2)
+ if (comp(*first1, *first2))
+ ++first1;
+ else if (comp(*first2, *first1))
+ ++first2;
+ else {
+ *result++ = *first1++;
+ ++first2;
+ }
+ return result;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result) {
+ while (first1 != last1 && first2 != last2)
+ if (*first1 < *first2)
+ *result++ = *first1++;
+ else if (*first2 < *first1)
+ ++first2;
+ else {
+ ++first1;
+ ++first2;
+ }
+ return copy(first1, last1, result);
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+ class Compare>
+OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ OutputIterator result, Compare comp) {
+ while (first1 != last1 && first2 != last2)
+ if (comp(*first1, *first2))
+ *result++ = *first1++;
+ else if (comp(*first2, *first1))
+ ++first2;
+ else {
+ ++first1;
+ ++first2;
+ }
+ return copy(first1, last1, result);
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_symmetric_difference(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result) {
+ while (first1 != last1 && first2 != last2)
+ if (*first1 < *first2)
+ *result++ = *first1++;
+ else if (*first2 < *first1)
+ *result++ = *first2++;
+ else {
+ ++first1;
+ ++first2;
+ }
+ return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+ class Compare>
+OutputIterator set_symmetric_difference(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result, Compare comp) {
+ while (first1 != last1 && first2 != last2)
+ if (comp(*first1, *first2))
+ *result++ = *first1++;
+ else if (comp(*first2, *first1))
+ *result++ = *first2++;
+ else {
+ ++first1;
+ ++first2;
+ }
+ return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class ForwardIterator>
+ForwardIterator max_element(ForwardIterator first, ForwardIterator last) {
+ if (first == last) return first;
+ ForwardIterator result = first;
+ while (++first != last)
+ if (*result < *first) result = first;
+ return result;
+}
+
+template <class ForwardIterator, class Compare>
+ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
+ Compare comp) {
+ if (first == last) return first;
+ ForwardIterator result = first;
+ while (++first != last)
+ if (comp(*result, *first)) result = first;
+ return result;
+}
+
+template <class ForwardIterator>
+ForwardIterator min_element(ForwardIterator first, ForwardIterator last) {
+ if (first == last) return first;
+ ForwardIterator result = first;
+ while (++first != last)
+ if (*first < *result) result = first;
+ return result;
+}
+
+template <class ForwardIterator, class Compare>
+ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
+ Compare comp) {
+ if (first == last) return first;
+ ForwardIterator result = first;
+ while (++first != last)
+ if (comp(*first, *result)) result = first;
+ return result;
+}
+
+template <class BidirectionalIterator>
+bool next_permutation(BidirectionalIterator first,
+ BidirectionalIterator last) {
+ if (first == last) return false;
+ BidirectionalIterator i = first;
+ ++i;
+ if (i == last) return false;
+ i = last;
+ --i;
+
+ for(;;) {
+ BidirectionalIterator ii = i--;
+ if (*i < *ii) {
+ BidirectionalIterator j = last;
+ while (!(*i < *--j));
+ iter_swap(i, j);
+ reverse(ii, last);
+ return true;
+ }
+ if (i == first) {
+ reverse(first, last);
+ return false;
+ }
+ }
+}
+
+template <class BidirectionalIterator, class Compare>
+bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
+ Compare comp) {
+ if (first == last) return false;
+ BidirectionalIterator i = first;
+ ++i;
+ if (i == last) return false;
+ i = last;
+ --i;
+
+ for(;;) {
+ BidirectionalIterator ii = i--;
+ if (comp(*i, *ii)) {
+ BidirectionalIterator j = last;
+ while (!comp(*i, *--j));
+ iter_swap(i, j);
+ reverse(ii, last);
+ return true;
+ }
+ if (i == first) {
+ reverse(first, last);
+ return false;
+ }
+ }
+}
+
+template <class BidirectionalIterator>
+bool prev_permutation(BidirectionalIterator first,
+ BidirectionalIterator last) {
+ if (first == last) return false;
+ BidirectionalIterator i = first;
+ ++i;
+ if (i == last) return false;
+ i = last;
+ --i;
+
+ for(;;) {
+ BidirectionalIterator ii = i--;
+ if (*ii < *i) {
+ BidirectionalIterator j = last;
+ while (!(*--j < *i));
+ iter_swap(i, j);
+ reverse(ii, last);
+ return true;
+ }
+ if (i == first) {
+ reverse(first, last);
+ return false;
+ }
+ }
+}
+
+template <class BidirectionalIterator, class Compare>
+bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
+ Compare comp) {
+ if (first == last) return false;
+ BidirectionalIterator i = first;
+ ++i;
+ if (i == last) return false;
+ i = last;
+ --i;
+
+ for(;;) {
+ BidirectionalIterator ii = i--;
+ if (comp(*ii, *i)) {
+ BidirectionalIterator j = last;
+ while (!comp(*--j, *i));
+ iter_swap(i, j);
+ reverse(ii, last);
+ return true;
+ }
+ if (i == first) {
+ reverse(first, last);
+ return false;
+ }
+ }
+}
+
+template <class InputIterator, class T>
+T accumulate(InputIterator first, InputIterator last, T init) {
+ while (first != last)
+ init = init + *first++;
+ return init;
+}
+
+template <class InputIterator, class T, class BinaryOperation>
+T accumulate(InputIterator first, InputIterator last, T init,
+ BinaryOperation binary_op) {
+ while (first != last)
+ init = binary_op(init, *first++);
+ return init;
+}
+
+template <class InputIterator1, class InputIterator2, class T>
+T inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init) {
+ while (first1 != last1)
+ init = init + (*first1++ * *first2++);
+ return init;
+}
+
+template <class InputIterator1, class InputIterator2, class T,
+ class BinaryOperation1, class BinaryOperation2>
+T inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init, BinaryOperation1 binary_op1,
+ BinaryOperation2 binary_op2) {
+ while (first1 != last1)
+ init = binary_op1(init, binary_op2(*first1++, *first2++));
+ return init;
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator __partial_sum(InputIterator first, InputIterator last,
+ OutputIterator result, T*) {
+ T value = *first;
+ while (++first != last) {
+ value = value + *first;
+ *++result = value;
+ }
+ return ++result;
+}
+
+template <class InputIterator, class OutputIterator>
+OutputIterator partial_sum(InputIterator first, InputIterator last,
+ OutputIterator result) {
+ if (first == last) return result;
+ *result = *first;
+ return __partial_sum(first, last, result, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator, class T,
+ class BinaryOperation>
+OutputIterator __partial_sum(InputIterator first, InputIterator last,
+ OutputIterator result, T*,
+ BinaryOperation binary_op) {
+ T value = *first;
+ while (++first != last) {
+ value = binary_op(value, *first);
+ *++result = value;
+ }
+ return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryOperation>
+OutputIterator partial_sum(InputIterator first, InputIterator last,
+ OutputIterator result, BinaryOperation binary_op) {
+ if (first == last) return result;
+ *result = *first;
+ return __partial_sum(first, last, result, value_type(first), binary_op);
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
+ OutputIterator result, T*) {
+ T value = *first;
+ while (++first != last) {
+ T tmp = *first;
+ *++result = tmp - value;
+ value = tmp;
+ }
+ return ++result;
+}
+
+template <class InputIterator, class OutputIterator>
+OutputIterator adjacent_difference(InputIterator first, InputIterator last,
+ OutputIterator result) {
+ if (first == last) return result;
+ *result = *first;
+ return __adjacent_difference(first, last, result, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator, class T,
+ class BinaryOperation>
+OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
+ OutputIterator result, T*,
+ BinaryOperation binary_op) {
+ T value = *first;
+ while (++first != last) {
+ T tmp = *first;
+ *++result = binary_op(tmp, value);
+ value = tmp;
+ }
+ return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryOperation>
+OutputIterator adjacent_difference(InputIterator first, InputIterator last,
+ OutputIterator result,
+ BinaryOperation binary_op) {
+ if (first == last) return result;
+ *result = *first;
+ return __adjacent_difference(first, last, result, value_type(first),
+ binary_op);
+}
+
+template <class ForwardIterator, class T>
+void iota(ForwardIterator first, ForwardIterator last, T value) {
+ while (first != last) *first++ = value++;
+}
+
+#endif
+
diff --git a/gnu/lib/libg++/libstdc++/stl/algobase.h b/gnu/lib/libg++/libstdc++/stl/algobase.h
new file mode 100644
index 00000000000..21cea93b5f8
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/algobase.h
@@ -0,0 +1,232 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef ALGOBASE_H
+#define ALGOBASE_H
+
+#include <pair.h>
+#include <iterator.h>
+
+template <class ForwardIterator1, class ForwardIterator2, class T>
+inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) {
+ T tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
+ __iter_swap(a, b, value_type(a));
+}
+
+template <class T>
+inline void swap(T& a, T& b) {
+ T tmp = a;
+ a = b;
+ b = tmp;
+}
+
+template <class T>
+inline const T& min(const T& a, const T& b) {
+ return b < a ? b : a;
+}
+
+template <class T, class Compare>
+inline const T& min(const T& a, const T& b, Compare comp) {
+ return comp(b, a) ? b : a;
+}
+
+template <class T>
+inline const T& max(const T& a, const T& b) {
+ return a < b ? b : a;
+}
+
+template <class T, class Compare>
+inline const T& max(const T& a, const T& b, Compare comp) {
+ return comp(a, b) ? b : a;
+}
+
+template <class InputIterator, class Distance>
+void __distance(InputIterator first, InputIterator last, Distance& n,
+ input_iterator_tag) {
+ while (first != last) { ++first; ++n; }
+}
+
+template <class ForwardIterator, class Distance>
+void __distance(ForwardIterator first, ForwardIterator last, Distance& n,
+ forward_iterator_tag) {
+ while (first != last) { ++first; ++n; }
+}
+
+template <class BidirectionalIterator, class Distance>
+void __distance(BidirectionalIterator first, BidirectionalIterator last,
+ Distance& n, bidirectional_iterator_tag) {
+ while (first != last) { ++first; ++n; }
+}
+
+template <class RandomAccessIterator, class Distance>
+inline void __distance(RandomAccessIterator first, RandomAccessIterator last,
+ Distance& n, random_access_iterator_tag) {
+ n += last - first;
+}
+
+template <class InputIterator, class Distance>
+inline void distance(InputIterator first, InputIterator last, Distance& n) {
+ __distance(first, last, n, iterator_category(first));
+}
+
+template <class InputIterator, class Distance>
+void __advance(InputIterator& i, Distance n, input_iterator_tag) {
+ while (n--) ++i;
+}
+
+template <class ForwardIterator, class Distance>
+void __advance(ForwardIterator& i, Distance n, forward_iterator_tag) {
+ while (n--) ++i;
+}
+
+template <class BidirectionalIterator, class Distance>
+void __advance(BidirectionalIterator& i, Distance n,
+ bidirectional_iterator_tag) {
+ if (n >= 0)
+ while (n--) ++i;
+ else
+ while (n++) --i;
+}
+
+template <class RandomAccessIterator, class Distance>
+inline void __advance(RandomAccessIterator& i, Distance n,
+ random_access_iterator_tag) {
+ i += n;
+}
+
+template <class InputIterator, class Distance>
+inline void advance(InputIterator& i, Distance n) {
+ __advance(i, n, iterator_category(i));
+}
+
+template <class ForwardIterator>
+void destroy(ForwardIterator first, ForwardIterator last) {
+ while (first != last) {
+ /* Borland bug */
+ destroy(&*first);
+ ++first;
+ //destroy(&*first++);
+ }
+}
+
+template <class InputIterator, class ForwardIterator>
+ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
+ ForwardIterator result) {
+ while (first != last) construct(&*result++, *first++);
+ return result;
+}
+
+template <class ForwardIterator, class T>
+void uninitialized_fill(ForwardIterator first, ForwardIterator last,
+ const T& x) {
+ while (first != last) construct(&*first++, x);
+}
+
+template <class ForwardIterator, class Size, class T>
+ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
+ const T& x) {
+ while (n--) construct(&*first++, x);
+ return first;
+}
+
+template <class InputIterator, class OutputIterator>
+OutputIterator copy(InputIterator first, InputIterator last,
+ OutputIterator result) {
+ while (first != last) *result++ = *first++;
+ return result;
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+BidirectionalIterator2 copy_backward(BidirectionalIterator1 first,
+ BidirectionalIterator1 last,
+ BidirectionalIterator2 result) {
+ while (first != last) *--result = *--last;
+ return result;
+}
+
+template <class ForwardIterator, class T>
+void fill(ForwardIterator first, ForwardIterator last, const T& value) {
+ while (first != last) *first++ = value;
+}
+
+template <class OutputIterator, class Size, class T>
+OutputIterator fill_n(OutputIterator first, Size n, const T& value) {
+ while (n-- > 0) *first++ = value;
+ return first;
+}
+
+template <class InputIterator1, class InputIterator2>
+pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2) {
+ while (first1 != last1 && *first1 == *first2) {
+ ++first1;
+ ++first2;
+ }
+ return pair<InputIterator1, InputIterator2>(first1, first2);
+}
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ BinaryPredicate binary_pred) {
+ while (first1 != last1 && binary_pred(*first1, *first2)) {
+ ++first1;
+ ++first2;
+ }
+ return pair<InputIterator1, InputIterator2>(first1, first2);
+}
+
+template <class InputIterator1, class InputIterator2>
+inline bool equal(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2) {
+ return mismatch(first1, last1, first2).first == last1;
+}
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+inline bool equal(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, BinaryPredicate binary_pred) {
+ return mismatch(first1, last1, first2, binary_pred).first == last1;
+}
+
+template <class InputIterator1, class InputIterator2>
+bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2) {
+ while (first1 != last1 && first2 != last2) {
+ if (*first1 < *first2) return true;
+ if (*first2++ < *first1++) return false;
+ }
+ return first1 == last1 && first2 != last2;
+}
+
+template <class InputIterator1, class InputIterator2, class Compare>
+bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2,
+ Compare comp) {
+ while (first1 != last1 && first2 != last2) {
+ if (comp(*first1, *first2)) return true;
+ if (comp(*first2++, *first1++)) return false;
+ }
+ return first1 == last1 && first2 != last2;
+}
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/bvector.h b/gnu/lib/libg++/libstdc++/stl/bvector.h
new file mode 100644
index 00000000000..f9fe10655cb
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/bvector.h
@@ -0,0 +1,421 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+// vector<bool> is replaced by bit_vector at present because bool is not
+// implemented.
+
+#ifndef BVECTOR_H
+#define BVECTOR_H
+
+#include <function.h>
+#include <algobase.h>
+#include <iterator.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#define __WORD_BIT (int(CHAR_BIT*sizeof(unsigned int)))
+
+class bit_vector {
+public:
+ typedef Allocator<unsigned int> vector_allocator;
+ typedef bool value_type;
+ typedef vector_allocator::size_type size_type;
+ typedef vector_allocator::difference_type difference_type;
+
+ class iterator;
+ class const_iterator;
+
+ class reference {
+ friend class iterator;
+ friend class const_iterator;
+ protected:
+ unsigned int* p;
+ unsigned int mask;
+ reference(unsigned int* x, unsigned int y) : p(x), mask(y) {}
+ public:
+ reference() : p(0), mask(0) {}
+ operator bool() const { return !(!(*p & mask)); }
+ reference& operator=(bool x) {
+ if (x)
+ *p |= mask;
+ else
+ *p &= ~mask;
+ return *this;
+ }
+ reference& operator=(const reference& x) { return *this = bool(x); }
+ bool operator==(const reference& x) const {
+ return bool(*this) == bool(x);
+ }
+ bool operator<(const reference& x) const {
+ return bool(*this) < bool(x);
+ }
+ void flip() { *p ^= mask; }
+ };
+ typedef bool const_reference;
+ class iterator : public random_access_iterator<bool, difference_type> {
+ friend class bit_vector;
+ friend class const_iterator;
+ protected:
+ unsigned int* p;
+ unsigned int offset;
+ void bump_up() {
+ if (offset++ == __WORD_BIT - 1) {
+ offset = 0;
+ ++p;
+ }
+ }
+ void bump_down() {
+ if (offset-- == 0) {
+ offset = __WORD_BIT - 1;
+ --p;
+ }
+ }
+ public:
+ iterator() : p(0), offset(0) {}
+ iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
+ reference operator*() const { return reference(p, 1U << offset); }
+ iterator& operator++() {
+ bump_up();
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator tmp = *this;
+ bump_up();
+ return tmp;
+ }
+ iterator& operator--() {
+ bump_down();
+ return *this;
+ }
+ iterator operator--(int) {
+ iterator tmp = *this;
+ bump_down();
+ return tmp;
+ }
+ iterator& operator+=(difference_type i) {
+ difference_type n = i + offset;
+ p += n / __WORD_BIT;
+ n = n % __WORD_BIT;
+ if (n < 0) {
+ offset = n + __WORD_BIT;
+ --p;
+ } else
+ offset = n;
+ return *this;
+ }
+ iterator& operator-=(difference_type i) {
+ *this += -i;
+ return *this;
+ }
+ iterator operator+(difference_type i) const {
+ iterator tmp = *this;
+ return tmp += i;
+ }
+ iterator operator-(difference_type i) const {
+ iterator tmp = *this;
+ return tmp -= i;
+ }
+ difference_type operator-(iterator x) const {
+ return __WORD_BIT * (p - x.p) + offset - x.offset;
+ }
+ reference operator[](difference_type i) { return *(*this + i); }
+ bool operator==(const iterator& x) const {
+ return p == x.p && offset == x.offset;
+ }
+ bool operator<(iterator x) const {
+ return p < x.p || (p == x.p && offset < x.offset);
+ }
+ };
+
+ class const_iterator
+ : public random_access_iterator<bool, difference_type> {
+ friend class bit_vector;
+ protected:
+ unsigned int* p;
+ unsigned int offset;
+ void bump_up() {
+ if (offset++ == __WORD_BIT - 1) {
+ offset = 0;
+ ++p;
+ }
+ }
+ void bump_down() {
+ if (offset-- == 0) {
+ offset = __WORD_BIT - 1;
+ --p;
+ }
+ }
+ public:
+ const_iterator() : p(0), offset(0) {}
+ const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
+ const_iterator(const iterator& x) : p(x.p), offset(x.offset) {}
+ const_reference operator*() const {
+ return reference(p, 1U << offset);
+ }
+ const_iterator& operator++() {
+ bump_up();
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ bump_up();
+ return tmp;
+ }
+ const_iterator& operator--() {
+ bump_down();
+ return *this;
+ }
+ const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ bump_down();
+ return tmp;
+ }
+ const_iterator& operator+=(difference_type i) {
+ difference_type n = i + offset;
+ p += n / __WORD_BIT;
+ n = n % __WORD_BIT;
+ if (n < 0) {
+ offset = n + __WORD_BIT;
+ --p;
+ } else
+ offset = n;
+ return *this;
+ }
+ const_iterator& operator-=(difference_type i) {
+ *this += -i;
+ return *this;
+ }
+ const_iterator operator+(difference_type i) const {
+ const_iterator tmp = *this;
+ return tmp += i;
+ }
+ const_iterator operator-(difference_type i) const {
+ const_iterator tmp = *this;
+ return tmp -= i;
+ }
+ difference_type operator-(const_iterator x) const {
+ return __WORD_BIT * (p - x.p) + offset - x.offset;
+ }
+ const_reference operator[](difference_type i) {
+ return *(*this + i);
+ }
+ bool operator==(const const_iterator& x) const {
+ return p == x.p && offset == x.offset;
+ }
+ bool operator<(const_iterator x) const {
+ return p < x.p || (p == x.p && offset < x.offset);
+ }
+ };
+
+ typedef reverse_iterator<const_iterator, value_type, const_reference,
+ difference_type> const_reverse_iterator;
+ typedef reverse_iterator<iterator, value_type, reference, difference_type>
+ reverse_iterator;
+
+protected:
+ static Allocator<unsigned int> static_allocator;
+ iterator start;
+ iterator finish;
+ unsigned int* end_of_storage;
+ unsigned int* bit_alloc(size_type n) {
+ return static_allocator.allocate((n + __WORD_BIT - 1)/__WORD_BIT);
+ }
+ void initialize(size_type n) {
+ unsigned int* q = bit_alloc(n);
+ end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
+ start = iterator(q, 0);
+ finish = start + n;
+ }
+ void insert_aux(iterator position, bool x);
+ typedef bit_vector self;
+public:
+ iterator begin() { return start; }
+ const_iterator begin() const { return start; }
+ iterator end() { return finish; }
+ const_iterator end() const { return finish; }
+
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ size_type size() const { return size_type(end() - begin()); }
+ size_type max_size() const { return static_allocator.max_size(); }
+ size_type capacity() const {
+ return size_type(const_iterator(end_of_storage, 0) - begin());
+ }
+ bool empty() const { return begin() == end(); }
+ reference operator[](size_type n) { return *(begin() + n); }
+ const_reference operator[](size_type n) const { return *(begin() + n); }
+ bit_vector() : start(iterator()), finish(iterator()), end_of_storage(0) {}
+ bit_vector(size_type n, bool value = bool()) {
+ initialize(n);
+ fill(start.p, end_of_storage, value ? ~0 : 0);
+ }
+ bit_vector(const self& x) {
+ initialize(x.size());
+ copy(x.begin(), x.end(), start);
+ }
+ bit_vector(const_iterator first, const_iterator last) {
+ size_type n = 0;
+ distance(first, last, n);
+ initialize(n);
+ copy(first, last, start);
+ }
+ ~bit_vector() { static_allocator.deallocate(start.p); }
+ self& operator=(const self& x) {
+ if (&x == this) return *this;
+ if (x.size() > capacity()) {
+ static_allocator.deallocate(start.p);
+ initialize(x.size());
+ }
+ copy(x.begin(), x.end(), begin());
+ finish = begin() + x.size();
+ return *this;
+ }
+ void reserve(size_type n) {
+ if (capacity() < n) {
+ unsigned int* q = bit_alloc(n);
+ finish = copy(begin(), end(), iterator(q, 0));
+ static_allocator.deallocate(start.p);
+ start = iterator(q, 0);
+ end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
+ }
+ }
+ reference front() { return *begin(); }
+ const_reference front() const { return *begin(); }
+ reference back() { return *(end() - 1); }
+ const_reference back() const { return *(end() - 1); }
+ void push_back(bool x) {
+ if (finish.p != end_of_storage)
+ *finish++ = x;
+ else
+ insert_aux(end(), x);
+ }
+ void swap(bit_vector& x) {
+ ::swap(start, x.start);
+ ::swap(finish, x.finish);
+ ::swap(end_of_storage, x.end_of_storage);
+ }
+ iterator insert(iterator position, bool x) {
+ size_type n = position - begin();
+ if (finish.p != end_of_storage && position == end())
+ *finish++ = x;
+ else
+ insert_aux(position, x);
+ return begin() + n;
+ }
+ void insert(iterator position, const_iterator first,
+ const_iterator last);
+ void insert(iterator position, size_type n, bool x);
+ void pop_back() { --finish; }
+ void erase(iterator position) {
+ if (position + 1 != end())
+ copy(position + 1, end(), position);
+ --finish;
+ }
+ void erase(iterator first, iterator last) {
+ finish = copy(last, end(), first);
+ }
+};
+
+Allocator<unsigned int> bit_vector::static_allocator;
+
+inline bool operator==(const bit_vector& x, const bit_vector& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+inline bool operator<(const bit_vector& x, const bit_vector& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+void swap(bit_vector::reference x, bit_vector::reference y) {
+ bool tmp = x;
+ x = y;
+ y = tmp;
+}
+
+void bit_vector::insert_aux(iterator position, bool x) {
+ if (finish.p != end_of_storage) {
+ copy_backward(position, finish - 1, finish);
+ *position = x;
+ ++finish;
+ } else {
+ size_type len = size() ? 2 * size() : __WORD_BIT;
+ unsigned int* q = bit_alloc(len);
+ iterator i = copy(begin(), position, iterator(q, 0));
+ *i++ = x;
+ finish = copy(position, end(), i);
+ static_allocator.deallocate(start.p);
+ end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+ start = iterator(q, 0);
+ }
+}
+
+void bit_vector::insert(iterator position, size_type n, bool x) {
+ if (n == 0) return;
+ if (capacity() - size() >= n) {
+ copy_backward(position, end(), finish + n);
+ fill(position, position + n, x);
+ finish += n;
+ } else {
+ size_type len = size() + max(size(), n);
+ unsigned int* q = bit_alloc(len);
+ iterator i = copy(begin(), position, iterator(q, 0));
+ fill_n(i, n, x);
+ finish = copy(position, end(), i + n);
+ static_allocator.deallocate(start.p);
+ end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
+ start = iterator(q, 0);
+ }
+}
+
+void bit_vector::insert(iterator position, const_iterator first,
+ const_iterator last) {
+ if (first == last) return;
+ size_type n = 0;
+ distance(first, last, n);
+ if (capacity() - size() >= n) {
+ copy_backward(position, end(), finish + n);
+ copy(first, last, position);
+ finish += n;
+ } else {
+ size_type len = size() + max(size(), n);
+ unsigned int* q = bit_alloc(len);
+ iterator i = copy(begin(), position, iterator(q, 0));
+ i = copy(first, last, i);
+ finish = copy(position, end(), i);
+ static_allocator.deallocate(start.p);
+ end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+ start = iterator(q, 0);
+ }
+}
+
+#undef Allocator
+#undef __WORD_BIT
+
+#endif
+
+
diff --git a/gnu/lib/libg++/libstdc++/stl/defalloc.h b/gnu/lib/libg++/libstdc++/stl/defalloc.h
new file mode 100644
index 00000000000..388e58fd744
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/defalloc.h
@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef DEFALLOC_H
+#define DEFALLOC_H
+
+#include <new.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <iostream.h>
+#include <algobase.h>
+
+#ifndef __GNUG__
+inline void* operator new(size_t, void* p) {return p;}
+#endif
+
+/*
+ * the following template function is replaced by the following two functions
+ * due to the fact that the Borland compiler doesn't change prediff_t type
+ * to type long when compile with -ml or -mh.
+
+template <class T>
+inline T* allocate(ptrdiff_t size, T*) {
+ set_new_handler(0);
+ T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
+ if (tmp == 0) {
+ cerr << "out of memory" << endl;
+ exit(1);
+ }
+ return tmp;
+}
+*/
+
+template <class T>
+inline T* allocate(int size, T*) {
+ set_new_handler(0);
+ T* tmp = (T*)(::operator new((unsigned int)(size * sizeof(T))));
+ if (tmp == 0) {
+ cerr << "out of memory" << endl;
+ exit(1);
+ }
+ return tmp;
+}
+
+template <class T>
+inline T* allocate(long size, T*) {
+ set_new_handler(0);
+ T* tmp = (T*)(::operator new((unsigned long)(size * sizeof(T))));
+ if (tmp == 0) {
+ cerr << "out of memory" << endl;
+ exit(1);
+ }
+ return tmp;
+}
+
+template <class T>
+inline void deallocate(T* buffer) {
+ ::operator delete(buffer);
+}
+
+template <class T>
+inline void destroy(T* pointer) {
+ pointer->~T();
+}
+
+inline void destroy(char*) {}
+inline void destroy(unsigned char*) {}
+inline void destroy(short*) {}
+inline void destroy(unsigned short*) {}
+inline void destroy(int*) {}
+inline void destroy(unsigned int*) {}
+inline void destroy(long*) {}
+inline void destroy(unsigned long*) {}
+inline void destroy(float*) {}
+inline void destroy(double*) {}
+inline void destroy(char**) {}
+inline void destroy(unsigned char**) {}
+inline void destroy(short**) {}
+inline void destroy(unsigned short**) {}
+inline void destroy(int**) {}
+inline void destroy(unsigned int**) {}
+inline void destroy(long**) {}
+inline void destroy(unsigned long**) {}
+inline void destroy(float**) {}
+inline void destroy(double**) {}
+
+inline void destroy(char*, char*) {}
+inline void destroy(unsigned char*, unsigned char*) {}
+inline void destroy(short*, short*) {}
+inline void destroy(unsigned short*, unsigned short*) {}
+inline void destroy(int*, int*) {}
+inline void destroy(unsigned int*, unsigned int*) {}
+inline void destroy(long*, long*) {}
+inline void destroy(unsigned long*, unsigned long*) {}
+inline void destroy(float*, float*) {}
+inline void destroy(double*, double*) {}
+inline void destroy(char**, char**) {}
+inline void destroy(unsigned char**, unsigned char**) {}
+inline void destroy(short**, short**) {}
+inline void destroy(unsigned short**, unsigned short**) {}
+inline void destroy(int**, int**) {}
+inline void destroy(unsigned int**, unsigned int**) {}
+inline void destroy(long**, long**) {}
+inline void destroy(unsigned long**, unsigned long**) {}
+inline void destroy(float**, float**) {}
+inline void destroy(double**, double**) {}
+
+template <class T1, class T2>
+inline void construct(T1* p, const T2& value) {
+ new (p) T1(value);
+}
+
+template <class T>
+class allocator {
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+#ifdef __GNUG__
+ static pointer allocate(size_type n) {
+ return ::allocate((difference_type)n, (pointer)0);
+ }
+ static void deallocate(pointer p) { ::deallocate(p); }
+ static pointer address(reference x) { return (pointer)&x; }
+ static const_pointer const_address(const_reference x) {
+ return (const_pointer)&x;
+ }
+ static size_type init_page_size() {
+ return max(size_type(1), size_type(4096/sizeof(T)));
+ }
+ static size_type max_size() {
+ return max(size_type(1), size_type(UINT_MAX/sizeof(T)));
+ }
+#else
+ pointer allocate(size_type n) {
+ return ::allocate((difference_type)n, (pointer)0);
+ }
+ void deallocate(pointer p) { ::deallocate(p); }
+ pointer address(reference x) { return (pointer)&x; }
+ const_pointer const_address(const_reference x) {
+ return (const_pointer)&x;
+ }
+ size_type init_page_size() {
+ return max(size_type(1), size_type(4096/sizeof(T)));
+ }
+ size_type max_size() const {
+ return max(size_type(1), size_type(UINT_MAX/sizeof(T)));
+ }
+#endif
+};
+
+class allocator<void> {
+public:
+ typedef void* pointer;
+};
+
+
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/deque.h b/gnu/lib/libg++/libstdc++/stl/deque.h
new file mode 100644
index 00000000000..f05de7b09f0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/deque.h
@@ -0,0 +1,681 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef DEQUE_H
+#define DEQUE_H
+
+#include <function.h>
+#include <algobase.h>
+#include <iterator.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#ifndef deque
+#define deque deque
+#endif
+
+template <class T>
+class deque {
+public:
+ class iterator;
+ class const_iterator;
+ friend class iterator;
+ friend class const_iterator;
+public:
+ typedef T value_type;
+ typedef Allocator<T> data_allocator_type;
+ typedef Allocator<T>::pointer pointer;
+ typedef Allocator<T>::reference reference;
+ typedef Allocator<T>::const_reference const_reference;
+ typedef Allocator<T>::size_type size_type;
+ typedef Allocator<T>::difference_type difference_type;
+ typedef Allocator<pointer> map_allocator_type;
+protected:
+ static data_allocator_type data_allocator;
+#ifdef __GNUG__
+ // static // Too bad -- I don't like this hack very much...
+ static size_type buffer_size() {
+ return data_allocator.init_page_size();
+ }
+#define __dq_buffer_size buffer_size()
+#else
+ static size_type buffer_size;
+#define __dq_buffer_size buffer_size
+#endif
+ static map_allocator_type map_allocator;
+ typedef Allocator<pointer>::pointer map_pointer;
+public:
+ class iterator : public random_access_iterator<T, difference_type> {
+ friend class deque<T>;
+ friend class const_iterator;
+ protected:
+ pointer current;
+ pointer first;
+ pointer last;
+ map_pointer node;
+ iterator(pointer x, map_pointer y)
+ : current(x), first(*y), last(*y + __dq_buffer_size), node(y) {}
+ public:
+ iterator() : current(0), first(0), last(0), node(0) {}
+ reference operator*() const { return *current; }
+ difference_type operator-(const iterator& x) const {
+ return node == x.node
+ ? current - x.current
+ : difference_type(__dq_buffer_size * (node - x.node - 1) +
+ (current - first) + (x.last - x.current));
+ }
+ iterator& operator++() {
+ if (++current == last) {
+ first = *(++node);
+ current = first;
+ last = first + __dq_buffer_size;
+ }
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ iterator& operator--() {
+ if (current == first) {
+ first = *(--node);
+ last = first + __dq_buffer_size;
+ current = last;
+ }
+ --current;
+ return *this;
+ }
+ iterator operator--(int) {
+ iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ iterator& operator+=(difference_type n) {
+ difference_type offset = n + (current - first);
+ difference_type num_node_to_jump = offset >= 0
+ ? offset / __dq_buffer_size
+ : -((-offset + __dq_buffer_size - 1) / __dq_buffer_size);
+ if (num_node_to_jump == 0)
+ current += n;
+ else {
+ node = node + num_node_to_jump;
+ first = *node;
+ last = first + __dq_buffer_size;
+ current = first + (offset - num_node_to_jump * __dq_buffer_size);
+ }
+ return *this;
+ }
+ iterator& operator-=(difference_type n) { return *this += -n; }
+ iterator operator+(difference_type n) const {
+ iterator tmp = *this;
+ return tmp += n;
+ }
+ iterator operator-(difference_type n) const {
+ iterator tmp = *this;
+ return tmp -= n;
+ }
+ reference operator[](difference_type n) { return *(*this + n); }
+ bool operator==(const iterator& x) const {
+ return current == x.current ||
+ ((current == first || x.current == x.first) &&
+ *this - x == 0);
+ }
+ bool operator<(const iterator& x) const {
+ return (node == x.node) ? (current < x.current) : (node < x.node);
+ }
+ };
+ class const_iterator : public random_access_iterator<T, difference_type> {
+ friend class deque<T>;
+ protected:
+ pointer current;
+ pointer first;
+ pointer last;
+ map_pointer node;
+ const_iterator(pointer x, map_pointer y)
+ : current(x), first(*y), last(*y + __dq_buffer_size), node(y) {}
+ public:
+ const_iterator() : current(0), first(0), last(0), node(0) {}
+ const_iterator(const iterator& x)
+ : current(x.current), first(x.first), last(x.last), node(x.node) {}
+ const_reference operator*() const { return *current; }
+ difference_type operator-(const const_iterator& x) const {
+ return node == x.node
+ ? current - x.current
+ : difference_type(__dq_buffer_size * (node - x.node - 1) +
+ (current - first) + (x.last - x.current));
+ }
+ const_iterator& operator++() {
+ if (++current == last) {
+ first = *(++node);
+ current = first;
+ last = first + __dq_buffer_size;
+ }
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ const_iterator& operator--() {
+ if (current == first) {
+ first = *(--node);
+ last = first + __dq_buffer_size;
+ current = last;
+ }
+ --current;
+ return *this;
+ }
+ const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ const_iterator& operator+=(difference_type n) {
+ difference_type offset = n + (current - first);
+ difference_type num_node_to_jump = offset >= 0
+ ? offset / __dq_buffer_size
+ : -((-offset + __dq_buffer_size - 1) / __dq_buffer_size);
+ if (num_node_to_jump == 0)
+ current += n;
+ else {
+ node = node + num_node_to_jump;
+ first = *node;
+ last = first + __dq_buffer_size;
+ current = first + (offset - num_node_to_jump * __dq_buffer_size);
+ }
+ return *this;
+ }
+ const_iterator& operator-=(difference_type n) { return *this += -n; }
+ const_iterator operator+(difference_type n) const {
+ const_iterator tmp = *this;
+ return tmp += n;
+ }
+ const_iterator operator-(difference_type n) const {
+ const_iterator tmp = *this;
+ return tmp -= n;
+ }
+ const_reference operator[](difference_type n) {
+ return *(*this + n);
+ }
+ bool operator==(const const_iterator& x) const {
+ return current == x.current ||
+ ((current == first || x.current == x.first) &&
+ *this - x == 0);
+ }
+ bool operator<(const const_iterator& x) const {
+ return (node == x.node) ? (current < x.current) : (node < x.node);
+ }
+ };
+ typedef reverse_iterator<const_iterator, value_type, const_reference,
+ difference_type> const_reverse_iterator;
+ typedef reverse_iterator<iterator, value_type, reference, difference_type>
+ reverse_iterator;
+protected:
+ iterator start;
+ iterator finish;
+ size_type length;
+ map_pointer map;
+ size_type map_size;
+
+ void allocate_at_begin();
+ void allocate_at_end();
+ void deallocate_at_begin();
+ void deallocate_at_end();
+
+public:
+ deque() : start(), finish(), length(0), map(0), map_size(0) {
+#ifndef __GNUG__
+ __dq_buffer_size = data_allocator.init_page_size();
+#endif
+ }
+ iterator begin() { return start; }
+ const_iterator begin() const { return start; }
+ iterator end() { return finish; }
+ const_iterator end() const { return finish; }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+ bool empty() const { return length == 0; }
+ size_type size() const { return length; }
+ size_type max_size() const { return data_allocator.max_size(); }
+ reference operator[](size_type n) { return *(begin() + n); }
+ const_reference operator[](size_type n) const { return *(begin() + n); }
+ reference front() { return *begin(); }
+ const_reference front() const { return *begin(); }
+ reference back() { return *(end() - 1); }
+ const_reference back() const { return *(end() - 1); }
+ void push_front(const T& x) {
+ if (empty() || begin().current == begin().first)
+ allocate_at_begin();
+ --start.current;
+ construct(start.current, x);
+ ++length;
+ if (end().current == end().last) allocate_at_end();
+ }
+ void push_back(const T& x) {
+ if (empty()) allocate_at_end();
+ construct(finish.current, x);
+ ++finish.current;
+ ++length;
+ if (end().current == end().last) allocate_at_end();
+ }
+ void pop_front() {
+ destroy(start.current);
+ ++start.current;
+ --length;
+ if (empty() || begin().current == begin().last)
+ deallocate_at_begin();
+ }
+ void pop_back() {
+ if (end().current == end().first) deallocate_at_end();
+ --finish.current;
+ destroy(finish.current);
+ --length;
+ if (empty()) deallocate_at_end();
+ }
+ void swap(deque<T>& x) {
+ ::swap(start, x.start);
+ ::swap(finish, x.finish);
+ ::swap(length, x.length);
+ ::swap(map, x.map);
+ ::swap(map_size, x.map_size);
+ }
+#ifdef __GNUG__
+ iterator insert(iterator position, const T& x) {
+ return insert(deque_iterator<T>(position), x);
+ }
+ deque_iterator<T> insert(deque_iterator<T> position, const T& x);
+ void insert(iterator position, size_type n, const T& x) {
+ insert(deque_iterator<T>(position), n, x);
+ }
+ void insert(deque_iterator<T>(position), size_type n, const T& x);
+// template <class Iterator> void insert(iterator position,
+// Iterator first, Iterator last);
+ void insert(iterator position, const T* first, const T* last) {
+ insert(deque_iterator<T>(position), first, last);
+ }
+ void insert(deque_iterator<T> position, const T* first, const T* last);
+ void erase(iterator position) {
+ erase(deque_iterator<T>(position));
+ }
+ void erase(deque_iterator<T> position);
+ void erase(iterator first, iterator last) {
+ erase(deque_iterator<T>(first), deque_iterator<T>(last));
+ }
+ void erase(deque_iterator<T> first, deque_iterator<T> last);
+#else
+ iterator insert(iterator position, const T& x);
+ void insert(iterator position, size_type n, const T& x);
+// template <class Iterator> void insert(iterator position,
+// Iterator first, Iterator last);
+ void insert(iterator position, const T* first, const T* last);
+ void erase(iterator position);
+ void erase(iterator first, iterator last);
+#endif
+ deque(size_type n, const T& value = T())
+ : start(), finish(), length(0), map(0), map_size(0) {
+#ifndef __GNUG__
+ __dq_buffer_size = data_allocator.init_page_size();
+#endif
+ insert(begin(), n, value);
+ }
+// template <class Iterator> deque(Iterator first, Iterator last);
+ deque(const T* first, const T* last)
+ : start(), finish(), length(0), map(0), map_size(0) {
+#ifndef __GNUG__
+ __dq_buffer_size = data_allocator.init_page_size();
+#endif
+ copy(first, last, back_inserter(*this));
+ }
+ deque(const deque<T>& x)
+ : start(), finish(), length(0), map(0), map_size(0) {
+#ifndef __GNUG__
+ __dq_buffer_size = data_allocator.init_page_size();
+#endif
+ copy(x.begin(), x.end(), back_inserter(*this));
+ }
+ deque<T>& operator=(const deque<T>& x) {
+ if (this != &x)
+ if (size() >= x.size())
+ erase(copy(x.begin(), x.end(), begin()), end());
+ else
+ copy(x.begin() + size(), x.end(),
+ inserter(*this, copy(x.begin(), x.begin() + size(),
+ begin())));
+ return *this;
+ }
+ ~deque();
+#ifdef __GNUG__
+ friend T* value_type(const iterator&) {
+ return (T*)(0);
+ }
+#endif
+};
+
+#ifdef __GNUG__
+template <class T>
+struct deque_iterator: deque<T>::iterator {
+ deque_iterator(deque<T>::iterator i) : deque<T>::iterator(i) {}
+};
+
+template <class T>
+inline T* value_type(const deque_iterator<T>&) {
+ return (T*)(0);
+}
+#else
+template <class T>
+deque<T>::data_allocator_type deque<T>::data_allocator;
+
+template <class T>
+deque<T>::map_allocator_type deque<T>::map_allocator;
+
+template <class T>
+deque<T>::size_type deque<T>::__dq_buffer_size = 0;
+// should be data_allocator.init_page_size(); // Borland bug
+#endif
+
+template <class T>
+bool operator==(const deque<T>& x, const deque<T>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T>
+bool operator<(const deque<T>& x, const deque<T>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T>
+deque<T>::~deque() { while (!empty()) pop_front(); }
+
+template <class T>
+void deque<T>::allocate_at_begin() {
+ pointer p = data_allocator.allocate(__dq_buffer_size);
+ if (!empty()) {
+ if (start.node == map) {
+ difference_type i = finish.node - start.node;
+ map_size = (i + 1) * 2;
+#ifdef __GNU_G__
+ map_pointer tmp = map_allocator_type::allocate(map_size);
+ copy(start.node, finish.node + 1, tmp + map_size / 4 + 1);
+ map_allocator_type::deallocate(map);
+#else
+ map_pointer tmp = map_allocator.allocate(map_size);
+ copy(start.node, finish.node + 1, tmp + map_size / 4 + 1);
+ map_allocator.deallocate(map);
+#endif
+ map = tmp;
+ map[map_size / 4] = p;
+ start = iterator(p + __dq_buffer_size, map + map_size / 4);
+ finish = iterator(finish.current, map + map_size / 4 + i + 1);
+ } else {
+#ifdef __GNUG__
+ map_size = map_allocator_type::init_page_size();
+ map = map_allocator_type::allocate(map_size);
+#else
+ *--start.node = p;
+ start = iterator(p + __dq_buffer_size, start.node);
+#endif
+ }
+ } else {
+#ifdef __GNUG__
+ map_size = map_allocator_type::init_page_size();
+ map = map_allocator_type::allocate(map_size);
+#else
+ map_size = map_allocator.init_page_size();
+ map = map_allocator.allocate(map_size);
+#endif
+ map[map_size / 2] = p;
+ start = iterator(p + __dq_buffer_size / 2 + 1, map + map_size / 2);
+ finish = start;
+ }
+}
+
+template <class T>
+void deque<T>::allocate_at_end() {
+ pointer p = data_allocator.allocate(__dq_buffer_size);
+ if (!empty()) {
+ if (finish.node == map + map_size - 1) {
+ difference_type i = finish.node - start.node;
+ map_size = (i + 1) * 2;
+#ifdef __GNUG__
+ map_pointer tmp = map_allocator_type::allocate(map_size);
+ copy(start.node, finish.node + 1, tmp + map_size / 4);
+ map_allocator_type::deallocate(map);
+#else
+ map_pointer tmp = map_allocator.allocate(map_size);
+ copy(start.node, finish.node + 1, tmp + map_size / 4);
+ map_allocator.deallocate(map);
+#endif
+ map = tmp;
+ map[map_size / 4 + i + 1] = p;
+ start = iterator(start.current, map + map_size / 4);
+ finish = iterator(p, map + map_size / 4 + i + 1);
+ } else {
+ *++finish.node = p;
+ finish = iterator(p, finish.node);
+ }
+ } else {
+#ifdef __GNUG__
+ map_size = map_allocator_type::init_page_size();
+ map = map_allocator_type::allocate(map_size);
+#else
+ map_size = map_allocator.init_page_size();
+ map = map_allocator.allocate(map_size);
+#endif
+ map[map_size / 2] = p;
+ start = iterator(p + __dq_buffer_size / 2, map + map_size / 2);
+ finish = start;
+ }
+}
+
+template <class T>
+void deque<T>::deallocate_at_begin() {
+ data_allocator.deallocate(*start.node++);
+ if (empty()) {
+ if (finish.current == finish.first)
+ data_allocator.deallocate(*start.node);
+ start = iterator();
+ finish = start;
+#ifdef __GNUG__
+ map_allocator.deallocate(map);
+#else
+ map_allocator.deallocate(map);
+#endif
+ } else
+ start = iterator(*start.node, start.node);
+}
+
+template <class T>
+void deque<T>::deallocate_at_end() {
+ data_allocator.deallocate(*finish.node--);
+ if (empty()) {
+ start = iterator();
+ finish = start;
+#ifdef __GNUG__
+ map_allocator.deallocate(map);
+#else
+ map_allocator.deallocate(map);
+#endif
+ } else
+ finish = iterator(*finish.node + __dq_buffer_size, finish.node);
+}
+
+template <class T>
+#ifdef __GNUG__
+deque_iterator<T>
+deque<T>::insert(deque_iterator<T> posn, const T& x) {
+ iterator position = posn;
+#else
+deque<T>::iterator deque<T>::insert(iterator position, const T& x) {
+#endif
+ if (position == begin()) {
+ push_front(x);
+ return begin();
+ } else if (position == end()) {
+ push_back(x);
+ return end() - 1;
+ } else {
+ difference_type index = position - begin();
+ if (index < length) {
+ push_front(*begin());
+ copy(begin() + 2, begin() + index + 1, begin() + 1);
+ } else {
+ push_back(*(end() - 1));
+ copy_backward(begin() + index, end() - 2, end() - 1);
+ }
+ *(begin() + index) = x;
+ return begin() + index;
+ }
+}
+
+template <class T>
+#ifdef __GNUG__
+void deque<T>::insert(deque_iterator<T> posn,
+ size_t n, // BAD HACK
+ const T& x) {
+ iterator position = posn;
+#else
+void deque<T>::insert(iterator position, size_type n, const T& x) {
+#endif
+ difference_type index = position - begin();
+ difference_type remainder = length - index;
+ if (remainder > index) {
+ if (n > index) {
+ difference_type m = n - index;
+ while (m-- > 0) push_front(x);
+ difference_type i = index;
+ while (i--) push_front(*(begin() + n - 1));
+ fill(begin() + n, begin() + n + index, x);
+ } else {
+ difference_type i = n;
+ while (i--) push_front(*(begin() + n - 1));
+ copy(begin() + n + n, begin() + n + index, begin() + n);
+ fill(begin() + index, begin() + n + index, x);
+ }
+ } else {
+ difference_type orig_len = index + remainder;
+ if (n > remainder) {
+ difference_type m = n - remainder;
+ while (m-- > 0) push_back(x);
+ difference_type i = 0;
+ while (i < remainder) push_back(*(begin() + index + i++));
+ fill(begin() + index, begin() + orig_len, x);
+ } else {
+ difference_type i = 0;
+ while (i < n) push_back(*(begin() + orig_len - n + i++));
+ copy_backward(begin() + index, begin() + orig_len - n,
+ begin() + orig_len);
+ fill(begin() + index, begin() + index + n, x);
+ }
+ }
+}
+
+template <class T>
+void deque<T>::insert
+#ifdef __GNUG__
+(deque_iterator<T> posn, const T* first, const T* last)
+{
+ iterator position = posn;
+#else
+(iterator position, const T* first, const T* last)
+{
+#endif
+ difference_type index = position - begin();
+ difference_type remainder = length - index;
+ size_type n = 0;
+ distance(first, last, n);
+ if (remainder > index) {
+ if (n > index) {
+ const T* m = last - index;
+ while (m != first) push_front(*--m);
+ difference_type i = index;
+ while (i--) push_front(*(begin() + n - 1));
+ copy(last - index, last, begin() + n);
+ } else {
+ difference_type i = n;
+ while (i--) push_front(*(begin() + n - 1));
+ copy(begin() + n + n, begin() + n + index, begin() + n);
+ copy(first, last, begin() + index);
+ }
+ } else {
+ difference_type orig_len = index + remainder;
+ if (n > remainder) {
+ const T* m = first + remainder;
+ while (m != last) push_back(*m++);
+ difference_type i = 0;
+ while (i < remainder) push_back(*(begin() + index + i++));
+ copy(first, first + remainder, begin() + index);
+ } else {
+ difference_type i = 0;
+ while (i < n) push_back(*(begin() + orig_len - n + i++));
+ copy_backward(begin() + index, begin() + orig_len - n,
+ begin() + orig_len);
+ copy(first, last, begin() + index);
+ }
+ }
+}
+
+template <class T>
+#ifdef __GNUG__
+void deque<T>::erase(deque_iterator<T> posn) {
+ iterator position = posn;
+#else
+void deque<T>::erase(iterator position) {
+#endif
+ if (end() - position > position - begin()) {
+ copy_backward(begin(), position, position + 1);
+ pop_front();
+ } else {
+ copy(position + 1, end(), position);
+ pop_back();
+ }
+}
+
+template <class T>
+#ifdef __GNUG__
+void deque<T>::erase(deque_iterator<T> fi, deque_iterator<T> la) {
+ iterator first = fi;
+ iterator last = la;
+ difference_type n = last - first;
+#else
+void deque<T>::erase(iterator first, iterator last) {
+ difference_type n = last - first;
+#endif
+ if (end() - last > first - begin()) {
+ copy_backward(begin(), first, last);
+ while(n-- > 0) pop_front();
+ } else {
+ copy(last, end(), first);
+ while(n-- > 0) pop_back();
+ }
+}
+
+#undef Allocator
+#undef deque
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/faralloc.h b/gnu/lib/libg++/libstdc++/stl/faralloc.h
new file mode 100644
index 00000000000..b29602cc632
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/faralloc.h
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FARALLOC_H
+#define FARALLOC_H
+
+#include <new.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <iostream.h>
+#include <algobase.h>
+
+template <class T>
+inline random_access_iterator_tag iterator_category(const T __far *) {
+ return random_access_iterator_tag();
+}
+
+template <class T>
+inline T* value_type(const T __far *) { return (T*)(0); }
+
+template <class T>
+inline long* distance_type(const T __far*) { return (long*)(0); }
+
+inline void destroy(char __far *) {}
+inline void destroy(unsigned char __far *) {}
+inline void destroy(short __far *) {}
+inline void destroy(unsigned short __far *) {}
+inline void destroy(int __far *) {}
+inline void destroy(unsigned int __far *) {}
+inline void destroy(long __far *) {}
+inline void destroy(unsigned long __far *) {}
+inline void destroy(float __far *) {}
+inline void destroy(double __far *) {}
+
+inline void destroy(char __far *, char __far *) {}
+inline void destroy(unsigned char __far *, unsigned char __far *) {}
+inline void destroy(short __far *, short __far *) {}
+inline void destroy(unsigned short __far *, unsigned short __far *) {}
+inline void destroy(int __far *, int __far *) {}
+inline void destroy(unsigned int __far *, unsigned int __far *) {}
+inline void destroy(long __far *, long __far *) {}
+inline void destroy(unsigned long __far *, unsigned long __far *) {}
+inline void destroy(float __far *, float __far *) {}
+inline void destroy(double __far *, double __far *) {}
+
+inline void __far * operator new(size_t, void __far *p) { return p; }
+
+template <class T>
+inline T __far * allocate(long size, T __far * p) {
+ set_new_handler(0);
+ T __far * tmp =
+ (T __far *)(::operator new((unsigned long)(size * sizeof(T))));
+ if (tmp == 0) {
+ cerr << "out of memory" << endl;
+ exit(1);
+ }
+ return tmp;
+}
+
+template <class T>
+inline void deallocate(T __far * buffer) {
+ ::operator delete(buffer);
+}
+
+template <class T1, class T2>
+inline void construct( T1 __far *p, const T2& value )
+{
+ new(p)T1(value);
+}
+
+template <class T>
+inline void destroy( T __far * pointer ) {
+ pointer->~T();
+}
+
+template <class T>
+class far_allocator {
+public:
+ typedef T value_type;
+ typedef T __far * pointer;
+ typedef const T __far * const_pointer;
+ typedef T __far & reference;
+ typedef const T __far & const_reference;
+ typedef unsigned long size_type;
+ typedef long difference_type;
+ pointer allocate(size_type n) {
+ return ::allocate((difference_type)n, (pointer)0);
+ }
+ void deallocate(pointer p) { ::deallocate(p); }
+ pointer address(reference x) { return (pointer)&x; }
+ const_pointer const_address(const_reference x) {
+ return (const_pointer)&x;
+ }
+ size_type init_page_size() {
+ return max(size_type(1), size_type(4096/sizeof(T)));
+ }
+ size_type max_size() const {
+ return max(size_type(1), size_type(ULONG_MAX/sizeof(T)));
+ }
+};
+
+class far_allocator<void> {
+public:
+ typedef void __far * pointer;
+};
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/fdeque.h b/gnu/lib/libg++/libstdc++/stl/fdeque.h
new file mode 100644
index 00000000000..7b512b62dc2
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/fdeque.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FDEQUE_H
+#define FDEQUE_H
+
+#ifdef DEQUE_H
+#undef DEQUE_H
+#define __DEQUE_WAS_DEFINED
+#endif
+
+#define Allocator far_allocator
+#define deque far_deque
+#include <faralloc.h>
+#include <deque.h>
+
+#undef DEQUE_H
+
+#ifdef __DEQUE_WAS_DEFINED
+#define DEQUE_H
+#undef __DEQUE_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef deque
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/flist.h b/gnu/lib/libg++/libstdc++/stl/flist.h
new file mode 100644
index 00000000000..35fe9bf6288
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/flist.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FLIST_H
+#define FLIST_H
+
+#ifdef LIST_H
+#undef LIST_H
+#define __LIST_WAS_DEFINED
+#endif
+
+#define Allocator far_allocator
+#define list far_list
+#include <faralloc.h>
+#include <list.h>
+
+#undef LIST_H
+
+#ifdef __LIST_WAS_DEFINED
+#define LIST_H
+#undef __LIST_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef list
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/fmap.h b/gnu/lib/libg++/libstdc++/stl/fmap.h
new file mode 100644
index 00000000000..65aa2091fc2
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/fmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FMAP_H
+#define FMAP_H
+
+#ifdef MAP_H
+#undef MAP_H
+#undef TREE_H
+#define __MAP_WAS_DEFINED
+#endif
+
+#define Allocator far_allocator
+#define map far_map
+#define rb_tree far_rb_tree
+#include <faralloc.h>
+#include <map.h>
+
+#undef MAP_H
+#undef TREE_H
+
+#ifdef __MAP_WAS_DEFINED
+#define MAP_H
+#define TREE_H
+#undef __MAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef map
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/fmultmap.h b/gnu/lib/libg++/libstdc++/stl/fmultmap.h
new file mode 100644
index 00000000000..ecb5cd4fdef
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/fmultmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FMULTIMAP_H
+#define FMULTIMAP_H
+
+#ifdef MULTIMAP_H
+#undef MULTIMAP_H
+#undef TREE_H
+#define __MULTIMAP_WAS_DEFINED
+#endif
+
+#define Allocator far_allocator
+#define multimap far_multimap
+#define rb_tree far_rb_tree
+#include <faralloc.h>
+#include <multimap.h>
+
+#undef MULTIMAP_H
+#undef TREE_H
+
+#ifdef __MULTIMAP_WAS_DEFINED
+#define MULTIMAP_H
+#define TREE_H
+#undef __MULTIMAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multimap
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/fmultset.h b/gnu/lib/libg++/libstdc++/stl/fmultset.h
new file mode 100644
index 00000000000..ca9887646ce
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/fmultset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FMULTISET_H
+#define FMULTISET_H
+
+#ifdef MULTISET_H
+#undef MULTISET_H
+#undef TREE_H
+#define __MULTISET_WAS_DEFINED
+#endif
+
+#define Allocator far_allocator
+#define multiset far_multiset
+#define rb_tree far_rb_tree
+#include <faralloc.h>
+#include <multiset.h>
+
+#undef MULTISET_H
+#undef TREE_H
+
+#ifdef __MULTISET_WAS_DEFINED
+#define MULTISET_H
+#define TREE_H
+#undef __MULTISET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multiset
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/fset.h b/gnu/lib/libg++/libstdc++/stl/fset.h
new file mode 100644
index 00000000000..b374bc435a6
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/fset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FSET_H
+#define FSET_H
+
+#ifdef SET_H
+#undef SET_H
+#undef TREE_H
+#define __SET_WAS_DEFINED
+#endif
+
+#define Allocator far_allocator
+#define set far_set
+#define rb_tree far_rb_tree
+#include <faralloc.h>
+#include <set.h>
+
+#undef SET_H
+#undef TREE_H
+
+#ifdef __SET_WAS_DEFINED
+#define SET_H
+#define TREE_H
+#undef __SET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef set
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/function.h b/gnu/lib/libg++/libstdc++/stl/function.h
new file mode 100644
index 00000000000..46fe55569bb
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/function.h
@@ -0,0 +1,282 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef FUNCTION_H
+#define FUNCTION_H
+
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+
+template <class T1, class T2>
+inline bool operator!=(const T1& x, const T2& y) {
+ return !(x == y);
+}
+
+template <class T1, class T2>
+inline bool operator>(const T1& x, const T2& y) {
+ return y < x;
+}
+
+template <class T1, class T2>
+inline bool operator<=(const T1& x, const T2& y) {
+ return !(y < x);
+}
+
+template <class T1, class T2>
+inline bool operator>=(const T1& x, const T2& y) {
+ return !(x < y);
+}
+
+template <class Arg, class Result>
+struct unary_function {
+ typedef Arg argument_type;
+ typedef Result result_type;
+};
+
+template <class Arg1, class Arg2, class Result>
+struct binary_function {
+ typedef Arg1 first_argument_type;
+ typedef Arg2 second_argument_type;
+ typedef Result result_type;
+};
+
+template <class T>
+struct plus : binary_function<T, T, T> {
+ T operator()(const T& x, const T& y) const { return x + y; }
+};
+
+template <class T>
+struct minus : binary_function<T, T, T> {
+ T operator()(const T& x, const T& y) const { return x - y; }
+};
+
+template <class T>
+struct times : binary_function<T, T, T> {
+ T operator()(const T& x, const T& y) const { return x * y; }
+};
+
+template <class T>
+struct divides : binary_function<T, T, T> {
+ T operator()(const T& x, const T& y) const { return x / y; }
+};
+
+template <class T>
+#ifdef __GNU__
+struct modulus {
+ typedef T first_argument_type;
+ typedef T second_argument_type;
+ typedef T result_type;
+ T operator()(const T& x, const T& y) const { return x % y; }
+};
+#else
+struct modulus : binary_function<T, T, T> {
+ T operator()(const T& x, const T& y) const { return x % y; }
+};
+#endif
+
+template <class T>
+struct negate : unary_function<T, T> {
+ T operator()(const T& x) const { return -x; }
+};
+
+template <class T>
+struct equal_to : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x == y; }
+};
+
+template <class T>
+struct not_equal_to : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x != y; }
+};
+
+template <class T>
+struct greater : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x > y; }
+};
+
+template <class T>
+struct less : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x < y; }
+};
+
+template <class T>
+struct greater_equal : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x >= y; }
+};
+
+template <class T>
+struct less_equal : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x <= y; }
+};
+
+template <class T>
+struct logical_and : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x && y; }
+};
+
+template <class T>
+struct logical_or : binary_function<T, T, bool> {
+ bool operator()(const T& x, const T& y) const { return x || y; }
+};
+
+template <class T>
+struct logical_not : unary_function<T, bool> {
+ bool operator()(const T& x) const { return !x; }
+};
+
+template <class Predicate>
+class unary_negate : public unary_function<Predicate::argument_type, bool> {
+protected:
+ Predicate pred;
+public:
+ unary_negate(const Predicate& x) : pred(x) {}
+ bool operator()(const argument_type& x) const { return !pred(x); }
+};
+
+template <class Predicate>
+unary_negate<Predicate> not1(const Predicate& pred) {
+ return unary_negate<Predicate>(pred);
+}
+
+template <class Predicate>
+class binary_negate
+ : public binary_function<Predicate::first_argument_type,
+ Predicate::second_argument_type, bool> {
+protected:
+ Predicate pred;
+public:
+ binary_negate(const Predicate& x) : pred(x) {}
+ bool operator()(const first_argument_type& x,
+ const second_argument_type& y) const {
+ return !pred(x, y);
+ }
+};
+
+template <class Predicate>
+binary_negate<Predicate> not2(const Predicate& pred) {
+ return binary_negate<Predicate>(pred);
+}
+
+template <class Operation>
+class binder1st : public unary_function<Operation::second_argument_type,
+ Operation::result_type> {
+protected:
+ Operation op;
+ Operation::first_argument_type value;
+public:
+ binder1st(const Operation& x, const Operation::first_argument_type& y)
+ : op(x), value(y) {}
+ result_type operator()(const argument_type& x) const {
+ return op(value, x);
+ }
+};
+
+template <class Operation, class T>
+binder1st<Operation> bind1st(const Operation& op, const T& x) {
+ return binder1st<Operation>(op, Operation::first_argument_type(x));
+}
+
+template <class Operation>
+class binder2nd : public unary_function<Operation::first_argument_type,
+ Operation::result_type> {
+protected:
+ Operation op;
+ Operation::second_argument_type value;
+public:
+ binder2nd(const Operation& x, const Operation::second_argument_type& y)
+ : op(x), value(y) {}
+ result_type operator()(const argument_type& x) const {
+ return op(x, value);
+ }
+};
+
+template <class Operation, class T>
+binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
+ return binder2nd<Operation>(op, Operation::second_argument_type(x));
+}
+
+template <class Operation1, class Operation2>
+class unary_compose : public unary_function<Operation2::argument_type,
+ Operation1::result_type> {
+protected:
+ Operation1 op1;
+ Operation2 op2;
+public:
+ unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
+ result_type operator()(const argument_type& x) const {
+ return op1(op2(x));
+ }
+};
+
+template <class Operation1, class Operation2>
+unary_compose<Operation1, Operation2> compose1(const Operation1& op1,
+ const Operation2& op2) {
+ return unary_compose<Operation1, Operation2>(op1, op2);
+}
+
+template <class Operation1, class Operation2, class Operation3>
+class binary_compose : public unary_function<Operation2::argument_type,
+ Operation1::result_type> {
+protected:
+ Operation1 op1;
+ Operation2 op2;
+ Operation3 op3;
+public:
+ binary_compose(const Operation1& x, const Operation2& y,
+ const Operation3& z) : op1(x), op2(y), op3(z) { }
+ result_type operator()(const argument_type& x) const {
+ return op1(op2(x), op3(x));
+ }
+};
+
+template <class Operation1, class Operation2, class Operation3>
+binary_compose<Operation1, Operation2, Operation3>
+compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
+ return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
+}
+
+template <class Arg, class Result>
+class pointer_to_unary_function : public unary_function<Arg, Result> {
+protected:
+ Result (*ptr)(Arg);
+public:
+ pointer_to_unary_function() {}
+ pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
+ Result operator()(Arg x) const { return ptr(x); }
+};
+
+template <class Arg, class Result>
+pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
+ return pointer_to_unary_function<Arg, Result>(x);
+}
+
+template <class Arg1, class Arg2, class Result>
+class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
+protected:
+ Result (*ptr)(Arg1, Arg2);
+public:
+ pointer_to_binary_function() {}
+ pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
+ Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
+};
+
+template <class Arg1, class Arg2, class Result>
+pointer_to_binary_function<Arg1, Arg2, Result>
+ptr_fun(Result (*x)(Arg1, Arg2)) {
+ return pointer_to_binary_function<Arg1, Arg2, Result>(x);
+}
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hdeque.h b/gnu/lib/libg++/libstdc++/stl/hdeque.h
new file mode 100644
index 00000000000..0d47098a06c
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hdeque.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HDEQUE_H
+#define HDEQUE_H
+
+#ifdef DEQUE_H
+#undef DEQUE_H
+#define __DEQUE_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define deque huge_deque
+#include <hugalloc.h>
+#include <deque.h>
+
+#undef DEQUE_H
+
+#ifdef __DEQUE_WAS_DEFINED
+#define DEQUE_H
+#undef __DEQUE_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef deque
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/heap.h b/gnu/lib/libg++/libstdc++/stl/heap.h
new file mode 100644
index 00000000000..7f2747fc5b9
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/heap.h
@@ -0,0 +1,193 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HEAP_H
+#define HEAP_H
+
+template <class RandomAccessIterator, class Distance, class T>
+void __push_heap(RandomAccessIterator first, Distance holeIndex,
+ Distance topIndex, T value) {
+ Distance parent = (holeIndex - 1) / 2;
+ while (holeIndex > topIndex && *(first + parent) < value) {
+ *(first + holeIndex) = *(first + parent);
+ holeIndex = parent;
+ parent = (holeIndex - 1) / 2;
+ }
+ *(first + holeIndex) = value;
+}
+
+template <class RandomAccessIterator, class T>
+inline void __push_heap_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*) {
+ __push_heap(first, (last - first) - 1, 0, T(*(last - 1)));
+}
+
+template <class RandomAccessIterator>
+inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
+ __push_heap_aux(first, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class Distance, class T, class Compare>
+void __push_heap(RandomAccessIterator first, Distance holeIndex,
+ Distance topIndex, T value, Compare comp) {
+ Distance parent = (holeIndex - 1) / 2;
+ while (holeIndex > topIndex && comp(*(first + parent), value)) {
+ *(first + holeIndex) = *(first + parent);
+ holeIndex = parent;
+ parent = (holeIndex - 1) / 2;
+ }
+ *(first + holeIndex) = value;
+}
+
+template <class RandomAccessIterator, class Compare, class T>
+inline void __push_heap_aux(RandomAccessIterator first,
+ RandomAccessIterator last, Compare comp, T*) {
+ __push_heap(first, (last - first) - 1, 0, T(*(last - 1)), comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
+ Compare comp) {
+ __push_heap_aux(first, last, comp, value_type(first));
+}
+
+template <class RandomAccessIterator, class Distance, class T>
+void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
+ Distance len, T value) {
+ Distance topIndex = holeIndex;
+ Distance secondChild = 2 * holeIndex + 2;
+ while (secondChild < len) {
+ if (*(first + secondChild) < *(first + (secondChild - 1)))
+ secondChild--;
+ *(first + holeIndex) = *(first + secondChild);
+ holeIndex = secondChild;
+ secondChild = 2 * (secondChild + 1);
+ }
+ if (secondChild == len) {
+ *(first + holeIndex) = *(first + (secondChild - 1));
+ holeIndex = secondChild - 1;
+ }
+ __push_heap(first, holeIndex, topIndex, value);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
+ RandomAccessIterator result, T value, Distance*) {
+ *result = *first;
+ __adjust_heap(first, Distance(0), Distance(last - first), value);
+}
+
+template <class RandomAccessIterator, class T>
+inline void __pop_heap_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*) {
+ __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
+}
+
+template <class RandomAccessIterator>
+inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
+ __pop_heap_aux(first, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class Distance, class T, class Compare>
+void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
+ Distance len, T value, Compare comp) {
+ Distance topIndex = holeIndex;
+ Distance secondChild = 2 * holeIndex + 2;
+ while (secondChild < len) {
+ if (comp(*(first + secondChild), *(first + (secondChild - 1))))
+ secondChild--;
+ *(first + holeIndex) = *(first + secondChild);
+ holeIndex = secondChild;
+ secondChild = 2 * (secondChild + 1);
+ }
+ if (secondChild == len) {
+ *(first + holeIndex) = *(first + (secondChild - 1));
+ holeIndex = secondChild - 1;
+ }
+ __push_heap(first, holeIndex, topIndex, value, comp);
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
+ RandomAccessIterator result, T value, Compare comp,
+ Distance*) {
+ *result = *first;
+ __adjust_heap(first, Distance(0), Distance(last - first), value, comp);
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+inline void __pop_heap_aux(RandomAccessIterator first,
+ RandomAccessIterator last, T*, Compare comp) {
+ __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
+ distance_type(first));
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
+ Compare comp) {
+ __pop_heap_aux(first, last, value_type(first), comp);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*,
+ Distance*) {
+ if (last - first < 2) return;
+ Distance len = last - first;
+ Distance parent = (len - 2)/2;
+
+ while (true) {
+ __adjust_heap(first, parent, len, T(*(first + parent)));
+ if (parent == 0) return;
+ parent--;
+ }
+}
+
+template <class RandomAccessIterator>
+inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
+ __make_heap(first, last, value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator, class Compare, class T, class Distance>
+void __make_heap(RandomAccessIterator first, RandomAccessIterator last,
+ Compare comp, T*, Distance*) {
+ if (last - first < 2) return;
+ Distance len = last - first;
+ Distance parent = (len - 2)/2;
+
+ while (true) {
+ __adjust_heap(first, parent, len, T(*(first + parent)), comp);
+ if (parent == 0) return;
+ parent--;
+ }
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void make_heap(RandomAccessIterator first, RandomAccessIterator last,
+ Compare comp) {
+ __make_heap(first, last, comp, value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator>
+void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
+ while (last - first > 1) pop_heap(first, last--);
+}
+
+template <class RandomAccessIterator, class Compare>
+void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
+ Compare comp) {
+ while (last - first > 1) pop_heap(first, last--, comp);
+}
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hlist.h b/gnu/lib/libg++/libstdc++/stl/hlist.h
new file mode 100644
index 00000000000..543ffa7a77e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hlist.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HLIST_H
+#define HLIST_H
+
+#ifdef LIST_H
+#undef LIST_H
+#define __LIST_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define list huge_list
+#include <hugalloc.h>
+#include <list.h>
+
+#undef LIST_H
+
+#ifdef __LIST_WAS_DEFINED
+#define LIST_H
+#undef __LIST_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef list
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hmap.h b/gnu/lib/libg++/libstdc++/stl/hmap.h
new file mode 100644
index 00000000000..f40abc042ad
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HMAP_H
+#define HMAP_H
+
+#ifdef MAP_H
+#undef MAP_H
+#undef TREE_H
+#define __MAP_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define map huge_map
+#define rb_tree huge_rb_tree
+#include <hugalloc.h>
+#include <map.h>
+
+#undef MAP_H
+#undef TREE_H
+
+#ifdef __MAP_WAS_DEFINED
+#define MAP_H
+#define TREE_H
+#undef __MAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef map
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hmultmap.h b/gnu/lib/libg++/libstdc++/stl/hmultmap.h
new file mode 100644
index 00000000000..0a8551e9ec5
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hmultmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HMULTIMAP_H
+#define HMULTIMAP_H
+
+#ifdef MULTIMAP_H
+#undef MULTIMAP_H
+#undef TREE_H
+#define __MULTIMAP_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define multimap huge_multimap
+#define rb_tree huge_rb_tree
+#include <hugalloc.h>
+#include <multimap.h>
+
+#undef MULTIMAP_H
+#undef TREE_H
+
+#ifdef __MULTIMAP_WAS_DEFINED
+#define MULTIMAP_H
+#define TREE_H
+#undef __MULTIMAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multimap
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hmultset.h b/gnu/lib/libg++/libstdc++/stl/hmultset.h
new file mode 100644
index 00000000000..e207299603f
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hmultset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HMULTISET_H
+#define HMULTISET_H
+
+#ifdef MULTISET_H
+#undef MULTISET_H
+#undef TREE_H
+#define __MULTISET_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define multiset huge_multiset
+#define rb_tree huge_rb_tree
+#include <hugalloc.h>
+#include <multiset.h>
+
+#undef MULTISET_H
+#undef TREE_H
+
+#ifdef __MULTISET_WAS_DEFINED
+#define MULTISET_H
+#define TREE_H
+#undef __MULTISET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multiset
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hset.h b/gnu/lib/libg++/libstdc++/stl/hset.h
new file mode 100644
index 00000000000..11a15763216
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HSET_H
+#define HSET_H
+
+#ifdef SET_H
+#undef SET_H
+#undef TREE_H
+#define __SET_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define set huge_set
+#define rb_tree huge_rb_tree
+#include <hugalloc.h>
+#include <set.h>
+
+#undef SET_H
+#undef TREE_H
+
+#ifdef __SET_WAS_DEFINED
+#define SET_H
+#define TREE_H
+#undef __SET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef set
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/hugalloc.h b/gnu/lib/libg++/libstdc++/stl/hugalloc.h
new file mode 100644
index 00000000000..a793ab27fd7
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hugalloc.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HUGALLOC_H
+#define HUGALLOC_H
+
+#ifdef FARALLOC_H
+#undef FARALLOC_H
+#define __FARALLOC_WAS_DEFINED
+#endif
+
+#define __far __huge
+#define far_allocator huge_allocator
+#include <faralloc.h>
+#undef __far
+#undef far_allocator
+
+#undef FARALLOC_H
+
+#ifdef __FARALLOC_WAS_DEFINED
+#define FARALLOC_H
+#undef __FARALLOC_WAS_DEFINED
+#endif
+
+#endif
+
diff --git a/gnu/lib/libg++/libstdc++/stl/hvector.h b/gnu/lib/libg++/libstdc++/stl/hvector.h
new file mode 100644
index 00000000000..e7fb41530db
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/hvector.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef HVECTOR_H
+#define HVECTOR_H
+
+#ifdef VECTOR_H
+#undef VECTOR_H
+#define __VECTOR_WAS_DEFINED
+#endif
+
+#define Allocator huge_allocator
+#define vector huge_vector
+#include <hugalloc.h>
+#include <vector.h>
+
+#undef VECTOR_H
+
+#ifdef __VECTOR_WAS_DEFINED
+#define VECTOR_H
+#undef __VECTOR_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef vector
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/iterator.h b/gnu/lib/libg++/libstdc++/stl/iterator.h
new file mode 100644
index 00000000000..5e51598f200
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/iterator.h
@@ -0,0 +1,395 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef ITERATOR_H
+#define ITERATOR_H
+
+#include <stddef.h>
+#include <iostream.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+#include <function.h>
+
+struct input_iterator_tag {};
+struct output_iterator_tag {};
+struct forward_iterator_tag {};
+struct bidirectional_iterator_tag {};
+struct random_access_iterator_tag {};
+
+template <class T, class Distance> struct input_iterator {};
+struct output_iterator {};
+template <class T, class Distance> struct forward_iterator {};
+template <class T, class Distance> struct bidirectional_iterator {};
+template <class T, class Distance> struct random_access_iterator {};
+
+template <class T, class Distance>
+inline input_iterator_tag
+iterator_category(const input_iterator<T, Distance>&) {
+ return input_iterator_tag();
+}
+
+inline output_iterator_tag iterator_category(const output_iterator&) {
+ return output_iterator_tag();
+}
+
+template <class T, class Distance>
+inline forward_iterator_tag
+iterator_category(const forward_iterator<T, Distance>&) {
+ return forward_iterator_tag();
+}
+
+template <class T, class Distance>
+inline bidirectional_iterator_tag
+iterator_category(const bidirectional_iterator<T, Distance>&) {
+ return bidirectional_iterator_tag();
+}
+
+template <class T, class Distance>
+inline random_access_iterator_tag
+iterator_category(const random_access_iterator<T, Distance>&) {
+ return random_access_iterator_tag();
+}
+
+template <class T>
+inline random_access_iterator_tag iterator_category(const T*) {
+ return random_access_iterator_tag();
+}
+
+template <class T, class Distance>
+inline T* value_type(const input_iterator<T, Distance>&) {
+ return (T*)(0);
+}
+
+template <class T, class Distance>
+inline T* value_type(const forward_iterator<T, Distance>&) {
+ return (T*)(0);
+}
+
+template <class T, class Distance>
+inline T* value_type(const bidirectional_iterator<T, Distance>&) {
+ return (T*)(0);
+}
+
+template <class T, class Distance>
+inline T* value_type(const random_access_iterator<T, Distance>&) {
+ return (T*)(0);
+}
+
+template <class T>
+inline T* value_type(const T*) { return (T*)(0); }
+
+template <class T, class Distance>
+inline Distance* distance_type(const input_iterator<T, Distance>&) {
+ return (Distance*)(0);
+}
+
+template <class T, class Distance>
+inline Distance* distance_type(const forward_iterator<T, Distance>&) {
+ return (Distance*)(0);
+}
+
+template <class T, class Distance>
+inline Distance*
+distance_type(const bidirectional_iterator<T, Distance>&) {
+ return (Distance*)(0);
+}
+
+template <class T, class Distance>
+inline Distance*
+distance_type(const random_access_iterator<T, Distance>&) {
+ return (Distance*)(0);
+}
+
+template <class T>
+inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
+
+template <class Container>
+class back_insert_iterator : public output_iterator {
+protected:
+ Container& container;
+public:
+ back_insert_iterator(Container& x) : container(x) {}
+ back_insert_iterator<Container>&
+ operator=(const Container::value_type& value) {
+ container.push_back(value);
+ return *this;
+ }
+ back_insert_iterator<Container>& operator*() { return *this; }
+ back_insert_iterator<Container>& operator++() { return *this; }
+ back_insert_iterator<Container>& operator++(int) { return *this; }
+};
+
+template <class Container>
+back_insert_iterator<Container> back_inserter(Container& x) {
+ return back_insert_iterator<Container>(x);
+}
+
+template <class Container>
+class front_insert_iterator : public output_iterator {
+protected:
+ Container& container;
+public:
+ front_insert_iterator(Container& x) : container(x) {}
+ front_insert_iterator<Container>&
+ operator=(const Container::value_type& value) {
+ container.push_front(value);
+ return *this;
+ }
+ front_insert_iterator<Container>& operator*() { return *this; }
+ front_insert_iterator<Container>& operator++() { return *this; }
+ front_insert_iterator<Container>& operator++(int) { return *this; }
+};
+
+template <class Container>
+front_insert_iterator<Container> front_inserter(Container& x) {
+ return front_insert_iterator<Container>(x);
+}
+
+template <class Container>
+class insert_iterator : public output_iterator {
+protected:
+ Container& container;
+ Container::iterator iter;
+public:
+ insert_iterator(Container& x, Container::iterator i)
+ : container(x), iter(i) {}
+ insert_iterator<Container>&
+ operator=(const Container::value_type& value) {
+ iter = container.insert(iter, value);
+ ++iter;
+ return *this;
+ }
+ insert_iterator<Container>& operator*() { return *this; }
+ insert_iterator<Container>& operator++() { return *this; }
+ insert_iterator<Container>& operator++(int) { return *this; }
+};
+
+template <class Container, class Iterator>
+insert_iterator<Container> inserter(Container& x, Iterator i) {
+ return insert_iterator<Container>(x, Container::iterator(i));
+}
+
+template <class BidirectionalIterator, class T, class Reference,
+ class Distance = ptrdiff_t>
+// Reference = T&
+class reverse_bidirectional_iterator
+ : public bidirectional_iterator<T, Distance> {
+ typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
+ Distance> self;
+ friend bool operator==(const self& x, const self& y);
+protected:
+ BidirectionalIterator current;
+public:
+ reverse_bidirectional_iterator() {}
+ reverse_bidirectional_iterator(BidirectionalIterator x) : current(x) {}
+ BidirectionalIterator base() { return current; }
+ Reference operator*() const {
+ BidirectionalIterator tmp = current;
+ return *--tmp;
+ }
+ self& operator++() {
+ --current;
+ return *this;
+ }
+ self operator++(int) {
+ self tmp = *this;
+ --current;
+ return tmp;
+ }
+ self& operator--() {
+ ++current;
+ return *this;
+ }
+ self operator--(int) {
+ self tmp = *this;
+ ++current;
+ return tmp;
+ }
+};
+
+template <class BidirectionalIterator, class T, class Reference,
+ class Distance>
+inline bool operator==(
+ const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
+ Distance>& x,
+ const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
+ Distance>& y) {
+ return x.current == y.current;
+}
+
+template <class RandomAccessIterator, class T, class Reference,
+ class Distance = ptrdiff_t>
+// Reference = T&
+class reverse_iterator : public random_access_iterator<T, Distance> {
+ typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
+ self;
+ friend bool operator==(const self& x, const self& y);
+ friend bool operator<(const self& x, const self& y);
+ friend Distance operator-(const self& x, const self& y);
+ friend self operator+(Distance n, const self& x);
+protected:
+ RandomAccessIterator current;
+public:
+ reverse_iterator() {}
+ reverse_iterator(RandomAccessIterator x) : current(x) {}
+ RandomAccessIterator base() { return current; }
+ Reference operator*() const { return *(current - 1); }
+ self& operator++() {
+ --current;
+ return *this;
+ }
+ self operator++(int) {
+ self tmp = *this;
+ --current;
+ return tmp;
+ }
+ self& operator--() {
+ ++current;
+ return *this;
+ }
+ self operator--(int) {
+ self tmp = *this;
+ ++current;
+ return tmp;
+ }
+ self operator+(Distance n) const {
+ return self(current - n);
+ }
+ self& operator+=(Distance n) {
+ current -= n;
+ return *this;
+ }
+ self operator-(Distance n) const {
+ return self(current + n);
+ }
+ self& operator-=(Distance n) {
+ current += n;
+ return *this;
+ }
+ Reference operator[](Distance n) { return *(*this + n); }
+};
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
+ Reference, Distance>& x,
+ const reverse_iterator<RandomAccessIterator, T,
+ Reference, Distance>& y) {
+ return x.current == y.current;
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
+ Reference, Distance>& x,
+ const reverse_iterator<RandomAccessIterator, T,
+ Reference, Distance>& y) {
+ return y.current < x.current;
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
+ Reference, Distance>& x,
+ const reverse_iterator<RandomAccessIterator, T,
+ Reference, Distance>& y) {
+ return y.current - x.current;
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline reverse_iterator<RandomAccessIterator, T, Reference, Distance>
+operator+(Distance n,
+ const reverse_iterator<RandomAccessIterator, T, Reference,
+ Distance>& x) {
+ return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
+ (x.current - n);
+}
+
+
+template <class OutputIterator, class T>
+class raw_storage_iterator : public output_iterator {
+protected:
+ OutputIterator iter;
+public:
+ raw_storage_iterator(OutputIterator x) : iter(x) {}
+ raw_storage_iterator<OutputIterator, T>& operator*() { return *this; }
+ raw_storage_iterator<OutputIterator, T>& operator=(const T& element) {
+ construct(iter, element);
+ return *this;
+ }
+ raw_storage_iterator<OutputIterator, T>& operator++() {
+ ++iter;
+ return *this;
+ }
+ raw_storage_iterator<OutputIterator, T> operator++(int) {
+ raw_storage_iterator<OutputIterator, T> tmp = *this;
+ ++iter;
+ return tmp;
+ }
+};
+
+
+template <class T, class Distance = ptrdiff_t>
+class istream_iterator : public input_iterator<T, Distance> {
+friend bool operator==(const istream_iterator<T, Distance>& x,
+ const istream_iterator<T, Distance>& y);
+protected:
+ istream* stream;
+ T value;
+ bool end_marker;
+ void read() {
+ end_marker = (*stream) ? true : false;
+ if (end_marker) *stream >> value;
+ end_marker = (*stream) ? true : false;
+ }
+public:
+ istream_iterator() : stream(&cin), end_marker(false) {}
+ istream_iterator(istream& s) : stream(&s) { read(); }
+ const T& operator*() const { return value; }
+ istream_iterator<T, Distance>& operator++() {
+ read();
+ return *this;
+ }
+ istream_iterator<T, Distance> operator++(int) {
+ istream_iterator<T, Distance> tmp = *this;
+ read();
+ return tmp;
+ }
+};
+
+template <class T, class Distance>
+bool operator==(const istream_iterator<T, Distance>& x,
+ const istream_iterator<T, Distance>& y) {
+ return x.stream == y.stream && x.end_marker == y.end_marker ||
+ x.end_marker == false && y.end_marker == false;
+}
+
+template <class T>
+class ostream_iterator : public output_iterator {
+protected:
+ ostream* stream;
+ char* string;
+public:
+ ostream_iterator(ostream& s) : stream(&s), string(0) {}
+ ostream_iterator(ostream& s, char* c) : stream(&s), string(c) {}
+ ostream_iterator<T>& operator=(const T& value) {
+ *stream << value;
+ if (string) *stream << string;
+ return *this;
+ }
+ ostream_iterator<T>& operator*() { return *this; }
+ ostream_iterator<T>& operator++() { return *this; }
+ ostream_iterator<T>& operator++(int) { return *this; }
+};
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/lbvector.h b/gnu/lib/libg++/libstdc++/stl/lbvector.h
new file mode 100644
index 00000000000..763666c3d39
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/lbvector.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LBVECTOR_H
+#define LBVECTOR_H
+
+#ifdef BVECTOR_H
+#undef BVECTOR_H
+#define __BVECTOR_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define bit_vector long_bit_vector
+#include <lngalloc.h>
+#include <bvector.h>
+
+#undef BVECTOR_H
+
+#ifdef __BVECTOR_WAS_DEFINED
+#define BVECTOR_H
+#undef __BVECTOR_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef bit_vector
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/ldeque.h b/gnu/lib/libg++/libstdc++/stl/ldeque.h
new file mode 100644
index 00000000000..4c8761c9f8b
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/ldeque.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LDEQUE_H
+#define LDEQUE_H
+
+#ifdef DEQUE_H
+#undef DEQUE_H
+#define __DEQUE_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define deque long_deque
+#include <lngalloc.h>
+#include <deque.h>
+
+#undef DEQUE_H
+
+#ifdef __DEQUE_WAS_DEFINED
+#define DEQUE_H
+#undef __DEQUE_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef deque
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/list.h b/gnu/lib/libg++/libstdc++/stl/list.h
new file mode 100644
index 00000000000..42b5d0f5f67
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/list.h
@@ -0,0 +1,531 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LIST_H
+#define LIST_H
+
+#include <function.h>
+#include <algobase.h>
+#include <iterator.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#ifndef list
+#define list list
+#endif
+
+template <class T>
+class list {
+protected:
+ typedef Allocator<void>::pointer void_pointer;
+ struct list_node;
+ friend list_node;
+ struct list_node {
+ void_pointer next;
+ void_pointer prev;
+ T data;
+ };
+#ifndef __GNUG__
+ static Allocator<list_node> list_node_allocator;
+ static Allocator<T> value_allocator;
+#endif
+public:
+ typedef T value_type;
+ typedef Allocator<T> value_allocator_type;
+ typedef Allocator<T>::pointer pointer;
+ typedef Allocator<T>::reference reference;
+ typedef Allocator<T>::const_reference const_reference;
+ typedef Allocator<list_node> list_node_allocator_type;
+ typedef Allocator<list_node>::pointer link_type;
+ typedef Allocator<list_node>::size_type size_type;
+ typedef Allocator<list_node>::difference_type difference_type;
+protected:
+#ifdef __GNUG__
+ link_type get_node() { return (link_type)(::operator new(sizeof(list_node))); }
+ void put_node(link_type p) { ::operator delete(p); }
+#else
+ size_type buffer_size() {
+ return list_node_allocator.init_page_size();
+ }
+ struct list_node_buffer;
+ friend list_node_buffer;
+ struct list_node_buffer {
+ void_pointer next_buffer;
+ link_type buffer;
+ };
+public:
+ typedef Allocator<list_node_buffer> buffer_allocator_type;
+ typedef Allocator<list_node_buffer>::pointer buffer_pointer;
+protected:
+ static Allocator<list_node_buffer> buffer_allocator;
+ static buffer_pointer buffer_list;
+ static link_type free_list;
+ static link_type next_avail;
+ static link_type last;
+ void add_new_buffer() {
+ buffer_pointer tmp = buffer_allocator.allocate((size_type)1);
+ tmp->buffer = list_node_allocator.allocate(buffer_size());
+ tmp->next_buffer = buffer_list;
+ buffer_list = tmp;
+ next_avail = buffer_list->buffer;
+ last = next_avail + buffer_size();
+ }
+ static size_type number_of_lists;
+ void deallocate_buffers();
+ link_type get_node() {
+ link_type tmp = free_list;
+ return free_list ? (free_list = (link_type)(free_list->next), tmp)
+ : (next_avail == last ? (add_new_buffer(), next_avail++)
+ : next_avail++);
+ // ugly code for inlining - avoids multiple returns
+ }
+ void put_node(link_type p) {
+ p->next = free_list;
+ free_list = p;
+ }
+#endif
+
+ link_type node;
+ size_type length;
+public:
+ class iterator;
+ class const_iterator;
+ class iterator : public bidirectional_iterator<T, difference_type> {
+ friend class list<T>;
+ friend class const_iterator;
+// friend bool operator==(const iterator& x, const iterator& y);
+ protected:
+ link_type node;
+ iterator(link_type x) : node(x) {}
+ public:
+ iterator() {}
+ bool operator==(const iterator& x) const { return node == x.node; }
+ reference operator*() const { return (*node).data; }
+ iterator& operator++() {
+ node = (link_type)((*node).next);
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ iterator& operator--() {
+ node = (link_type)((*node).prev);
+ return *this;
+ }
+ iterator operator--(int) {
+ iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ };
+ class const_iterator : public bidirectional_iterator<T, difference_type> {
+ friend class list<T>;
+ protected:
+ link_type node;
+ const_iterator(link_type x) : node(x) {}
+ public:
+ const_iterator() {}
+ const_iterator(const iterator& x) : node(x.node) {}
+ bool operator==(const const_iterator& x) const { return node == x.node; }
+ const_reference operator*() const { return (*node).data; }
+ const_iterator& operator++() {
+ node = (link_type)((*node).next);
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ const_iterator& operator--() {
+ node = (link_type)((*node).prev);
+ return *this;
+ }
+ const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ };
+ typedef reverse_bidirectional_iterator<const_iterator, value_type,
+ const_reference, difference_type>
+ const_reverse_iterator;
+ typedef reverse_bidirectional_iterator<iterator, value_type, reference,
+ difference_type>
+ reverse_iterator;
+ list() : length(0) {
+#ifndef __GNUG__
+ ++number_of_lists;
+#endif
+ node = get_node();
+ (*node).next = node;
+ (*node).prev = node;
+ }
+ iterator begin() { return (link_type)((*node).next); }
+ const_iterator begin() const { return (link_type)((*node).next); }
+ iterator end() { return node; }
+ const_iterator end() const { return node; }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+ bool empty() const { return length == 0; }
+ size_type size() const { return length; }
+#ifndef __GNUG__
+ size_type max_size() const { return list_node_allocator.max_size(); }
+#endif
+ reference front() { return *begin(); }
+ const_reference front() const { return *begin(); }
+ reference back() { return *(--end()); }
+ const_reference back() const { return *(--end()); }
+ void swap(list<T>& x) {
+ ::swap(node, x.node);
+ ::swap(length, x.length);
+ }
+ iterator insert(iterator position, const T& x) {
+ link_type tmp = get_node();
+#ifdef __GNUG__
+ construct(&(*tmp).data, x);
+#else
+ construct(value_allocator.address((*tmp).data), x);
+#endif
+ (*tmp).next = position.node;
+ (*tmp).prev = (*position.node).prev;
+ (*(link_type((*position.node).prev))).next = tmp;
+ (*position.node).prev = tmp;
+ ++length;
+ return tmp;
+ }
+#ifdef __GNUG__
+ void insert(iterator position, const T* first, const T* last) {
+ while (first != last) insert(position, *first++);
+ }
+ void insert(iterator position, const_iterator first,
+ const_iterator last) {
+ while (first != last) insert(position, *first++);
+ }
+ void insert(iterator position, size_type n, const T& x) {
+ while (n--) insert(position, x);
+ }
+#else
+ void insert(iterator position, const T* first, const T* last);
+ void insert(iterator position, const_iterator first,
+ const_iterator last);
+ void insert(iterator position, size_type n, const T& x);
+#endif
+ void push_front(const T& x) { insert(begin(), x); }
+ void push_back(const T& x) { insert(end(), x); }
+ void erase(iterator position) {
+ (*(link_type((*position.node).prev))).next = (*position.node).next;
+ (*(link_type((*position.node).next))).prev = (*position.node).prev;
+#ifdef __GNUG__
+ destroy(&(*position.node).data);
+#else
+ destroy(value_allocator.address((*position.node).data));
+#endif
+ put_node(position.node);
+ --length;
+ }
+#ifdef __GNUG__
+ void erase(iterator first, iterator last) {
+ while (first != last) erase(first++);
+ }
+#else
+ void erase(iterator first, iterator last);
+#endif
+ void pop_front() { erase(begin()); }
+ void pop_back() {
+ iterator tmp = end();
+ erase(--tmp);
+ }
+ list(size_type n, const T& value = T()) : length(0) {
+#ifndef __GNUG__
+ ++number_of_lists;
+#endif
+ node = get_node();
+ (*node).next = node;
+ (*node).prev = node;
+ insert(begin(), n, value);
+ }
+ list(const T* first, const T* last) : length(0) {
+#ifndef __GNUG__
+ ++number_of_lists;
+#endif
+ node = get_node();
+ (*node).next = node;
+ (*node).prev = node;
+ insert(begin(), first, last);
+ }
+ list(const list<T>& x) : length(0) {
+#ifndef __GNUG__
+ ++number_of_lists;
+#endif
+ node = get_node();
+ (*node).next = node;
+ (*node).prev = node;
+ insert(begin(), x.begin(), x.end());
+ }
+ ~list() {
+ erase(begin(), end());
+ put_node(node);
+#ifndef __GNUG__
+ if (--number_of_lists == 0) deallocate_buffers();
+#endif
+ }
+ list<T>& operator=(const list<T>& x);
+protected:
+ void transfer(iterator position, iterator first, iterator last) {
+ (*(link_type((*last.node).prev))).next = position.node;
+ (*(link_type((*first.node).prev))).next = last.node;
+ (*(link_type((*position.node).prev))).next = first.node;
+ link_type tmp = link_type((*position.node).prev);
+ (*position.node).prev = (*last.node).prev;
+ (*last.node).prev = (*first.node).prev;
+ (*first.node).prev = tmp;
+ }
+public:
+ void splice(iterator position, list<T>& x) {
+ if (!x.empty()) {
+ transfer(position, x.begin(), x.end());
+ length += x.length;
+ x.length = 0;
+ }
+ }
+ void splice(iterator position, list<T>& x, iterator i) {
+ iterator j = i;
+ if (position == i || position == ++j) return;
+ transfer(position, i, j);
+ ++length;
+ --x.length;
+ }
+ void splice(iterator position, list<T>& x, iterator first, iterator last) {
+ if (first != last) {
+ if (&x != this) {
+ difference_type n = 0;
+ distance(first, last, n);
+ x.length -= n;
+ length += n;
+ }
+ transfer(position, first, last);
+ }
+ }
+ void remove(const T& value);
+ void unique();
+ void merge(list<T>& x);
+ void reverse();
+ void sort();
+#ifdef __GNUG__
+ friend difference_type* distance_type(const iterator&) {
+ return (difference_type*)(0);
+ }
+ friend T* value_type(const iterator&) {
+ return (T*)(0);
+ }
+ friend bidirectional_iterator_tag iterator_category(iterator) {
+ return bidirectional_iterator_tag();
+ }
+#endif
+};
+
+#ifndef __GNUG__
+template <class T>
+list<T>::buffer_pointer list<T>::buffer_list = 0;
+
+template <class T>
+list<T>::link_type list<T>::free_list = 0;
+
+template <class T>
+list<T>::link_type list<T>::next_avail = 0;
+
+template <class T>
+list<T>::link_type list<T>::last = 0;
+
+template <class T>
+list<T>::size_type list<T>::number_of_lists = 0;
+
+template <class T>
+list<T>::list_node_allocator_type list<T>::list_node_allocator;
+
+template <class T>
+list<T>::value_allocator_type list<T>::value_allocator;
+
+template <class T>
+list<T>::buffer_allocator_type list<T>::buffer_allocator;
+#endif
+
+/*
+ * currently the following does not work - made into a member function
+
+template <class T>
+inline bool operator==(const list<T>::iterator& x, const list<T>::iterator& y) {
+ return x.node == y.node;
+}
+*/
+
+template <class T>
+inline bool operator==(const list<T>& x, const list<T>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T>
+inline bool operator<(const list<T>& x, const list<T>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#ifndef __GNUG__
+template <class T>
+void list<T>::deallocate_buffers() {
+ while (buffer_list) {
+ buffer_pointer tmp = buffer_list;
+ buffer_list = (buffer_pointer)(buffer_list->next_buffer);
+ list_node_allocator.deallocate(tmp->buffer);
+ buffer_allocator.deallocate(tmp);
+ }
+ free_list = 0;
+ next_avail = 0;
+ last = 0;
+}
+#endif
+
+#ifndef __GNUG__
+template <class T>
+void list<T>::insert(iterator position, const T* first, const T* last) {
+ while (first != last) insert(position, *first++);
+}
+
+template <class T>
+void list<T>::insert(iterator position, const_iterator first,
+ const_iterator last) {
+ while (first != last) insert(position, *first++);
+}
+
+template <class T>
+void list<T>::insert(iterator position, size_type n, const T& x) {
+ while (n--) insert(position, x);
+}
+
+template <class T>
+void list<T>::erase(iterator first, iterator last) {
+ while (first != last) erase(first++);
+}
+#endif
+
+template <class T>
+list<T>& list<T>::operator=(const list<T>& x) {
+ if (this != &x) {
+ iterator first1 = begin();
+ iterator last1 = end();
+ const_iterator first2 = x.begin();
+ const_iterator last2 = x.end();
+ while (first1 != last1 && first2 != last2) *first1++ = *first2++;
+ if (first2 == last2)
+ erase(first1, last1);
+ else
+ insert(last1, first2, last2);
+ }
+ return *this;
+}
+
+template <class T>
+void list<T>::remove(const T& value) {
+ iterator first = begin();
+ iterator last = end();
+ while (first != last) {
+ iterator next = first;
+ ++next;
+ if (*first == value) erase(first);
+ first = next;
+ }
+}
+
+template <class T>
+void list<T>::unique() {
+ iterator first = begin();
+ iterator last = end();
+ if (first == last) return;
+ iterator next = first;
+ while (++next != last) {
+ if (*first == *next)
+ erase(next);
+ else
+ first = next;
+ next = first;
+ }
+}
+
+template <class T>
+void list<T>::merge(list<T>& x) {
+ iterator first1 = begin();
+ iterator last1 = end();
+ iterator first2 = x.begin();
+ iterator last2 = x.end();
+ while (first1 != last1 && first2 != last2)
+ if (*first2 < *first1) {
+ iterator next = first2;
+ transfer(first1, first2, ++next);
+ first2 = next;
+ } else
+ ++first1;
+ if (first2 != last2) transfer(last1, first2, last2);
+ length += x.length;
+ x.length= 0;
+}
+
+template <class T>
+void list<T>::reverse() {
+ if (size() < 2) return;
+ for (iterator first = ++begin(); first != end();) {
+ iterator old = first++;
+ transfer(begin(), old, first);
+ }
+}
+
+template <class T>
+void list<T>::sort() {
+ if (size() < 2) return;
+ list<T> carry;
+ list<T> counter[64];
+ int fill = 0;
+ while (!empty()) {
+ carry.splice(carry.begin(), *this, begin());
+ int i = 0;
+ while(i < fill && !counter[i].empty()) {
+ counter[i].merge(carry);
+ carry.swap(counter[i++]);
+ }
+ carry.swap(counter[i]);
+ if (i == fill) ++fill;
+ }
+
+ for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
+ swap(counter[fill-1]);
+}
+
+#undef Allocator
+#undef list
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/llist.h b/gnu/lib/libg++/libstdc++/stl/llist.h
new file mode 100644
index 00000000000..07ee6113a09
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/llist.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LLIST_H
+#define LLIST_H
+
+#ifdef LIST_H
+#undef LIST_H
+#define __LIST_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define list long_list
+#include <lngalloc.h>
+#include <list.h>
+
+#undef LIST_H
+
+#ifdef __LIST_WAS_DEFINED
+#define LIST_H
+#undef __LIST_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef list
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/lmap.h b/gnu/lib/libg++/libstdc++/stl/lmap.h
new file mode 100644
index 00000000000..da1eeba6c8c
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/lmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LMAP_H
+#define LMAP_H
+
+#ifdef MAP_H
+#undef MAP_H
+#undef TREE_H
+#define __MAP_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define map long_map
+#define rb_tree long_rb_tree
+#include <lngalloc.h>
+#include <map.h>
+
+#undef MAP_H
+#undef TREE_H
+
+#ifdef __MAP_WAS_DEFINED
+#define MAP_H
+#define TREE_H
+#undef __MAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef map
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/lmultmap.h b/gnu/lib/libg++/libstdc++/stl/lmultmap.h
new file mode 100644
index 00000000000..1a87e3372d8
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/lmultmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LMULTIMAP_H
+#define LMULTIMAP_H
+
+#ifdef MULTIMAP_H
+#undef MULTIMAP_H
+#undef TREE_H
+#define __MULTIMAP_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define multimap long_multimap
+#define rb_tree long_rb_tree
+#include <lngalloc.h>
+#include <multimap.h>
+
+#undef MULTIMAP_H
+#undef TREE_H
+
+#ifdef __MULTIMAP_WAS_DEFINED
+#define MULTIMAP_H
+#define TREE_H
+#undef __MULTIMAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multimap
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/lmultset.h b/gnu/lib/libg++/libstdc++/stl/lmultset.h
new file mode 100644
index 00000000000..bb1571f6c90
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/lmultset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LMULTISET_H
+#define LMULTISET_H
+
+#ifdef MULTISET_H
+#undef MULTISET_H
+#undef TREE_H
+#define __MULTISET_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define multiset long_multiset
+#define rb_tree long_rb_tree
+#include <lngalloc.h>
+#include <multiset.h>
+
+#undef MULTISET_H
+#undef TREE_H
+
+#ifdef __MULTISET_WAS_DEFINED
+#define MULTISET_H
+#define TREE_H
+#undef __MULTISET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multiset
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/lngalloc.h b/gnu/lib/libg++/libstdc++/stl/lngalloc.h
new file mode 100644
index 00000000000..6685ea54511
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/lngalloc.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LNGALLOC_H
+#define LNGALLOC_H
+
+#include <limits.h>
+#include <algobase.h>
+#include <defalloc.h>
+
+template <class T>
+class long_allocator {
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef unsigned long size_type;
+ typedef long difference_type;
+ pointer allocate(size_type n) {
+ return ::allocate((difference_type)n, (pointer)0);
+ }
+ void deallocate(pointer p) { ::deallocate(p); }
+ pointer address(reference x) { return (pointer)&x; }
+ const_pointer const_address(const_reference x) {
+ return (const_pointer)&x;
+ }
+ size_type init_page_size() {
+ return max(size_type(1), size_type(4096/sizeof(T)));
+ }
+ size_type max_size() const {
+ return max(size_type(1), size_type(ULONG_MAX/sizeof(T)));
+ }
+};
+
+class long_allocator<void> {
+public:
+ typedef void* pointer;
+};
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/lset.h b/gnu/lib/libg++/libstdc++/stl/lset.h
new file mode 100644
index 00000000000..e4d52f7c39e
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/lset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef LSET_H
+#define LSET_H
+
+#ifdef SET_H
+#undef SET_H
+#undef TREE_H
+#define __SET_WAS_DEFINED
+#endif
+
+#define Allocator long_allocator
+#define set long_set
+#define rb_tree long_rb_tree
+#include <lngalloc.h>
+#include <set.h>
+
+#undef SET_H
+#undef TREE_H
+
+#ifdef __SET_WAS_DEFINED
+#define SET_H
+#define TREE_H
+#undef __SET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef set
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/map.h b/gnu/lib/libg++/libstdc++/stl/map.h
new file mode 100644
index 00000000000..5c1c30d49e6
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/map.h
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef MAP_H
+#define MAP_H
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#include <tree.h>
+
+template <class Key, class T, class Compare>
+class map {
+public:
+
+// typedefs:
+
+ typedef Key key_type;
+ typedef pair<const Key, T> value_type;
+ typedef Compare key_compare;
+
+ class value_compare
+ : public binary_function<value_type, value_type, bool> {
+ friend class map<Key, T, Compare>;
+ protected :
+ Compare comp;
+ value_compare(Compare c) : comp(c) {}
+ public:
+ bool operator()(const value_type& x, const value_type& y) const {
+ return comp(x.first, y.first);
+ }
+ };
+
+private:
+ typedef rb_tree<key_type, value_type,
+ select1st<value_type, key_type>, key_compare> rep_type;
+ rep_type t; // red-black tree representing map
+public:
+ typedef rep_type::pointer pointer;
+ typedef rep_type::reference reference;
+ typedef rep_type::const_reference const_reference;
+ typedef rep_type::iterator iterator;
+ typedef rep_type::const_iterator const_iterator;
+ typedef rep_type::reverse_iterator reverse_iterator;
+ typedef rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef rep_type::size_type size_type;
+ typedef rep_type::difference_type difference_type;
+
+// allocation/deallocation
+
+ map(const Compare& comp = Compare()) : t(comp, false) {}
+ map(const value_type* first, const value_type* last,
+ const Compare& comp = Compare()) : t(first, last, comp, false) {}
+ map(const map<Key, T, Compare>& x) : t(x.t, false) {}
+ map<Key, T, Compare>& operator=(const map<Key, T, Compare>& x) {
+ t = x.t;
+ return *this;
+ }
+
+// accessors:
+
+ key_compare key_comp() const { return t.key_comp(); }
+ value_compare value_comp() const { return value_compare(t.key_comp()); }
+ iterator begin() { return t.begin(); }
+ const_iterator begin() const { return t.begin(); }
+ iterator end() { return t.end(); }
+ const_iterator end() const { return t.end(); }
+ reverse_iterator rbegin() { return t.rbegin(); }
+ const_reverse_iterator rbegin() const { return t.rbegin(); }
+ reverse_iterator rend() { return t.rend(); }
+ const_reverse_iterator rend() const { return t.rend(); }
+ bool empty() const { return t.empty(); }
+ size_type size() const { return t.size(); }
+#ifndef __GNUG__
+ size_type max_size() const { return t.max_size(); }
+#endif
+ Allocator<T>::reference operator[](const key_type& k) {
+ return (*((insert(value_type(k, T()))).first)).second;
+ }
+ void swap(map<Key, T, Compare>& x) { t.swap(x.t); }
+
+// insert/erase
+
+ typedef pair<iterator, bool> pair_iterator_bool;
+ // typedef done to get around compiler bug
+ pair_iterator_bool insert(const value_type& x) { return t.insert(x); }
+ iterator insert(iterator position, const value_type& x) {
+ return t.insert(position, x);
+ }
+ void insert(const value_type* first, const value_type* last) {
+ t.insert(first, last);
+ }
+ void erase(iterator position) { t.erase(position); }
+ size_type erase(const key_type& x) { return t.erase(x); }
+ void erase(iterator first, iterator last) { t.erase(first, last); }
+
+// map operations:
+
+ iterator find(const key_type& x) { return t.find(x); }
+ const_iterator find(const key_type& x) const { return t.find(x); }
+ size_type count(const key_type& x) const { return t.count(x); }
+ iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
+ const_iterator lower_bound(const key_type& x) const {
+ return t.lower_bound(x);
+ }
+ iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
+ const_iterator upper_bound(const key_type& x) const {
+ return t.upper_bound(x);
+ }
+ typedef pair<iterator, iterator> pair_iterator_iterator;
+ // typedef done to get around compiler bug
+ pair_iterator_iterator equal_range(const key_type& x) {
+ return t.equal_range(x);
+ }
+ typedef pair<const_iterator, const_iterator> pair_citerator_citerator;
+ // typedef done to get around compiler bug
+ pair_citerator_citerator equal_range(const key_type& x) const {
+ return t.equal_range(x);
+ }
+};
+
+template <class Key, class T, class Compare>
+inline bool operator==(const map<Key, T, Compare>& x,
+ const map<Key, T, Compare>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class T, class Compare>
+inline bool operator<(const map<Key, T, Compare>& x,
+ const map<Key, T, Compare>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#undef Allocator
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/multimap.h b/gnu/lib/libg++/libstdc++/stl/multimap.h
new file mode 100644
index 00000000000..2478e2419fa
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/multimap.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef MULTIMAP_H
+#define MULTIMAP_H
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#include <tree.h>
+
+template <class Key, class T, class Compare>
+class multimap {
+public:
+
+// typedefs:
+
+ typedef Key key_type;
+ typedef pair<const Key, T> value_type;
+ typedef Compare key_compare;
+
+ class value_compare
+ : public binary_function<value_type, value_type, bool> {
+ friend class multimap<Key, T, Compare>;
+ protected:
+ Compare comp;
+ value_compare(Compare c) : comp(c) {}
+ public:
+ bool operator()(const value_type& x, const value_type& y) const {
+ return comp(x.first, y.first);
+ }
+ };
+
+private:
+ typedef rb_tree<key_type, value_type,
+ select1st<value_type, key_type>, key_compare> rep_type;
+ rep_type t; // red-black tree representing multimap
+public:
+ typedef rep_type::reference reference;
+ typedef rep_type::const_reference const_reference;
+ typedef rep_type::iterator iterator;
+ typedef rep_type::const_iterator const_iterator;
+ typedef rep_type::reverse_iterator reverse_iterator;
+ typedef rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef rep_type::size_type size_type;
+ typedef rep_type::difference_type difference_type;
+
+// allocation/deallocation
+
+ multimap(const Compare& comp = Compare()) : t(comp, true) { }
+ multimap(const value_type* first, const value_type* last,
+ const Compare& comp = Compare()) : t(first, last, comp, true) { }
+ multimap(const multimap<Key, T, Compare>& x) : t(x.t, true) { }
+ multimap<Key, T, Compare>& operator=(const multimap<Key, T, Compare>& x) {
+ t = x.t;
+ return *this;
+ }
+
+// accessors:
+
+ key_compare key_comp() const { return t.key_comp(); }
+ value_compare value_comp() const { return value_compare(t.key_comp()); }
+ iterator begin() { return t.begin(); }
+ const_iterator begin() const { return t.begin(); }
+ iterator end() { return t.end(); }
+ const_iterator end() const { return t.end(); }
+ reverse_iterator rbegin() { return t.rbegin(); }
+ const_reverse_iterator rbegin() const { return t.rbegin(); }
+ reverse_iterator rend() { return t.rend(); }
+ const_reverse_iterator rend() const { return t.rend(); }
+ bool empty() const { return t.empty(); }
+ size_type size() const { return t.size(); }
+ size_type max_size() const { return t.max_size(); }
+ void swap(multimap<Key, T, Compare>& x) { t.swap(x.t); }
+
+// insert/erase
+
+ iterator insert(const value_type& x) { return t.insert(x).first; }
+ iterator insert(iterator position, const value_type& x) {
+ return t.insert(position, x);
+ }
+ void insert(const value_type* first, const value_type* last) {
+ t.insert(first, last);
+ }
+ void erase(iterator position) { t.erase(position); }
+ size_type erase(const key_type& x) { return t.erase(x); }
+ void erase(iterator first, iterator last) { t.erase(first, last); }
+
+// multimap operations:
+
+ iterator find(const key_type& x) { return t.find(x); }
+ const_iterator find(const key_type& x) const { return t.find(x); }
+ size_type count(const key_type& x) const { return t.count(x); }
+ iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
+ const_iterator lower_bound(const key_type& x) const {
+ return t.lower_bound(x);
+ }
+ iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
+ const_iterator upper_bound(const key_type& x) const {
+ return t.upper_bound(x);
+ }
+ typedef pair<iterator, iterator> pair_iterator_iterator;
+ // typedef done to get around compiler bug
+ pair_iterator_iterator equal_range(const key_type& x) {
+ return t.equal_range(x);
+ }
+ typedef pair<const_iterator, const_iterator> pair_citerator_citerator;
+ // typedef done to get around compiler bug
+ pair_citerator_citerator equal_range(const key_type& x) const {
+ return t.equal_range(x);
+ }
+};
+
+template <class Key, class T, class Compare>
+inline bool operator==(const multimap<Key, T, Compare>& x,
+ const multimap<Key, T, Compare>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class T, class Compare>
+inline bool operator<(const multimap<Key, T, Compare>& x,
+ const multimap<Key, T, Compare>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#undef Allocator
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/multiset.h b/gnu/lib/libg++/libstdc++/stl/multiset.h
new file mode 100644
index 00000000000..1ee6d93e352
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/multiset.h
@@ -0,0 +1,129 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef MULTISET_H
+#define MULTISET_H
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#include <tree.h>
+
+template <class Key, class Compare>
+class multiset {
+public:
+// typedefs:
+
+ typedef Key key_type;
+ typedef Key value_type;
+ typedef Compare key_compare;
+ typedef Compare value_compare;
+private:
+ typedef rb_tree<key_type, value_type,
+ ident<value_type, key_type>, key_compare> rep_type;
+ rep_type t; // red-black tree representing multiset
+public:
+ typedef rep_type::const_reference reference;
+ typedef rep_type::const_reference const_reference;
+ typedef rep_type::const_iterator iterator;
+ typedef rep_type::const_iterator const_iterator;
+ typedef rep_type::const_reverse_iterator reverse_iterator;
+ typedef rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef rep_type::size_type size_type;
+ typedef rep_type::difference_type difference_type;
+
+// allocation/deallocation
+
+ multiset(const Compare& comp = Compare()) : t(comp, true) {}
+ multiset(const value_type* first, const value_type* last,
+ const Compare& comp = Compare()) : t(comp, true) {
+ for (const value_type* i = first; i != last; ++i)
+ t.insert(*i);
+ }
+ multiset(const multiset<Key, Compare>& x) : t(x.t, true) {}
+ multiset<Key, Compare>& operator=(const multiset<Key, Compare>& x) {
+ t = x.t;
+ return *this;
+ }
+
+// accessors:
+
+ key_compare key_comp() const { return t.key_comp(); }
+ value_compare value_comp() const { return t.key_comp(); }
+ iterator begin() const { return t.begin(); }
+ iterator end() const { return t.end(); }
+ reverse_iterator rbegin() const { return t.rbegin(); }
+ reverse_iterator rend() const { return t.rend(); }
+ bool empty() const { return t.empty(); }
+ size_type size() const { return t.size(); }
+ size_type max_size() const { return t.max_size(); }
+ void swap(multiset<Key, Compare>& x) { t.swap(x.t); }
+
+// insert/erase
+ iterator insert(const value_type& x) {
+ return t.insert(x).first;
+ }
+ iterator insert(iterator position, const value_type& x) {
+ return t.insert((rep_type::iterator&)position, x);
+ }
+ void insert(const value_type* first, const value_type* last) {
+ for (const value_type* i = first; i != last; ++i)
+ t.insert(*i);
+ }
+ void erase(iterator position) {
+ t.erase((rep_type::iterator&)position);
+ }
+ size_type erase(const key_type& x) {
+ return t.erase(x);
+ }
+ void erase(iterator first, iterator last) {
+ t.erase((rep_type::iterator&)first,
+ (rep_type::iterator&)last);
+ }
+
+// multiset operations:
+
+ iterator find(const key_type& x) const { return t.find(x); }
+ size_type count(const key_type& x) const { return t.count(x); }
+ iterator lower_bound(const key_type& x) const {
+ return t.lower_bound(x);
+ }
+ iterator upper_bound(const key_type& x) const {
+ return t.upper_bound(x);
+ }
+ typedef pair<iterator, iterator> pair_iterator_iterator;
+ // typedef done to get around compiler bug
+ pair_iterator_iterator equal_range(const key_type& x) const {
+ return t.equal_range(x);
+ }
+};
+
+template <class Key, class Compare>
+inline bool operator==(const multiset<Key, Compare>& x,
+ const multiset<Key, Compare>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Compare>
+inline bool operator<(const multiset<Key, Compare>& x,
+ const multiset<Key, Compare>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#undef Allocator
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/neralloc.h b/gnu/lib/libg++/libstdc++/stl/neralloc.h
new file mode 100644
index 00000000000..c66e9b366a0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/neralloc.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef NEARALLOC_H
+#define NEARALLOC_H
+
+#ifdef FARALLOC_H
+#undef FARALLOC_H
+#define __FARALLOC_WAS_DEFINED
+#endif
+
+#define __far __near
+#define far_allocator near_allocator
+#include <faralloc.h>
+#undef __far
+#undef far_allocator
+
+#undef FARALLOC_H
+
+#ifdef __FARALLOC_WAS_DEFINED
+#define FARALLOC_H
+#undef __FARALLOC_WAS_DEFINED
+#endif
+
+#endif
+
diff --git a/gnu/lib/libg++/libstdc++/stl/nmap.h b/gnu/lib/libg++/libstdc++/stl/nmap.h
new file mode 100644
index 00000000000..99754c78169
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/nmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef NMAP_H
+#define NMAP_H
+
+#ifdef MAP_H
+#undef MAP_H
+#undef TREE_H
+#define __MAP_WAS_DEFINED
+#endif
+
+#define Allocator near_allocator
+#define map near_map
+#define rb_tree near_rb_tree
+#include <neralloc.h>
+#include <map.h>
+
+#undef MAP_H
+#undef TREE_H
+
+#ifdef __MAP_WAS_DEFINED
+#define MAP_H
+#define TREE_H
+#undef __MAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef map
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/nmultmap.h b/gnu/lib/libg++/libstdc++/stl/nmultmap.h
new file mode 100644
index 00000000000..a6ad67c4fbb
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/nmultmap.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef NMULTIMAP_H
+#define NMULTIMAP_H
+
+#ifdef MULTIMAP_H
+#undef MULTIMAP_H
+#undef TREE_H
+#define __MULTIMAP_WAS_DEFINED
+#endif
+
+#define Allocator near_allocator
+#define multimap near_multimap
+#define rb_tree near_rb_tree
+#include <neralloc.h>
+#include <multimap.h>
+
+#undef MULTIMAP_H
+#undef TREE_H
+
+#ifdef __MULTIMAP_WAS_DEFINED
+#define MULTIMAP_H
+#define TREE_H
+#undef __MULTIMAP_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multimap
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/nmultset.h b/gnu/lib/libg++/libstdc++/stl/nmultset.h
new file mode 100644
index 00000000000..3a0ad30db0d
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/nmultset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef NMULTISET_H
+#define NMULTISET_H
+
+#ifdef MULTISET_H
+#undef MULTISET_H
+#undef TREE_H
+#define __MULTISET_WAS_DEFINED
+#endif
+
+#define Allocator near_allocator
+#define multiset near_multiset
+#define rb_tree near_rb_tree
+#include <neralloc.h>
+#include <multiset.h>
+
+#undef MULTISET_H
+#undef TREE_H
+
+#ifdef __MULTISET_WAS_DEFINED
+#define MULTISET_H
+#define TREE_H
+#undef __MULTISET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef multiset
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/nset.h b/gnu/lib/libg++/libstdc++/stl/nset.h
new file mode 100644
index 00000000000..325d6b94aac
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/nset.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef NSET_H
+#define NSET_H
+
+#ifdef SET_H
+#undef SET_H
+#undef TREE_H
+#define __SET_WAS_DEFINED
+#endif
+
+#define Allocator near_allocator
+#define set near_set
+#define rb_tree near_rb_tree
+#include <neralloc.h>
+#include <set.h>
+
+#undef SET_H
+#undef TREE_H
+
+#ifdef __SET_WAS_DEFINED
+#define SET_H
+#define TREE_H
+#undef __SET_WAS_DEFINED
+#endif
+
+#undef Allocator
+#undef set
+#undef rb_tree
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/pair.h b/gnu/lib/libg++/libstdc++/stl/pair.h
new file mode 100644
index 00000000000..817d9a43969
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/pair.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef PAIR_H
+#define PAIR_H
+
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+
+template <class T1, class T2>
+struct pair {
+ T1 first;
+ T2 second;
+ pair() {}
+ pair(const T1& a, const T2& b) : first(a), second(b) {}
+};
+
+template <class T1, class T2>
+inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) {
+ return x.first == y.first && x.second == y.second;
+}
+
+template <class T1, class T2>
+inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) {
+ return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
+}
+
+template <class T1, class T2>
+inline pair<T1, T2> make_pair(const T1& x, const T2& y) {
+ return pair<T1, T2>(x, y);
+}
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/projectn.h b/gnu/lib/libg++/libstdc++/stl/projectn.h
new file mode 100644
index 00000000000..766796e9f21
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/projectn.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef PROJECTN_H
+#define PROJECTN_H
+
+#include <function.h>
+
+template <class T, class U>
+struct select1st : public unary_function<T, U> {
+ const U& operator()(const T& x) const { return x.first; }
+};
+
+template <class T, class U>
+struct ident : public unary_function<T, U> {
+ const U& operator()(const T& x) const { return x; }
+};
+
+#endif
+
+
diff --git a/gnu/lib/libg++/libstdc++/stl/random.cc b/gnu/lib/libg++/libstdc++/stl/random.cc
new file mode 100644
index 00000000000..e79872ca49b
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/random.cc
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include <stddef.h>
+
+#define __SEED 161803398
+
+class __random_generator {
+protected:
+ unsigned long table[55];
+ size_t index1;
+ size_t index2;
+public:
+ unsigned long operator()(unsigned long limit) {
+ index1 = (index1 + 1) % 55;
+ index2 = (index2 + 1) % 55;
+ table[index1] = table[index1] - table[index2];
+ return table[index1] % limit;
+ }
+ void seed(unsigned long j);
+ __random_generator(unsigned long j) { seed(j); }
+};
+
+void __random_generator::seed(unsigned long j) {
+ unsigned long k = 1;
+ table[54] = j;
+ for (size_t i = 0; i < 54; i++) {
+ size_t ii = 21 * i % 55;
+ table[ii] = k;
+ k = j - k;
+ j = table[ii];
+ }
+ for (int loop = 0; loop < 4; loop++) {
+ for (size_t i = 0; i < 55; i++)
+ table[i] = table[i] - table[(1 + i + 30) % 55];
+ }
+ index1 = 0;
+ index2 = 31;
+}
+
+static __random_generator rd(__SEED);
+
+unsigned long __long_random(unsigned long limit) {
+ return rd(limit);
+}
+
+
+
diff --git a/gnu/lib/libg++/libstdc++/stl/set.h b/gnu/lib/libg++/libstdc++/stl/set.h
new file mode 100644
index 00000000000..d108e42371a
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/set.h
@@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef SET_H
+#define SET_H
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#include <tree.h>
+
+template <class Key, class Compare>
+class set {
+public:
+// typedefs:
+
+ typedef Key key_type;
+ typedef Key value_type;
+ typedef Compare key_compare;
+ typedef Compare value_compare;
+private:
+ typedef rb_tree<key_type, value_type,
+ ident<value_type, key_type>, key_compare> rep_type;
+ rep_type t; // red-black tree representing set
+public:
+ typedef rep_type::const_reference reference;
+ typedef rep_type::const_reference const_reference;
+ typedef rep_type::const_iterator iterator;
+ typedef rep_type::const_iterator const_iterator;
+ typedef rep_type::const_reverse_iterator reverse_iterator;
+ typedef rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef rep_type::size_type size_type;
+ typedef rep_type::difference_type difference_type;
+
+// allocation/deallocation
+
+ set(const Compare& comp = Compare()) : t(comp, false) {}
+ set(const value_type* first, const value_type* last,
+ const Compare& comp = Compare()) : t(comp, false) {
+ for (const value_type* i = first; i != last; ++i)
+ t.insert(*i);
+ }
+ set(const set<Key, Compare>& x) : t(x.t, false) {}
+ set<Key, Compare>& operator=(const set<Key, Compare>& x) {
+ t = x.t;
+ return *this;
+ }
+
+// accessors:
+
+ key_compare key_comp() const { return t.key_comp(); }
+ value_compare value_comp() const { return t.key_comp(); }
+ iterator begin() const { return t.begin(); }
+ iterator end() const { return t.end(); }
+ reverse_iterator rbegin() const { return t.rbegin(); }
+ reverse_iterator rend() const { return t.rend(); }
+ bool empty() const { return t.empty(); }
+ size_type size() const { return t.size(); }
+ size_type max_size() const { return t.max_size(); }
+ void swap(set<Key, Compare>& x) { t.swap(x.t); }
+
+// insert/erase
+ typedef pair<iterator, bool> pair_iterator_bool;
+ // typedef done to get around compiler bug
+ pair_iterator_bool insert(const value_type& x) {
+ pair<rep_type::iterator, bool> p = t.insert(x);
+ return pair<iterator, bool>(p.first, p.second);
+ }
+ iterator insert(iterator position, const value_type& x) {
+ return t.insert((rep_type::iterator&)position, x);
+ }
+ void insert(const value_type* first, const value_type* last) {
+ for (const value_type* i = first; i != last; ++i)
+ t.insert(*i);
+ }
+ void erase(iterator position) {
+ t.erase((rep_type::iterator&)position);
+ }
+ size_type erase(const key_type& x) {
+ return t.erase(x);
+ }
+ void erase(iterator first, iterator last) {
+ t.erase((rep_type::iterator&)first,
+ (rep_type::iterator&)last);
+ }
+
+// set operations:
+
+ iterator find(const key_type& x) const { return t.find(x); }
+ size_type count(const key_type& x) const { return t.count(x); }
+ iterator lower_bound(const key_type& x) const {
+ return t.lower_bound(x);
+ }
+ iterator upper_bound(const key_type& x) const {
+ return t.upper_bound(x);
+ }
+ typedef pair<iterator, iterator> pair_iterator_iterator;
+ // typedef done to get around compiler bug
+ pair_iterator_iterator equal_range(const key_type& x) const {
+ return t.equal_range(x);
+ }
+};
+
+template <class Key, class Compare>
+inline bool operator==(const set<Key, Compare>& x,
+ const set<Key, Compare>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Compare>
+inline bool operator<(const set<Key, Compare>& x,
+ const set<Key, Compare>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#undef Allocator
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/stack.h b/gnu/lib/libg++/libstdc++/stl/stack.h
new file mode 100644
index 00000000000..83a59a4c2af
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/stack.h
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef STACK_H
+#define STACK_H
+
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+#include <heap.h>
+
+template <class Container>
+class stack {
+friend bool operator==(const stack<Container>& x, const stack<Container>& y);
+friend bool operator<(const stack<Container>& x, const stack<Container>& y);
+public:
+ typedef Container::value_type value_type;
+ typedef Container::size_type size_type;
+protected:
+ Container c;
+public:
+ bool empty() const { return c.empty(); }
+ size_type size() const { return c.size(); }
+ value_type& top() { return c.back(); }
+ const value_type& top() const { return c.back(); }
+ void push(const value_type& x) { c.push_back(x); }
+ void pop() { c.pop_back(); }
+};
+
+template <class Container>
+bool operator==(const stack<Container>& x, const stack<Container>& y) {
+ return x.c == y.c;
+}
+
+template <class Container>
+bool operator<(const stack<Container>& x, const stack<Container>& y) {
+ return x.c < y.c;
+}
+
+template <class Container>
+class queue {
+friend bool operator==(const queue<Container>& x, const queue<Container>& y);
+friend bool operator<(const queue<Container>& x, const queue<Container>& y);
+public:
+ typedef Container::value_type value_type;
+ typedef Container::size_type size_type;
+protected:
+ Container c;
+public:
+ bool empty() const { return c.empty(); }
+ size_type size() const { return c.size(); }
+ value_type& front() { return c.front(); }
+ const value_type& front() const { return c.front(); }
+ value_type& back() { return c.back(); }
+ const value_type& back() const { return c.back(); }
+ void push(const value_type& x) { c.push_back(x); }
+ void pop() { c.pop_front(); }
+};
+
+template <class Container>
+bool operator==(const queue<Container>& x, const queue<Container>& y) {
+ return x.c == y.c;
+}
+
+template <class Container>
+bool operator<(const queue<Container>& x, const queue<Container>& y) {
+ return x.c < y.c;
+}
+
+template <class Container, class Compare>
+// Compare = less<Container::value_type> >
+class priority_queue {
+public:
+ typedef Container::value_type value_type;
+ typedef Container::size_type size_type;
+protected:
+ Container c;
+ Compare comp;
+public:
+ priority_queue(const Compare& x = Compare()) : c(), comp(x) {}
+ priority_queue(const value_type* first, const value_type* last,
+ const Compare& x = Compare()) : c(first, last), comp(x) {
+ make_heap(c.begin(), c.end(), comp);
+ }
+/*
+ template <class InputIterator>
+ priority_queue(InputIterator first, InputIterator last,
+ const Compare& x = Compare()) : c(first, last), comp(x) {
+ make_heap(c.begin(), c.end(), comp);
+ }
+*/
+ bool empty() const { return c.empty(); }
+ size_type size() const { return c.size(); }
+ value_type& top() { return c.front(); }
+ const value_type& top() const { return c.front(); }
+ void push(const value_type& x) {
+ c.push_back(x);
+ push_heap(c.begin(), c.end(), comp);
+ }
+ void pop() {
+ pop_heap(c.begin(), c.end(), comp);
+ c.pop_back();
+ }
+};
+
+// no equality is provided
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/tempbuf.cc b/gnu/lib/libg++/libstdc++/stl/tempbuf.cc
new file mode 100644
index 00000000000..2e7408eadd3
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/tempbuf.cc
@@ -0,0 +1,18 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#include <tempbuf.h>
+
+char __stl_temp_buffer[__stl_buffer_size];
diff --git a/gnu/lib/libg++/libstdc++/stl/tempbuf.h b/gnu/lib/libg++/libstdc++/stl/tempbuf.h
new file mode 100644
index 00000000000..238b6acc31b
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/tempbuf.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef TEMPBUF_H
+#define TEMPBUF_H
+
+#include <limits.h>
+#include <pair.h>
+
+#ifndef __stl_buffer_size
+#define __stl_buffer_size 16384 // 16k
+#endif
+
+extern char __stl_temp_buffer[__stl_buffer_size];
+
+//not reentrant code
+
+template <class T>
+pair<T*, int> get_temporary_buffer(int len, T*) {
+ while (len > __stl_buffer_size / sizeof(T)) {
+ set_new_handler(0);
+ T* tmp = (T*)(::operator new((unsigned int)len * sizeof(T)));
+ if (tmp) return pair<T*, int>(tmp, len);
+ len = len / 2;
+ }
+ return pair<T*, int>((T*)__stl_temp_buffer,
+ (int)(__stl_buffer_size / sizeof(T)));
+}
+
+template <class T>
+void return_temporary_buffer(T* p) {
+ if ((char*)(p) != __stl_temp_buffer) deallocate(p);
+}
+
+template <class T>
+pair<T*, long> get_temporary_buffer(long len, T* p) {
+ if (len > INT_MAX/sizeof(T))
+ len = INT_MAX/sizeof(T);
+ pair<T*, int> tmp = get_temporary_buffer((int)len, p);
+ return pair<T*, long>(tmp.first, (long)(tmp.second));
+}
+
+#endif
diff --git a/gnu/lib/libg++/libstdc++/stl/tree.cc b/gnu/lib/libg++/libstdc++/stl/tree.cc
new file mode 100644
index 00000000000..e4a9cfe10fa
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/tree.cc
@@ -0,0 +1,3 @@
+#include "tree.h"
+
+__rb_tree_node_base __rb_NIL = { black, 0, 0, 0 };
diff --git a/gnu/lib/libg++/libstdc++/stl/tree.h b/gnu/lib/libg++/libstdc++/stl/tree.h
new file mode 100644
index 00000000000..3ae5da02b08
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/tree.h
@@ -0,0 +1,1246 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef TREE_H
+#define TREE_H
+
+/*
+
+Red-black tree class, designed for use in implementing STL
+associative containers (set, multiset, map, and multimap). The
+insertion and deletion algorithms are based on those in Cormen,
+Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
+except that
+
+(1) the header cell is maintained with links not only to the root
+but also to the leftmost node of the tree, to enable constant time
+begin(), and to the rightmost node of the tree, to enable linear time
+performance when used with the generic set algorithms (set_union,
+etc.);
+
+(2) when a node being deleted has two children its successor node is
+relinked into its place, rather than copied, so that the only
+iterators invalidated are those referring to the deleted node.
+
+*/
+
+#include <algobase.h>
+#include <iterator.h>
+#include <function.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+#include <projectn.h>
+
+#ifndef rb_tree
+#define rb_tree rb_tree
+#endif
+
+enum __rb_color_type {red, black};
+
+struct __rb_tree_node_base {
+ enum __rb_color_type color_field;
+ void* parent_link;
+ void* left_link;
+ void* right_link;
+};
+
+extern __rb_tree_node_base __rb_NIL;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+class rb_tree {
+protected:
+ typedef enum __rb_color_type color_type;
+ typedef Allocator<void>::pointer void_pointer;
+ struct rb_tree_node;
+ friend rb_tree_node;
+ struct rb_tree_node : public __rb_tree_node_base {
+ Value value_field;
+ };
+#ifndef __GNUG__
+ static Allocator<rb_tree_node> rb_tree_node_allocator;
+ static Allocator<Value> value_allocator;
+#endif
+public:
+ typedef Key key_type;
+ typedef Value value_type;
+ typedef Allocator<Value>::pointer pointer;
+ typedef Allocator<Value>::reference reference;
+ typedef Allocator<Value>::const_reference const_reference;
+ typedef Allocator<rb_tree_node> rb_tree_node_allocator_type;
+ typedef Allocator<rb_tree_node>::pointer link_type;
+ typedef Allocator<rb_tree_node>::size_type size_type;
+ typedef Allocator<rb_tree_node>::difference_type difference_type;
+protected:
+#ifndef __GNUG__
+ size_type buffer_size() {
+ return rb_tree_node_allocator.init_page_size();
+ }
+#endif
+ struct rb_tree_node_buffer;
+ friend rb_tree_node_buffer;
+ struct rb_tree_node_buffer {
+ void_pointer next_buffer;
+ link_type buffer;
+ };
+public:
+ typedef Allocator<rb_tree_node_buffer> buffer_allocator_type;
+ typedef Allocator<rb_tree_node_buffer>::pointer buffer_pointer;
+protected:
+#ifdef __GNUG__
+ static Allocator<rb_tree_node_buffer> buffer_allocator;
+ static buffer_pointer buffer_list;
+ static link_type free_list;
+ static link_type next_avail;
+ static link_type last;
+ link_type get_node() { return (link_type) operator new (sizeof (rb_tree_node)); }
+ void put_node(link_type p) { operator delete (p); }
+#else
+ void add_new_buffer() {
+ buffer_pointer tmp = buffer_allocator.allocate((size_type)1);
+ tmp->buffer = rb_tree_node_allocator.allocate(buffer_size());
+ tmp->next_buffer = buffer_list;
+ buffer_list = tmp;
+ next_avail = buffer_list->buffer;
+ last = next_avail + buffer_size();
+ }
+ static size_type number_of_trees;
+ void deallocate_buffers();
+ link_type get_node() {
+ link_type tmp = free_list;
+ return free_list ?
+ (free_list = (link_type)(free_list->right_link), tmp)
+ : (next_avail == last ? (add_new_buffer(), next_avail++)
+ : next_avail++);
+ // ugly code for inlining - avoids multiple returns
+ }
+ void put_node(link_type p) {
+ p->right_link = free_list;
+ free_list = p;
+ }
+#endif
+protected:
+ link_type header;
+ link_type& root() { return parent(header); }
+ link_type& root() const { return parent(header); }
+ link_type& leftmost() { return left(header); }
+ link_type& leftmost() const { return left(header); }
+ link_type& rightmost() { return right(header); }
+ link_type& rightmost() const { return right(header); }
+ size_type node_count; // keeps track of size of tree
+ bool insert_always; // controls whether an element already in the
+ // tree is inserted again
+//public:
+ Compare key_compare;
+ static link_type& left(link_type x) {
+ return (link_type&)((*x).left_link);
+ }
+ static link_type& right(link_type x) {
+ return (link_type&)((*x).right_link);
+ }
+ static link_type& parent(link_type x) {
+ return (link_type&)((*x).parent_link);
+ }
+ static reference value(link_type x) { return (*x).value_field; }
+ static Allocator<Key>::const_reference key(link_type x) {
+ return KeyOfValue()(value(x));
+ }
+ static color_type& color(link_type x) {
+ return (color_type&)(*x).color_field; }
+ static link_type minimum(link_type x) {
+ while (left(x) != &__rb_NIL)
+ x = left(x);
+ return x;
+ }
+ static link_type maximum(link_type x) {
+ while (right(x) != &__rb_NIL)
+ x = right(x);
+ return x;
+ }
+public:
+ class iterator;
+ friend iterator;
+ class const_iterator;
+ friend const_iterator;
+ class iterator : public bidirectional_iterator<Value, difference_type> {
+ friend class rb_tree<Key, Value, KeyOfValue, Compare>;
+ friend class const_iterator;
+/*
+ friend bool operator==(const iterator& x, const iterator& y) {
+ return x.node == y.node;
+ }
+*/
+ protected:
+ link_type node;
+ iterator(link_type x) : node(x) {}
+ public:
+ iterator() {}
+ bool operator==(const iterator& y) const { return node == y.node; }
+ reference operator*() const { return value(node); }
+ iterator& operator++() {
+ if (right(node) != &__rb_NIL) {
+ node = right(node);
+ while (left(node) != &__rb_NIL)
+ node = left(node);
+ } else {
+ link_type y = parent(node);
+ while (node == right(y)) {
+ node = y;
+ y = parent(y);
+ }
+ if (right(node) != y) // necessary because of rightmost
+ node = y;
+ }
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ iterator& operator--() {
+ if (color(node) == red && parent(parent(node)) == node)
+ // check for header
+ node = right(node); // return rightmost
+ else if (left(node) != &__rb_NIL) {
+ link_type y = left(node);
+ while (right(y) != &__rb_NIL)
+ y = right(y);
+ node = y;
+ } else {
+ link_type y = parent(node);
+ while (node == left(y)) {
+ node = y;
+ y = parent(y);
+ }
+ node = y;
+ }
+ return *this;
+ }
+ iterator operator--(int) {
+ iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ };
+ class const_iterator
+ : public bidirectional_iterator<Value,difference_type> {
+ friend class rb_tree<Key, Value, KeyOfValue, Compare>;
+ friend class iterator;
+/*
+ friend bool operator==(const const_iterator& x, const const_iterator& y) {
+ return x.node == y.node;
+ }
+*/
+ protected:
+ link_type node;
+ const_iterator(link_type x) : node(x) {}
+ public:
+ const_iterator() {}
+ const_iterator(const iterator& x) : node(x.node) {}
+ bool operator==(const const_iterator& y) const {
+ return node == y.node;
+ }
+ bool operator!=(const const_iterator& y) const {
+ return node != y.node;
+ }
+ const_reference operator*() const { return value(node); }
+ const_iterator& operator++() {
+ if (right(node) != &__rb_NIL) {
+ node = right(node);
+ while (left(node) != &__rb_NIL)
+ node = left(node);
+ } else {
+ link_type y = parent(node);
+ while (node == right(y)) {
+ node = y;
+ y = parent(y);
+ }
+ if (right(node) != y) // necessary because of rightmost
+ node = y;
+ }
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ const_iterator& operator--() {
+ if (color(node) == red && parent(parent(node)) == node)
+ // check for header
+ node = right(node); // return rightmost
+ else if (left(node) != &__rb_NIL) {
+ link_type y = left(node);
+ while (right(y) != &__rb_NIL)
+ y = right(y);
+ node = y;
+ } else {
+ link_type y = parent(node);
+ while (node == left(y)) {
+ node = y;
+ y = parent(y);
+ }
+ node = y;
+ }
+ return *this;
+ }
+ const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ };
+ typedef reverse_bidirectional_iterator<iterator, value_type, reference,
+ difference_type>
+ reverse_iterator;
+ typedef reverse_bidirectional_iterator<const_iterator, value_type,
+ const_reference, difference_type>
+ const_reverse_iterator;
+private:
+#ifdef __GNUC__
+ rb_tree_iterator<Key, Value, KeyOfValue, Compare> __insert(void* x, void* y, const value_type& v);
+ link_type __copy(link_type x, link_type p) {
+ return (link_type) __copy_hack (x, p);
+ }
+private:
+ void * __copy_hack (void *, void *);
+public:
+ void __erase(void* x);
+#else
+ iterator __insert(link_type x, link_type y, const value_type& v);
+ link_type __copy(link_type x, link_type p);
+ void __erase(link_type x);
+#endif
+ void init() {
+#ifndef __GNUG__
+ ++number_of_trees;
+#endif
+ header = get_node();
+ color(header) = red; // used to distinguish header from root,
+ // in iterator.operator++
+ header->parent_link = &__rb_NIL;
+ leftmost() = header;
+ rightmost() = header;
+ }
+public:
+
+// allocation/deallocation
+
+ rb_tree(const Compare& comp = Compare(), bool always = true)
+ : node_count(0), insert_always(always), key_compare(comp) {
+ init();
+ }
+ rb_tree(const value_type* first, const value_type* last,
+ const Compare& comp = Compare(), bool always = true)
+ : node_count(0), insert_always(always), key_compare(comp) {
+ init();
+ insert(first, last);
+ }
+ rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare>& x,
+ bool always = true) : node_count(x.node_count),
+ insert_always(always), key_compare(x.key_compare) {
+#ifndef __GNUG__
+ ++number_of_trees;
+#endif
+ header = get_node();
+ color(header) = red;
+ root() = __copy(x.root(), header);
+ if (root() == &__rb_NIL) {
+ leftmost() = header;
+ rightmost() = header;
+ } else {
+ leftmost() = minimum(root());
+ rightmost() = maximum(root());
+ }
+ }
+ ~rb_tree() {
+ erase(begin(), end());
+ put_node(header);
+#ifndef __GNUG__
+ if (--number_of_trees == 0) {
+ deallocate_buffers();
+ free_list = 0;
+ next_avail = 0;
+ last = 0;
+ }
+#endif
+ }
+ rb_tree<Key, Value, KeyOfValue, Compare>&
+ operator=(const rb_tree<Key, Value, KeyOfValue, Compare>& x);
+
+// accessors:
+
+ Compare key_comp() const { return key_compare; }
+ iterator begin() { return leftmost(); }
+ const_iterator begin() const { return leftmost(); }
+ iterator end() { return header; }
+ const_iterator end() const { return header; }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+ bool empty() const { return node_count == 0; }
+ size_type size() const { return node_count; }
+#ifndef __GNUG__
+ size_type max_size() const {
+ return rb_tree_node_allocator.max_size();
+ }
+#else
+ size_type max_size() const {
+ return rb_tree_node_allocator_type::max_size();
+ }
+#endif
+ void swap(rb_tree<Key, Value, KeyOfValue, Compare>& t) {
+ ::swap(header, t.header);
+ ::swap(node_count, t.node_count);
+ ::swap(insert_always, t.insert_always);
+ ::swap(key_compare, t.key_compare);
+ }
+
+// insert/erase
+
+ typedef pair<iterator, bool> pair_iterator_bool;
+ // typedef done to get around compiler bug
+#ifdef __GNUG__
+ pair_iterator_bool insert(const value_type& x) {
+ return insert_hack(x);
+ }
+private:
+ rb_tree_pair_iterator_bool<Key, Value, KeyOfValue, Compare>
+ insert_hack(const Value& v);
+public:
+ iterator insert(iterator position, const value_type& x) {
+ return insert_hack(position, x);
+ }
+private:
+ rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+ insert_hack(rb_tree_iterator<Key, Value, KeyOfValue, Compare> posn,
+ const Value& v);
+public:
+ void insert(iterator first, iterator last) {
+ while (first != last) insert(*first++);
+ }
+ void insert(const value_type* first, const value_type* last){
+ while (first != last) insert(*first++);
+ }
+ void erase(iterator position) {
+ erase_hack(position);
+ }
+private:
+ void erase_hack(rb_tree_iterator<Key, Value, KeyOfValue, Compare> position);
+public:
+ size_type erase(const key_type& x);
+ void erase(iterator first, iterator last) {
+ while (first != last) erase(first++);
+ }
+#else
+ pair_iterator_bool insert(const value_type& x);
+ iterator insert(iterator position, const value_type& x);
+ void insert(iterator first, iterator last);
+ void insert(const value_type* first, const value_type* last);
+ void erase(iterator position);
+ size_type erase(const key_type& x);
+ void erase(iterator first, iterator last);
+#endif
+ void erase(const key_type* first, const key_type* last);
+
+// set operations:
+
+#ifdef __GNUG__
+ iterator find(const key_type& x) {
+ return find_hack(x);
+ }
+ const_iterator find(const key_type& x) const {
+ return find_hack(x);
+ }
+private:
+ rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+ find_hack(const key_type& x);
+ rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>
+ find_hack(const Key& k) const;
+public:
+
+ size_type count(const key_type& x) const;
+ iterator lower_bound(const key_type& x) {
+ return lower_bound_hack(x);
+ }
+ const_iterator lower_bound(const key_type& x) const {
+ return lower_bound_hack(x);
+ }
+ iterator upper_bound(const key_type& x) {
+ return upper_bound_hack(x);
+ }
+ const_iterator upper_bound(const key_type& x) const {
+ return upper_bound_hack(x);
+ }
+private:
+ rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+ lower_bound_hack(const key_type& x);
+ rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>
+ lower_bound_hack(const Key& k) const;
+ rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+ upper_bound_hack(const key_type& x);
+ rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>
+ upper_bound_hack(const Key& k) const;
+public:
+ typedef pair<iterator, iterator> pair_iterator_iterator;
+ // typedef done to get around compiler bug
+ pair_iterator_iterator equal_range(const key_type& x) {
+ return pair_iterator_iterator(lower_bound(x), upper_bound(x));
+ }
+ typedef pair<const_iterator, const_iterator> pair_citerator_citerator;
+
+ // typedef done to get around compiler bug
+ pair_citerator_citerator equal_range(const key_type& x) const {
+ return pair_citerator_citerator(lower_bound(x), upper_bound(x));
+ }
+ inline void rotate_left(link_type x) {
+ link_type y = right(x);
+ right(x) = left(y);
+ if (left(y) != &__rb_NIL)
+ parent(left(y)) = x;
+ parent(y) = parent(x);
+ if (x == root())
+ root() = y;
+ else if (x == left(parent(x)))
+ left(parent(x)) = y;
+ else
+ right(parent(x)) = y;
+ left(y) = x;
+ parent(x) = y;
+ }
+
+ inline void rotate_right(link_type x) {
+ link_type y = left(x);
+ left(x) = right(y);
+ if (right(y) != &__rb_NIL)
+ parent(right(y)) = x;
+ parent(y) = parent(x);
+ if (x == root())
+ root() = y;
+ else if (x == right(parent(x)))
+ right(parent(x)) = y;
+ else
+ left(parent(x)) = y;
+ right(y) = x;
+ parent(x) = y;
+ }
+ friend bidirectional_iterator_tag iterator_category(iterator) {
+ return bidirectional_iterator_tag();
+ }
+ friend bidirectional_iterator_tag iterator_category(const_iterator) {
+ return bidirectional_iterator_tag();
+ }
+#else
+ iterator find(const key_type& x);
+ const_iterator find(const key_type& x) const;
+ size_type count(const key_type& x) const;
+ iterator lower_bound(const key_type& x);
+ const_iterator lower_bound(const key_type& x) const;
+ iterator upper_bound(const key_type& x);
+ const_iterator upper_bound(const key_type& x) const;
+ typedef pair<iterator, iterator> pair_iterator_iterator;
+ // typedef done to get around compiler bug
+ pair_iterator_iterator equal_range(const key_type& x);
+ typedef pair<const_iterator, const_iterator> pair_citerator_citerator;
+ // typedef done to get around compiler bug
+ pair_citerator_citerator equal_range(const key_type& x) const;
+ inline void rotate_left(link_type x);
+ inline void rotate_right(link_type x);
+#endif
+};
+
+#ifndef __GNUG__
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::buffer_pointer
+ rb_tree<Key, Value, KeyOfValue, Compare>::buffer_list = 0;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::link_type
+ rb_tree<Key, Value, KeyOfValue, Compare>::free_list = 0;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::link_type
+ rb_tree<Key, Value, KeyOfValue, Compare>::next_avail = 0;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::link_type
+ rb_tree<Key, Value, KeyOfValue, Compare>::last = 0;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::size_type
+ rb_tree<Key, Value, KeyOfValue, Compare>::number_of_trees = 0;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::rb_tree_node_allocator_type
+ rb_tree<Key, Value, KeyOfValue, Compare>::rb_tree_node_allocator;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+Allocator<Value> rb_tree<Key, Value, KeyOfValue, Compare>::value_allocator;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::buffer_allocator_type
+ rb_tree<Key, Value, KeyOfValue, Compare>::buffer_allocator;
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+void rb_tree<Key, Value, KeyOfValue, Compare>::deallocate_buffers() {
+ while (buffer_list) {
+ buffer_pointer tmp = buffer_list;
+ buffer_list = (buffer_pointer)(buffer_list->next_buffer);
+ rb_tree_node_allocator.deallocate(tmp->buffer);
+ buffer_allocator.deallocate(tmp);
+ }
+}
+#endif
+
+#ifdef __GNUC__
+template <class Key, class Value, class KeyOfValue, class Compare>
+struct rb_tree_iterator {
+ rb_tree<Key, Value, KeyOfValue, Compare>::iterator it;
+ rb_tree_iterator(rb_tree<Key, Value, KeyOfValue, Compare>::iterator i) : it(i) {}
+ operator rb_tree<Key, Value, KeyOfValue, Compare>::iterator() {
+ return it;
+ }
+};
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline Value* value_type(const rb_tree_iterator<Key, Value, KeyOfValue, Compare>&) {
+ return (Value*)(0);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+struct rb_tree_const_iterator {
+ rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator it;
+ rb_tree_const_iterator(rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator i) : it(i) {}
+ operator rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator() {
+ return it;
+ }
+};
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline Value* value_type(const rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>&) {
+ return (Value*)(0);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+struct rb_tree_pair_iterator_bool {
+ rb_tree<Key, Value, KeyOfValue, Compare>::pair_iterator_bool it;
+ rb_tree_pair_iterator_bool(rb_tree<Key, Value, KeyOfValue, Compare>::pair_iterator_bool i) : it(i) {}
+ operator rb_tree<Key, Value, KeyOfValue, Compare>::pair_iterator_bool() {
+ return it;
+ }
+};
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline Value* value_type(rb_tree_pair_iterator_bool<Key, Value, KeyOfValue, Compare>&) {
+ return (Value*)(0);
+}
+#endif
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare>& x,
+ const rb_tree<Key, Value, KeyOfValue, Compare>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline bool operator<(const rb_tree<Key, Value, KeyOfValue, Compare>& x,
+ const rb_tree<Key, Value, KeyOfValue, Compare>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>&
+rb_tree<Key, Value, KeyOfValue, Compare>::
+operator=(const rb_tree<Key, Value, KeyOfValue, Compare>& x) {
+ if (this != &x) {
+ // can't be done as in list because Key may be a constant type
+ erase(begin(), end());
+ root() = __copy(x.root(), header);
+ if (root() == &__rb_NIL) {
+ leftmost() = header;
+ rightmost() = header;
+ } else {
+ leftmost() = minimum(root());
+ rightmost() = maximum(root());
+ }
+ node_count = x.node_count;
+ }
+ return *this;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::__insert
+(void* xa, void* ya, const Value& v) {
+ link_type x = (link_type)xa;
+ link_type y = (link_type)ya;
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::
+__insert(link_type x, link_type y, const Value& v) {
+#endif
+ ++node_count;
+ link_type z = get_node();
+#ifdef __GNUG__
+ construct(&(value(z)), v);
+#else
+ construct(value_allocator.address(value(z)), v);
+#endif
+ if (y == header || x != &__rb_NIL || key_compare(KeyOfValue()(v), key(y))) {
+ left(y) = z; // also makes leftmost() = z when y == header
+ if (y == header) {
+ root() = z;
+ rightmost() = z;
+ } else if (y == leftmost())
+ leftmost() = z; // maintain leftmost() pointing to minimum node
+ } else {
+ right(y) = z;
+ if (y == rightmost())
+ rightmost() = z; // maintain rightmost() pointing to maximum node
+ }
+ parent(z) = y;
+ z->left_link = &__rb_NIL;
+ z->right_link = &__rb_NIL;
+ x = z; // recolor and rebalance the tree
+ color(x) = red;
+ while (x != root() && color(parent(x)) == red)
+ if (parent(x) == left(parent(parent(x)))) {
+ y = right(parent(parent(x)));
+ if (color(y) == red) {
+ color(parent(x)) = black;
+ color(y) = black;
+ color(parent(parent(x))) = red;
+ x = parent(parent(x));
+ } else {
+ if (x == right(parent(x))) {
+ x = parent(x);
+ rotate_left(x);
+ }
+ color(parent(x)) = black;
+ color(parent(parent(x))) = red;
+ rotate_right(parent(parent(x)));
+ }
+ } else {
+ y = left(parent(parent(x)));
+ if (color(y) == red) {
+ color(parent(x)) = black;
+ color(y) = black;
+ color(parent(parent(x))) = red;
+ x = parent(parent(x));
+ } else {
+ if (x == left(parent(x))) {
+ x = parent(x);
+ rotate_right(x);
+ }
+ color(parent(x)) = black;
+ color(parent(parent(x))) = red;
+ rotate_left(parent(parent(x)));
+ }
+ }
+ color(root()) = black;
+ return iterator(z);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_pair_iterator_bool<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::insert_hack(const Value& v) {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::pair_iterator_bool
+rb_tree<Key, Value, KeyOfValue, Compare>::insert(const Value& v) {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = true;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(KeyOfValue()(v), key(x));
+ x = comp ? left(x) : right(x);
+ }
+ if (insert_always)
+ return pair_iterator_bool(__insert(x, y, v), true);
+ iterator j = iterator(y);
+ if (comp)
+ if (j == begin())
+ return pair_iterator_bool(__insert(x, y, v), true);
+ else
+ --j;
+ if (key_compare(key(j.node), KeyOfValue()(v)))
+ return pair_iterator_bool(__insert(x, y, v), true);
+ return pair_iterator_bool(j, false);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::insert_hack(rb_tree_iterator<Key, Value, KeyOfValue, Compare> posn,
+ const Value& v) {
+ iterator position = posn;
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::insert(iterator position,
+ const Value& v) {
+#endif
+ if (position == iterator(begin()))
+ if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
+ return __insert(position.node, position.node, v);
+ // first argument just needs to be non-&__rb_NIL
+ else
+ return insert(v).first;
+ else if (position == iterator(end()))
+ if (key_compare(key(rightmost()), KeyOfValue()(v)))
+ return __insert(&__rb_NIL, rightmost(), v);
+ else
+ return insert(v).first;
+ else {
+ iterator before = --position;
+ if (key_compare(key(before.node), KeyOfValue()(v))
+ && key_compare(KeyOfValue()(v), key(position.node)))
+ if (right(before.node) == &__rb_NIL)
+ return __insert(&__rb_NIL, before.node, v);
+ else
+ return __insert(position.node, position.node, v);
+ // first argument just needs to be non-&__rb_NIL
+ else
+ return insert(v).first;
+ }
+}
+
+#ifndef __GNUC__
+template <class Key, class Value, class KeyOfValue, class Compare>
+void rb_tree<Key, Value, KeyOfValue, Compare>::insert(iterator first,
+ iterator last) {
+ while (first != last) insert(*first++);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+void rb_tree<Key, Value, KeyOfValue, Compare>::insert(const Value* first,
+ const Value* last) {
+ while (first != last) insert(*first++);
+}
+#endif
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+void rb_tree<Key, Value, KeyOfValue, Compare>::erase_hack(
+ rb_tree_iterator<Key, Value, KeyOfValue, Compare> posn) {
+ iterator position = posn;
+#else
+void rb_tree<Key, Value, KeyOfValue, Compare>::erase(iterator position) {
+#endif
+ link_type z = position.node;
+ link_type y = z;
+ link_type x;
+ if (left(y) == &__rb_NIL)
+ x = right(y);
+ else
+ if (right(y) == &__rb_NIL)
+ x = left(y);
+ else {
+ y = right(y);
+ while (left(y) != &__rb_NIL)
+ y = left(y);
+ x = right(y);
+ }
+ if (y != z) { // relink y in place of z
+ parent(left(z)) = y;
+ left(y) = left(z);
+ if (y != right(z)) {
+ parent(x) = parent(y); // possibly x == &__rb_NIL
+ left(parent(y)) = x; // y must be a left child
+ right(y) = right(z);
+ parent(right(z)) = y;
+ } else
+ parent(x) = y; // needed in case x == &__rb_NIL
+ if (root() == z)
+ root() = y;
+ else if (left(parent(z)) == z)
+ left(parent(z)) = y;
+ else
+ right(parent(z)) = y;
+ parent(y) = parent(z);
+ ::swap(color(y), color(z));
+ ::swap(y, z);
+ // y points to node to be actually deleted,
+ // z points to old z's former successor
+ } else { // y == z
+ parent(x) = parent(y); // possibly x == &__rb_NIL
+ if (root() == z)
+ root() = x;
+ else
+ if (left(parent(z)) == z)
+ left(parent(z)) = x;
+ else
+ right(parent(z)) = x;
+ if (leftmost() == z)
+ if (right(z) == &__rb_NIL) // left(z) must be &__rb_NIL also
+ leftmost() = parent(z);
+ // makes leftmost() == header if z == root()
+ else
+ leftmost() = minimum(x);
+ if (rightmost() == z)
+ if (left(z) == &__rb_NIL) // right(z) must be &__rb_NIL also
+ rightmost() = parent(z);
+ // makes rightmost() == header if z == root()
+ else // x == left(z)
+ rightmost() = maximum(x);
+ }
+ if (color(y) != red) {
+ while (x != root() && color(x) == black)
+ if (x == left(parent(x))) {
+ link_type w = right(parent(x));
+ if (color(w) == red) {
+ color(w) = black;
+ color(parent(x)) = red;
+ rotate_left(parent(x));
+ w = right(parent(x));
+ }
+ if (color(left(w)) == black && color(right(w)) == black) {
+ color(w) = red;
+ x = parent(x);
+ } else {
+ if (color(right(w)) == black) {
+ color(left(w)) = black;
+ color(w) = red;
+ rotate_right(w);
+ w = right(parent(x));
+ }
+ color(w) = color(parent(x));
+ color(parent(x)) = black;
+ color(right(w)) = black;
+ rotate_left(parent(x));
+ break;
+ }
+ } else { // same as then clause with "right" and "left" exchanged
+ link_type w = left(parent(x));
+ if (color(w) == red) {
+ color(w) = black;
+ color(parent(x)) = red;
+ rotate_right(parent(x));
+ w = left(parent(x));
+ }
+ if (color(right(w)) == black && color(left(w)) == black) {
+ color(w) = red;
+ x = parent(x);
+ } else {
+ if (color(left(w)) == black) {
+ color(right(w)) = black;
+ color(w) = red;
+ rotate_left(w);
+ w = left(parent(x));
+ }
+ color(w) = color(parent(x));
+ color(parent(x)) = black;
+ color(left(w)) = black;
+ rotate_right(parent(x));
+ break;
+ }
+ }
+ color(x) = black;
+ }
+#ifdef __GNUG__
+ delete y;
+#else
+ destroy(value_allocator.address(value(y)));
+ put_node(y);
+#endif
+ --node_count;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ long unsigned int
+#endif
+__SIZE_TYPE__
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::size_type
+#endif
+rb_tree<Key, Value, KeyOfValue, Compare>::erase(const Key& x) {
+ pair_iterator_iterator p = equal_range(x);
+ size_type n = 0;
+ distance(p.first, p.second, n);
+ erase(p.first, p.second);
+ return n;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUG__
+void *
+rb_tree<Key, Value, KeyOfValue, Compare>::__copy_hack(void* xa, void* pa) {
+ link_type x = (link_type)xa;
+ link_type p = (link_type)pa;
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::link_type
+rb_tree<Key, Value, KeyOfValue, Compare>::__copy(link_type x, link_type p) {
+#endif
+ // structural copy
+ link_type r = x;
+ while (x != &__rb_NIL) {
+ link_type y = get_node();
+ if (r == x) r = y; // save for return value
+#ifdef __GNUG__
+ construct(&(value(y)), value(x));
+#else
+ construct(value_allocator.address(value(y)), value(x));
+#endif
+ left(p) = y;
+ parent(y) = p;
+ color(y) = color(x);
+ right(y) = __copy(right(x), y);
+ p = y;
+ x = left(x);
+ }
+ left(p) = (link_type)&__rb_NIL;
+ return r;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUG__
+void rb_tree<Key, Value, KeyOfValue, Compare>::__erase(void* xa) {
+ link_type x = (link_type)xa;
+#else
+void rb_tree<Key, Value, KeyOfValue, Compare>::__erase(link_type x) {
+#endif
+ // erase without rebalancing
+ while (x != &__rb_NIL) {
+ __erase(right(x));
+ link_type y = left(x);
+#ifdef __GNUG__
+ delete x;
+#else
+ destroy(value_allocator.address(value(x)));
+ put_node(x);
+#endif
+ x = y;
+ }
+}
+
+#ifndef __GNUC__
+template <class Key, class Value, class KeyOfValue, class Compare>
+void rb_tree<Key, Value, KeyOfValue, Compare>::erase(iterator first,
+ iterator last) {
+ if (first == begin() && last == end() && node_count != 0) {
+ __erase(root());
+ leftmost() = header;
+ root() = NIL;
+ rightmost() = header;
+ node_count = 0;
+ } else
+ while (first != last) erase(first++);
+}
+#endif
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+void rb_tree<Key, Value, KeyOfValue, Compare>::erase(const Key* first,
+ const Key* last) {
+ while (first != last) erase(*first++);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::find_hack(const Key& k) {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::find(const Key& k) {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = false;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(key(x), k);
+ x = comp ? right(x) : left(x);
+ }
+ iterator j = iterator(y);
+ if (comp) ++j;
+ return (j == end() || key_compare(k, key(j.node))) ? end() : j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::find_hack(const Key& k) const {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::find(const Key& k) const {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = false;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(key(x), k);
+ x = comp ? right(x) : left(x);
+ }
+ const_iterator j = const_iterator(y);
+ if (comp) ++j;
+ return (j == end() || key_compare(k, key(j.node))) ? end() : j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUG__
+__SIZE_TYPE__
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::size_type
+#endif
+rb_tree<Key, Value, KeyOfValue, Compare>::count(const Key& k) const {
+ pair<const_iterator, const_iterator> p = equal_range(k);
+ size_type n = 0;
+ distance(p.first, p.second, n);
+ return n;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::lower_bound_hack(const Key& k) {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::lower_bound(const Key& k) {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = false;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(key(x), k);
+ x = comp ? right(x) : left(x);
+ }
+ iterator j = iterator(y);
+ return comp ? ++j : j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::lower_bound_hack(const Key& k) const {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::lower_bound(const Key& k) const {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = false;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(key(x), k);
+ x = comp ? right(x) : left(x);
+ }
+ const_iterator j = const_iterator(y);
+ return comp ? ++j : j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::upper_bound_hack(const Key& k) {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::upper_bound(const Key& k) {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = true;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(k, key(x));
+ x = comp ? left(x) : right(x);
+ }
+ iterator j = iterator(y);
+ return comp ? j : ++j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+#ifdef __GNUC__
+rb_tree_const_iterator<Key, Value, KeyOfValue, Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::upper_bound_hack(const Key& k) const {
+#else
+rb_tree<Key, Value, KeyOfValue, Compare>::const_iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::upper_bound(const Key& k) const {
+#endif
+ link_type y = header;
+ link_type x = root();
+ bool comp = true;
+ while (x != &__rb_NIL) {
+ y = x;
+ comp = key_compare(k, key(x));
+ x = comp ? left(x) : right(x);
+ }
+ const_iterator j = const_iterator(y);
+ return comp ? j : ++j;
+}
+
+
+#ifndef __GNUC__
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::pair_iterator_iterator
+rb_tree<Key, Value, KeyOfValue, Compare>::equal_range(const Key& k) {
+ return pair_iterator_iterator(lower_bound(k), upper_bound(k));
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+rb_tree<Key, Value, KeyOfValue, Compare>::pair_citerator_citerator
+rb_tree<Key, Value, KeyOfValue, Compare>::equal_range(const Key& k) const {
+ return pair_citerator_citerator(lower_bound(k), upper_bound(k));
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline void
+rb_tree<Key, Value, KeyOfValue, Compare>::rotate_left(link_type x) {
+ link_type y = right(x);
+ right(x) = left(y);
+ if (left(y) != &__rb_NIL)
+ parent(left(y)) = x;
+ parent(y) = parent(x);
+ if (x == root())
+ root() = y;
+ else if (x == left(parent(x)))
+ left(parent(x)) = y;
+ else
+ right(parent(x)) = y;
+ left(y) = x;
+ parent(x) = y;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare>
+inline void
+rb_tree<Key, Value, KeyOfValue, Compare>::rotate_right(link_type x) {
+ link_type y = left(x);
+ left(x) = right(y);
+ if (right(y) != &__rb_NIL)
+ parent(right(y)) = x;
+ parent(y) = parent(x);
+ if (x == root())
+ root() = y;
+ else if (x == right(parent(x)))
+ right(parent(x)) = y;
+ else
+ left(parent(x)) = y;
+ right(y) = x;
+ parent(x) = y;
+}
+#endif
+
+#endif
+
diff --git a/gnu/lib/libg++/libstdc++/stl/vector.h b/gnu/lib/libg++/libstdc++/stl/vector.h
new file mode 100644
index 00000000000..e609aa109a0
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/stl/vector.h
@@ -0,0 +1,355 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <function.h>
+#include <algobase.h>
+#ifndef __GNUG__
+#include <bool.h>
+#endif
+
+#ifndef Allocator
+#define Allocator allocator
+#include <defalloc.h>
+#endif
+
+#ifndef vector
+#define vector vector
+#endif
+
+template <class T>
+class vector {
+public:
+
+ typedef Allocator<T> vector_allocator;
+ typedef T value_type;
+ typedef vector_allocator::pointer pointer;
+ typedef vector_allocator::pointer iterator;
+ typedef vector_allocator::const_pointer const_iterator;
+ typedef vector_allocator::reference reference;
+ typedef vector_allocator::const_reference const_reference;
+ typedef vector_allocator::size_type size_type;
+ typedef vector_allocator::difference_type difference_type;
+ typedef reverse_iterator<const_iterator, value_type, const_reference,
+ difference_type> const_reverse_iterator;
+ typedef reverse_iterator<iterator, value_type, reference, difference_type>
+ reverse_iterator;
+protected:
+ static Allocator<T> static_allocator;
+ iterator start;
+ iterator finish;
+ iterator end_of_storage;
+#ifdef __GNUG__
+ void insert_aux(iterator position, const T& x) {
+ insert_aux(vector_iterator<T>(position), x);
+ }
+ void insert_aux(vector_iterator<T> position, const T& x);
+#else
+ void insert_aux(iterator position, const T& x);
+#endif
+public:
+ iterator begin() { return start; }
+ const_iterator begin() const { return start; }
+ iterator end() { return finish; }
+ const_iterator end() const { return finish; }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+ size_type size() const { return size_type(end() - begin()); }
+ size_type max_size() const { return static_allocator.max_size(); }
+ size_type capacity() const { return size_type(end_of_storage - begin()); }
+ bool empty() const { return begin() == end(); }
+ reference operator[](size_type n) { return *(begin() + n); }
+ const_reference operator[](size_type n) const { return *(begin() + n); }
+ vector() : start(0), finish(0), end_of_storage(0) {}
+ vector(size_type n, const T& value = T()) {
+ start = static_allocator.allocate(n);
+ uninitialized_fill_n(start, n, value);
+ finish = start + n;
+ end_of_storage = finish;
+ }
+ vector(const vector<T>& x) {
+ start = static_allocator.allocate(x.end() - x.begin());
+ finish = uninitialized_copy(x.begin(), x.end(), start);
+ end_of_storage = finish;
+ }
+ vector(const_iterator first, const_iterator last) {
+ size_type n = 0;
+ distance(first, last, n);
+ start = static_allocator.allocate(n);
+ finish = uninitialized_copy(first, last, start);
+ end_of_storage = finish;
+ }
+ ~vector() {
+ destroy(start, finish);
+ static_allocator.deallocate(start);
+ }
+ vector<T>& operator=(const vector<T>& x);
+ void reserve(size_type n) {
+ if (capacity() < n) {
+ iterator tmp = static_allocator.allocate(n);
+ uninitialized_copy(begin(), end(), tmp);
+ destroy(start, finish);
+ static_allocator.deallocate(start);
+ finish = tmp + size();
+ start = tmp;
+ end_of_storage = begin() + n;
+ }
+ }
+ reference front() { return *begin(); }
+ const_reference front() const { return *begin(); }
+ reference back() { return *(end() - 1); }
+ const_reference back() const { return *(end() - 1); }
+ void push_back(const T& x) {
+ if (finish != end_of_storage) {
+ /* Borland bug */
+ construct(finish, x);
+ finish++;
+ } else
+ insert_aux(end(), x);
+ }
+ void swap(vector<T>& x) {
+ ::swap(start, x.start);
+ ::swap(finish, x.finish);
+ ::swap(end_of_storage, x.end_of_storage);
+ }
+ iterator insert(iterator position, const T& x) {
+ size_type n = position - begin();
+ if (finish != end_of_storage && position == end()) {
+ /* Borland bug */
+ construct(finish, x);
+ finish++;
+ } else
+ insert_aux(position, x);
+ return begin() + n;
+ }
+#ifdef __GNUG__
+ void insert (iterator position, const_iterator first,
+ const_iterator last) {
+ insert(vector_iterator<T>(position),
+ vector_const_iterator<T>(first),
+ vector_const_iterator<T>(last));
+ }
+ void insert (vector_iterator<T> position, vector_const_iterator<T> first,
+ vector_const_iterator<T> last);
+ void insert (iterator position, size_type n, const T& x) {
+ insert(vector_iterator<T>(position), n, x);
+ }
+ void insert (vector_iterator<T> position, size_type n, const T& x);
+#else
+ void insert (iterator position, const_iterator first,
+ const_iterator last);
+ void insert (iterator position, size_type n, const T& x);
+#endif
+ void pop_back() {
+ /* Borland bug */
+ --finish;
+ destroy(finish);
+ }
+ void erase(iterator position) {
+ if (position + 1 != end())
+ copy(position + 1, end(), position);
+ /* Borland bug */
+ --finish;
+ destroy(finish);
+ }
+ void erase(iterator first, iterator last) {
+ vector<T>::iterator i = copy(last, end(), first);
+ destroy(i, finish);
+ // work around for destroy(copy(last, end(), first), finish);
+ finish = finish - (last - first);
+ }
+};
+
+#ifdef __GNUG__
+template <class T>
+struct vector_iterator {
+ vector<T>::iterator it;
+ vector_iterator(vector<T>::iterator i) : it(i) {}
+ operator vector<T>::iterator() {
+ return it;
+ }
+};
+
+template <class T>
+inline T* value_type(const vector_iterator<T>&) {
+ return (T*)(0);
+}
+
+
+template <class T>
+struct vector_const_iterator {
+ vector<T>::const_iterator it;
+ vector_const_iterator(vector<T>::const_iterator i) : it(i) {}
+ operator vector<T>::const_iterator() {
+ return it;
+ }
+};
+#endif
+
+template <class T>
+inline bool operator==(const vector<T>& x, const vector<T>& y) {
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T>
+inline bool operator<(const vector<T>& x, const vector<T>& y) {
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#ifndef __GNUG__
+template <class T>
+vector<T>::vector_allocator vector<T>::static_allocator;
+#endif
+
+template <class T>
+vector<T>& vector<T>::operator=(const vector<T>& x) {
+ if (&x == this) return *this;
+ if (x.size() > capacity()) {
+ destroy(start, finish);
+ static_allocator.deallocate(start);
+ start = static_allocator.allocate(x.end() - x.begin());
+ end_of_storage = uninitialized_copy(x.begin(), x.end(), start);
+ } else if (size() >= x.size()) {
+ vector<T>::iterator i = copy(x.begin(), x.end(), begin());
+ destroy(i, finish);
+ // work around for destroy(copy(x.begin(), x.end(), begin()), finish);
+ } else {
+ copy(x.begin(), x.begin() + size(), begin());
+ uninitialized_copy(x.begin() + size(), x.end(), begin() + size());
+ }
+ finish = begin() + x.size();
+ return *this;
+}
+
+template <class T>
+#ifdef __GNUG__
+void vector<T>::insert_aux(vector_iterator<T> posn, const T& x) {
+ iterator position = posn;
+#else
+void vector<T>::insert_aux(iterator position, const T& x) {
+#endif
+ if (finish != end_of_storage) {
+ construct(finish, *(finish - 1));
+ copy_backward(position, finish - 1, finish);
+ *position = x;
+ ++finish;
+ } else {
+ size_type len = size() ? 2 * size()
+ : static_allocator.init_page_size();
+ iterator tmp = static_allocator.allocate(len);
+ uninitialized_copy(begin(), position, tmp);
+ construct(tmp + (position - begin()), x);
+ uninitialized_copy(position, end(), tmp + (position - begin()) + 1);
+ destroy(begin(), end());
+ static_allocator.deallocate(begin());
+ end_of_storage = tmp + len;
+ finish = tmp + size() + 1;
+ start = tmp;
+ }
+}
+
+template <class T>
+#ifdef __GNUG__
+void vector<T>::insert(vector_iterator<T> posn,
+ size_t n,
+ const T& x) {
+ iterator position = posn;
+#else
+void vector<T>::insert(iterator position, size_type n, const T& x) {
+#endif
+ if (n == 0) return;
+ if ((size_type) (end_of_storage - finish) >= n) {
+ if ((size_type) (end() - position) > n) {
+ uninitialized_copy(end() - n, end(), end());
+ copy_backward(position, end() - n, end());
+ fill(position, position + n, x);
+ } else {
+ uninitialized_copy(position, end(), position + n);
+ fill(position, end(), x);
+ uninitialized_fill_n(end(), n - (end() - position), x);
+ }
+ finish += n;
+ } else {
+ size_type len = size() + max(size(), n);
+ iterator tmp = static_allocator.allocate(len);
+ uninitialized_copy(begin(), position, tmp);
+ uninitialized_fill_n(tmp + (position - begin()), n, x);
+ uninitialized_copy(position, end(), tmp + (position - begin() + n));
+ destroy(begin(), end());
+ static_allocator.deallocate(begin());
+ end_of_storage = tmp + len;
+ finish = tmp + size() + n;
+ start = tmp;
+ }
+}
+
+template <class T>
+#ifdef __GNUG__
+void vector<T>::insert(vector_iterator<T> posn,
+ vector_const_iterator<T> fi,
+ vector_const_iterator<T> la) {
+ iterator position = posn;
+ const_iterator first = fi;
+ const_iterator last = la;
+#else
+void vector<T>::insert(iterator position,
+ const_iterator first,
+ const_iterator last) {
+#endif
+ if (first == last) return;
+ size_type n = 0;
+ distance(first, last, n);
+ if ((size_type) (end_of_storage - finish) >= n) {
+ if ((size_type) (end() - position) > n) {
+ uninitialized_copy(end() - n, end(), end());
+ copy_backward(position, end() - n, end());
+ copy(first, last, position);
+ } else {
+ uninitialized_copy(position, end(), position + n);
+ copy(first, first + (end() - position), position);
+ uninitialized_copy(first + (end() - position), last, end());
+ }
+ finish += n;
+ } else {
+ size_type len = size() + max(size(), n);
+ iterator tmp = static_allocator.allocate(len);
+ uninitialized_copy(begin(), position, tmp);
+ uninitialized_copy(first, last, tmp + (position - begin()));
+ uninitialized_copy(position, end(), tmp + (position - begin() + n));
+ destroy(begin(), end());
+ static_allocator.deallocate(begin());
+ end_of_storage = tmp + len;
+ finish = tmp + size() + n;
+ start = tmp;
+ }
+}
+
+#undef Allocator
+#undef vector
+
+#endif
+
+
+
+
+
diff --git a/gnu/lib/libg++/libstdc++/string b/gnu/lib/libg++/libstdc++/string
new file mode 100644
index 00000000000..467a2fd0a69
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/string
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __STRING__
+#include <std/string.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/typeinfo b/gnu/lib/libg++/libstdc++/typeinfo
new file mode 100644
index 00000000000..93524ed1862
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/typeinfo
@@ -0,0 +1,6 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __TYPEINFO__
+#include <std/typeinfo.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/typeinfoi.cc b/gnu/lib/libg++/libstdc++/typeinfoi.cc
new file mode 100644
index 00000000000..01274e009f4
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/typeinfoi.cc
@@ -0,0 +1,129 @@
+// Methods for type_info for the -*- C++ -*- Run Time Type Identification.
+// Copyright (C) 1994 Free Software Foundation
+
+// This file is part of the GNU ANSI C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// As a special exception, if you link this library with files
+// compiled with a GNU compiler to produce an executable, this does not cause
+// the resulting executable to be covered by the GNU General Public License.
+// This exception does not however invalidate any other reasons why
+// the executable file might be covered by the GNU General Public License.
+
+// Written by Kung Hsu based upon the specification in the 20 September 1994
+// C++ working paper, ANSI document X3J16/94-0158.
+
+#ifdef __GNUG__
+#pragma implementation "std/typeinfo.h"
+#endif
+
+#include <std/cstdlib.h>
+#include <std/typeinfo.h>
+
+// Offset functions for the class type.
+
+// 0 is returned if the cast is invalid, otherwise the converted
+// object pointer that points to the sub-object that is matched is
+// returned.
+
+void* __class_type_info::__rtti_match(const type_info& desired, int is_public,
+ void *objptr) const
+{
+ if (__rtti_compare(desired) == 0)
+ return objptr;
+
+ void *match_found = 0;
+ for (int i = 0; i < n_bases; i++) {
+ if (is_public && access_list[i] != _RTTI_ACCESS_PUBLIC)
+ continue;
+ void *p = (char *)objptr + offset_list[i];
+ if (is_virtual_list[i])
+ p = *(void **)p;
+
+ if ((p=base_list[i]->__rtti_match(desired, is_public, p))
+ != 0)
+ if (match_found == 0)
+ match_found = p;
+ else if (match_found != p) {
+ // base found at two different pointers,
+ // conversion is not unique
+ return 0;
+ }
+ }
+
+ return match_found;
+}
+
+void* __pointer_type_info::__rtti_match(const type_info& catch_type, int,
+ void *objptr) const
+{
+ if (catch_type.__rtti_get_node_type () == __rtti_get_node_type())
+ {
+ type_info &sub_catch_type = ((__pointer_type_info&)catch_type).type;
+ type_info &sub_throw_type = ((__pointer_type_info*)this)->type;
+ if (sub_catch_type.__rtti_get_node_type () == _RTTI_BUILTIN_TYPE
+ && ((__builtin_type_info&)sub_catch_type).b_type == __builtin_type_info::_RTTI_BI_VOID)
+ {
+ return objptr;
+ }
+ if (sub_catch_type.__rtti_get_node_type () == _RTTI_ATTR_TYPE
+ && ((__attr_type_info&)sub_catch_type).attr == __attr_type_info::_RTTI_ATTR_CONST)
+ {
+ /* We have to allow a catch of const int* on a int * throw. */
+ type_info &sub_sub_catch_type = ((__attr_type_info&)sub_catch_type).type;
+ return __throw_type_match_rtti (&sub_sub_catch_type, &sub_throw_type, objptr);
+ }
+ return __throw_type_match_rtti (&sub_catch_type, &sub_throw_type, objptr);
+ }
+ return 0;
+}
+
+/* Low level match routine used by compiler to match types of catch variables and thrown
+ objects. */
+extern "C"
+void*
+__throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void *objptr)
+{
+ type_info &catch_type = *(type_info*)catch_type_r;
+ type_info &throw_type = *(type_info*)throw_type_r;
+ void *new_objptr;
+
+ if (catch_type == throw_type)
+ return objptr;
+
+ /* Ensure we can call __rtti_match. */
+ if ((throw_type.__rtti_get_node_type () != type_info::_RTTI_CLASS_TYPE
+ && throw_type.__rtti_get_node_type () != type_info::_RTTI_USER_TYPE
+ && throw_type.__rtti_get_node_type () != type_info::_RTTI_POINTER_TYPE)
+ || ((catch_type.__rtti_get_node_type () != type_info::_RTTI_CLASS_TYPE
+ && catch_type.__rtti_get_node_type () != type_info::_RTTI_USER_TYPE
+ && catch_type.__rtti_get_node_type () != type_info::_RTTI_POINTER_TYPE)))
+ return 0;
+
+#if 0
+ printf("We want to match a %s against a %s!\n",
+ throw_type.name(), catch_type.name());
+#endif
+
+ /* The 1 skips conversions to private bases. */
+ new_objptr = throw_type.__rtti_match (catch_type, 1, objptr);
+#if 0
+ if (new_objptr)
+ printf("It converts, delta is %d\n", new_objptr-objptr);
+#endif
+ return new_objptr;
+}
+
+bad_cast __bad_cast_object ("bad_cast");
diff --git a/gnu/lib/libg++/libstdc++/utility b/gnu/lib/libg++/libstdc++/utility
new file mode 100644
index 00000000000..fb79aa78274
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/utility
@@ -0,0 +1,8 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __UTILITY__
+#define __UTILITY__
+#include <function.h>
+#include <pair.h>
+#endif
diff --git a/gnu/lib/libg++/libstdc++/vector b/gnu/lib/libg++/libstdc++/vector
new file mode 100644
index 00000000000..79f73593751
--- /dev/null
+++ b/gnu/lib/libg++/libstdc++/vector
@@ -0,0 +1,7 @@
+// -*- C++ -*- forwarding header.
+// This file is part of the GNU ANSI C++ Library.
+
+#ifndef __VECTOR__
+#define __VECTOR__
+#include <vector.h>
+#endif