summaryrefslogtreecommitdiff
path: root/gnu/lib/libg++
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /gnu/lib/libg++
initial import of NetBSD tree
Diffstat (limited to 'gnu/lib/libg++')
-rw-r--r--gnu/lib/libg++/COPYING249
-rw-r--r--gnu/lib/libg++/Makefile27
-rw-r--r--gnu/lib/libg++/VERSION3
-rw-r--r--gnu/lib/libg++/g++-include/ACG.cc291
-rw-r--r--gnu/lib/libg++/g++-include/ACG.h71
-rw-r--r--gnu/lib/libg++/g++-include/AllocRing.cc110
-rw-r--r--gnu/lib/libg++/g++-include/AllocRing.h63
-rw-r--r--gnu/lib/libg++/g++-include/Binomial.cc34
-rw-r--r--gnu/lib/libg++/g++-include/Binomial.h58
-rw-r--r--gnu/lib/libg++/g++-include/BitSet.cc1000
-rw-r--r--gnu/lib/libg++/g++-include/BitSet.h363
-rw-r--r--gnu/lib/libg++/g++-include/BitString.cc2080
-rw-r--r--gnu/lib/libg++/g++-include/BitString.h759
-rw-r--r--gnu/lib/libg++/g++-include/Complex.cc262
-rw-r--r--gnu/lib/libg++/g++-include/Complex.h272
-rw-r--r--gnu/lib/libg++/g++-include/CursesW.cc255
-rw-r--r--gnu/lib/libg++/g++-include/CursesW.h581
-rw-r--r--gnu/lib/libg++/g++-include/DLList.cc327
-rw-r--r--gnu/lib/libg++/g++-include/DLList.h125
-rw-r--r--gnu/lib/libg++/g++-include/DiscUnif.cc29
-rw-r--r--gnu/lib/libg++/g++-include/DiscUnif.h75
-rw-r--r--gnu/lib/libg++/g++-include/Erlang.cc32
-rw-r--r--gnu/lib/libg++/g++-include/Erlang.h71
-rw-r--r--gnu/lib/libg++/g++-include/Fix.cc615
-rw-r--r--gnu/lib/libg++/g++-include/Fix.h471
-rw-r--r--gnu/lib/libg++/g++-include/Fix16.cc238
-rw-r--r--gnu/lib/libg++/g++-include/Fix16.h650
-rw-r--r--gnu/lib/libg++/g++-include/Fix24.cc327
-rw-r--r--gnu/lib/libg++/g++-include/Fix24.h599
-rw-r--r--gnu/lib/libg++/g++-include/Geom.cc30
-rw-r--r--gnu/lib/libg++/g++-include/Geom.h55
-rw-r--r--gnu/lib/libg++/g++-include/GetOpt.cc253
-rw-r--r--gnu/lib/libg++/g++-include/GetOpt.h130
-rw-r--r--gnu/lib/libg++/g++-include/HypGeom.cc30
-rw-r--r--gnu/lib/libg++/g++-include/HypGeom.h73
-rw-r--r--gnu/lib/libg++/g++-include/Integer.cc2423
-rw-r--r--gnu/lib/libg++/g++-include/Integer.h1104
-rw-r--r--gnu/lib/libg++/g++-include/LogNorm.cc36
-rw-r--r--gnu/lib/libg++/g++-include/LogNorm.h81
-rw-r--r--gnu/lib/libg++/g++-include/MLCG.cc103
-rw-r--r--gnu/lib/libg++/g++-include/MLCG.h90
-rw-r--r--gnu/lib/libg++/g++-include/Makefile31
-rw-r--r--gnu/lib/libg++/g++-include/NegExp.cc28
-rw-r--r--gnu/lib/libg++/g++-include/NegExp.h58
-rw-r--r--gnu/lib/libg++/g++-include/Normal.cc60
-rw-r--r--gnu/lib/libg++/g++-include/Normal.h69
-rw-r--r--gnu/lib/libg++/g++-include/Obstack.cc112
-rw-r--r--gnu/lib/libg++/g++-include/Obstack.h217
-rw-r--r--gnu/lib/libg++/g++-include/Pix.h6
-rw-r--r--gnu/lib/libg++/g++-include/Poisson.cc36
-rw-r--r--gnu/lib/libg++/g++-include/Poisson.h54
-rw-r--r--gnu/lib/libg++/g++-include/RNG.cc132
-rw-r--r--gnu/lib/libg++/g++-include/RNG.h60
-rw-r--r--gnu/lib/libg++/g++-include/Random.cc4
-rw-r--r--gnu/lib/libg++/g++-include/Random.h57
-rw-r--r--gnu/lib/libg++/g++-include/Rational.cc415
-rw-r--r--gnu/lib/libg++/g++-include/Rational.h284
-rw-r--r--gnu/lib/libg++/g++-include/Regex.cc136
-rw-r--r--gnu/lib/libg++/g++-include/Regex.h77
-rw-r--r--gnu/lib/libg++/g++-include/RndInt.cc4
-rw-r--r--gnu/lib/libg++/g++-include/RndInt.h177
-rw-r--r--gnu/lib/libg++/g++-include/SLList.cc247
-rw-r--r--gnu/lib/libg++/g++-include/SLList.h117
-rw-r--r--gnu/lib/libg++/g++-include/SmplHist.cc112
-rw-r--r--gnu/lib/libg++/g++-include/SmplHist.h74
-rw-r--r--gnu/lib/libg++/g++-include/SmplStat.cc160
-rw-r--r--gnu/lib/libg++/g++-include/SmplStat.h69
-rw-r--r--gnu/lib/libg++/g++-include/String.cc1311
-rw-r--r--gnu/lib/libg++/g++-include/String.h1318
-rw-r--r--gnu/lib/libg++/g++-include/Uniform.cc27
-rw-r--r--gnu/lib/libg++/g++-include/Uniform.h74
-rw-r--r--gnu/lib/libg++/g++-include/Weibull.cc33
-rw-r--r--gnu/lib/libg++/g++-include/Weibull.h76
-rw-r--r--gnu/lib/libg++/g++-include/_G_config.h52
-rw-r--r--gnu/lib/libg++/g++-include/builtin.cc4
-rw-r--r--gnu/lib/libg++/g++-include/builtin.h160
-rw-r--r--gnu/lib/libg++/g++-include/chr.cc37
-rw-r--r--gnu/lib/libg++/g++-include/compare.cc4
-rw-r--r--gnu/lib/libg++/g++-include/compare.h92
-rw-r--r--gnu/lib/libg++/g++-include/dtoa.cc335
-rw-r--r--gnu/lib/libg++/g++-include/error.cc51
-rw-r--r--gnu/lib/libg++/g++-include/fmtq.cc29
-rw-r--r--gnu/lib/libg++/g++-include/gcd.cc52
-rw-r--r--gnu/lib/libg++/g++-include/gen/AVLMap.ccP608
-rw-r--r--gnu/lib/libg++/g++-include/gen/AVLMap.hP157
-rw-r--r--gnu/lib/libg++/g++-include/gen/AVLSet.ccP885
-rw-r--r--gnu/lib/libg++/g++-include/gen/AVLSet.hP167
-rw-r--r--gnu/lib/libg++/g++-include/gen/AVec.ccP401
-rw-r--r--gnu/lib/libg++/g++-include/gen/AVec.hP123
-rw-r--r--gnu/lib/libg++/g++-include/gen/BSTSet.ccP383
-rw-r--r--gnu/lib/libg++/g++-include/gen/BSTSet.hP166
-rw-r--r--gnu/lib/libg++/g++-include/gen/Bag.ccP79
-rw-r--r--gnu/lib/libg++/g++-include/gen/Bag.hP87
-rw-r--r--gnu/lib/libg++/g++-include/gen/CHBag.ccP214
-rw-r--r--gnu/lib/libg++/g++-include/gen/CHBag.hP110
-rw-r--r--gnu/lib/libg++/g++-include/gen/CHMap.ccP171
-rw-r--r--gnu/lib/libg++/g++-include/gen/CHMap.hP118
-rw-r--r--gnu/lib/libg++/g++-include/gen/CHSet.ccP276
-rw-r--r--gnu/lib/libg++/g++-include/gen/CHSet.hP121
-rw-r--r--gnu/lib/libg++/g++-include/gen/DLDeque.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/DLDeque.hP138
-rw-r--r--gnu/lib/libg++/g++-include/gen/DLList.ccP317
-rw-r--r--gnu/lib/libg++/g++-include/gen/DLList.hP170
-rw-r--r--gnu/lib/libg++/g++-include/gen/Deque.ccP11
-rw-r--r--gnu/lib/libg++/g++-include/gen/Deque.hP67
-rw-r--r--gnu/lib/libg++/g++-include/gen/FPQueue.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/FPQueue.hP121
-rw-r--r--gnu/lib/libg++/g++-include/gen/FPStack.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/FPStack.hP123
-rw-r--r--gnu/lib/libg++/g++-include/gen/FPlex.ccP182
-rw-r--r--gnu/lib/libg++/g++-include/gen/FPlex.hP263
-rw-r--r--gnu/lib/libg++/g++-include/gen/List.ccP959
-rw-r--r--gnu/lib/libg++/g++-include/gen/List.hP279
-rw-r--r--gnu/lib/libg++/g++-include/gen/MPlex.ccP850
-rw-r--r--gnu/lib/libg++/g++-include/gen/MPlex.hP422
-rw-r--r--gnu/lib/libg++/g++-include/gen/Map.ccP63
-rw-r--r--gnu/lib/libg++/g++-include/gen/Map.hP96
-rw-r--r--gnu/lib/libg++/g++-include/gen/OSLBag.ccP201
-rw-r--r--gnu/lib/libg++/g++-include/gen/OSLBag.hP100
-rw-r--r--gnu/lib/libg++/g++-include/gen/OSLSet.ccP326
-rw-r--r--gnu/lib/libg++/g++-include/gen/OSLSet.hP109
-rw-r--r--gnu/lib/libg++/g++-include/gen/OXPBag.ccP226
-rw-r--r--gnu/lib/libg++/g++-include/gen/OXPBag.hP76
-rw-r--r--gnu/lib/libg++/g++-include/gen/OXPSet.ccP285
-rw-r--r--gnu/lib/libg++/g++-include/gen/OXPSet.hP110
-rw-r--r--gnu/lib/libg++/g++-include/gen/PHPQ.ccP342
-rw-r--r--gnu/lib/libg++/g++-include/gen/PHPQ.hP118
-rw-r--r--gnu/lib/libg++/g++-include/gen/PQ.ccP67
-rw-r--r--gnu/lib/libg++/g++-include/gen/PQ.hP80
-rw-r--r--gnu/lib/libg++/g++-include/gen/Plex.ccP227
-rw-r--r--gnu/lib/libg++/g++-include/gen/Plex.hP503
-rw-r--r--gnu/lib/libg++/g++-include/gen/Queue.ccP14
-rw-r--r--gnu/lib/libg++/g++-include/gen/Queue.hP62
-rw-r--r--gnu/lib/libg++/g++-include/gen/RAVLMap.ccP684
-rw-r--r--gnu/lib/libg++/g++-include/gen/RAVLMap.hP162
-rw-r--r--gnu/lib/libg++/g++-include/gen/RPlex.ccP492
-rw-r--r--gnu/lib/libg++/g++-include/gen/RPlex.hP268
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLBag.ccP110
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLBag.hP104
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLList.ccP296
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLList.hP152
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLQueue.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLQueue.hP118
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLSet.ccP81
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLSet.hP97
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLStack.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/SLStack.hP119
-rw-r--r--gnu/lib/libg++/g++-include/gen/Set.ccP121
-rw-r--r--gnu/lib/libg++/g++-include/gen/Set.hP88
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplayBag.ccP451
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplayBag.hP160
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplayMap.ccP407
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplayMap.hP166
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplayPQ.ccP529
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplayPQ.hP157
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplaySet.ccP505
-rw-r--r--gnu/lib/libg++/g++-include/gen/SplaySet.hP167
-rw-r--r--gnu/lib/libg++/g++-include/gen/Stack.ccP11
-rw-r--r--gnu/lib/libg++/g++-include/gen/Stack.hP62
-rw-r--r--gnu/lib/libg++/g++-include/gen/VHBag.ccP269
-rw-r--r--gnu/lib/libg++/g++-include/gen/VHBag.hP92
-rw-r--r--gnu/lib/libg++/g++-include/gen/VHMap.ccP215
-rw-r--r--gnu/lib/libg++/g++-include/gen/VHMap.hP94
-rw-r--r--gnu/lib/libg++/g++-include/gen/VHSet.ccP268
-rw-r--r--gnu/lib/libg++/g++-include/gen/VHSet.hP105
-rw-r--r--gnu/lib/libg++/g++-include/gen/VOHSet.ccP313
-rw-r--r--gnu/lib/libg++/g++-include/gen/VOHSet.hP97
-rw-r--r--gnu/lib/libg++/g++-include/gen/VQueue.ccP88
-rw-r--r--gnu/lib/libg++/g++-include/gen/VQueue.hP139
-rw-r--r--gnu/lib/libg++/g++-include/gen/VStack.ccP71
-rw-r--r--gnu/lib/libg++/g++-include/gen/VStack.hP128
-rw-r--r--gnu/lib/libg++/g++-include/gen/Vec.ccP474
-rw-r--r--gnu/lib/libg++/g++-include/gen/Vec.hP142
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPBag.ccP77
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPBag.hP105
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPDeque.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPDeque.hP142
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPPQ.ccP148
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPPQ.hP115
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPQueue.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPQueue.hP123
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPSet.ccP68
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPSet.hP99
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPStack.ccP4
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPStack.hP124
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPlex.ccP412
-rw-r--r--gnu/lib/libg++/g++-include/gen/XPlex.hP248
-rw-r--r--gnu/lib/libg++/g++-include/gen/defs.hP60
-rw-r--r--gnu/lib/libg++/g++-include/hash.cc56
-rw-r--r--gnu/lib/libg++/g++-include/ioob.cc32
-rw-r--r--gnu/lib/libg++/g++-include/lg.cc32
-rw-r--r--gnu/lib/libg++/g++-include/math.cc4
-rw-r--r--gnu/lib/libg++/g++-include/new.cc31
-rw-r--r--gnu/lib/libg++/g++-include/new.h35
-rw-r--r--gnu/lib/libg++/g++-include/osfcn.h17
-rw-r--r--gnu/lib/libg++/g++-include/pow.cc70
-rw-r--r--gnu/lib/libg++/g++-include/regex.cc2757
-rw-r--r--gnu/lib/libg++/g++-include/regex.h274
-rw-r--r--gnu/lib/libg++/g++-include/shlib_version2
-rw-r--r--gnu/lib/libg++/g++-include/sqrt.cc43
-rw-r--r--gnu/lib/libg++/g++-include/std.h39
-rw-r--r--gnu/lib/libg++/g++-include/str.cc38
-rw-r--r--gnu/lib/libg++/g++-include/timer.cc130
-rw-r--r--gnu/lib/libg++/g++-include/values.h175
-rw-r--r--gnu/lib/libg++/genclass/Makefile13
-rw-r--r--gnu/lib/libg++/genclass/genclass.sh452
-rw-r--r--gnu/lib/libg++/iostream/PlotFile.C130
-rw-r--r--gnu/lib/libg++/iostream/PlotFile.h120
-rw-r--r--gnu/lib/libg++/iostream/SFile.C58
-rw-r--r--gnu/lib/libg++/iostream/SFile.h48
-rw-r--r--gnu/lib/libg++/iostream/editbuf.C707
-rw-r--r--gnu/lib/libg++/iostream/editbuf.h175
-rw-r--r--gnu/lib/libg++/iostream/filebuf.C580
-rw-r--r--gnu/lib/libg++/iostream/floatconv.C2416
-rw-r--r--gnu/lib/libg++/iostream/floatio.h27
-rw-r--r--gnu/lib/libg++/iostream/fstream.C65
-rw-r--r--gnu/lib/libg++/iostream/fstream.h72
-rw-r--r--gnu/lib/libg++/iostream/igetline.C135
-rw-r--r--gnu/lib/libg++/iostream/igetsb.C48
-rw-r--r--gnu/lib/libg++/iostream/indstream.C108
-rw-r--r--gnu/lib/libg++/iostream/indstream.h67
-rw-r--r--gnu/lib/libg++/iostream/iomanip.C77
-rw-r--r--gnu/lib/libg++/iostream/iomanip.h152
-rw-r--r--gnu/lib/libg++/iostream/ioprivate.h66
-rw-r--r--gnu/lib/libg++/iostream/iostream.C783
-rw-r--r--gnu/lib/libg++/iostream/iostream.h228
-rw-r--r--gnu/lib/libg++/iostream/makebuf.C71
-rw-r--r--gnu/lib/libg++/iostream/outfloat.C183
-rw-r--r--gnu/lib/libg++/iostream/parsestream.C307
-rw-r--r--gnu/lib/libg++/iostream/parsestream.h147
-rw-r--r--gnu/lib/libg++/iostream/procbuf.C126
-rw-r--r--gnu/lib/libg++/iostream/procbuf.h31
-rw-r--r--gnu/lib/libg++/iostream/sbufvform.C856
-rw-r--r--gnu/lib/libg++/iostream/sbufvscan.C746
-rw-r--r--gnu/lib/libg++/iostream/sgetline.C64
-rw-r--r--gnu/lib/libg++/iostream/stdiostream.C112
-rw-r--r--gnu/lib/libg++/iostream/stdiostream.h45
-rw-r--r--gnu/lib/libg++/iostream/stdstrbufs.C113
-rw-r--r--gnu/lib/libg++/iostream/stdstreams.C145
-rw-r--r--gnu/lib/libg++/iostream/stream.C120
-rw-r--r--gnu/lib/libg++/iostream/stream.h33
-rw-r--r--gnu/lib/libg++/iostream/streambuf.C666
-rw-r--r--gnu/lib/libg++/iostream/streambuf.h497
-rw-r--r--gnu/lib/libg++/iostream/strstream.C237
-rw-r--r--gnu/lib/libg++/iostream/strstream.h105
245 files changed, 56490 insertions, 0 deletions
diff --git a/gnu/lib/libg++/COPYING b/gnu/lib/libg++/COPYING
new file mode 100644
index 00000000000..9a170375811
--- /dev/null
+++ b/gnu/lib/libg++/COPYING
@@ -0,0 +1,249 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 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
+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.
+
+ 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.
+
+ 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
+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.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+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.
+
+ 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.
+
+ 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
+ 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.
+
+ 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.
+
+ 7. 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
+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
+Foundation.
+
+ 8. 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
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 9. 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
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+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
+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
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ 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.
+
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+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 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.
+
+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:
+
+ 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.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/gnu/lib/libg++/Makefile b/gnu/lib/libg++/Makefile
new file mode 100644
index 00000000000..0092c731a02
--- /dev/null
+++ b/gnu/lib/libg++/Makefile
@@ -0,0 +1,27 @@
+# $Id: Makefile,v 1.1 1995/10/18 08:38:05 deraadt Exp $
+
+SUBDIR= libg++ genclass
+
+INCLUDEDIRS= iostream libg++ g++-include
+
+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
+ @-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 g++-include/gen
+ @(cd g++-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)
+
+.include <bsd.subdir.mk>
diff --git a/gnu/lib/libg++/VERSION b/gnu/lib/libg++/VERSION
new file mode 100644
index 00000000000..22c1fccec44
--- /dev/null
+++ b/gnu/lib/libg++/VERSION
@@ -0,0 +1,3 @@
+libg++ version 2.4
+
+complete, unmodified libg++ sources are available from prep.ai.mit.edu.
diff --git a/gnu/lib/libg++/g++-include/ACG.cc b/gnu/lib/libg++/g++-include/ACG.cc
new file mode 100644
index 00000000000..27e7aa22564
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/ACG.cc
@@ -0,0 +1,291 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <ACG.h>
+#include <assert.h>
+
+//
+// This is an extension of the older implementation of Algorithm M
+// which I previously supplied. The main difference between this
+// version and the old code are:
+//
+// + Andres searched high & low for good constants for
+// the LCG.
+//
+// + theres more bit chopping going on.
+//
+// The following contains his comments.
+//
+// agn@UNH.CS.CMU.EDU sez..
+//
+// The generator below is based on 2 well known
+// methods: Linear Congruential (LCGs) and Additive
+// Congruential generators (ACGs).
+//
+// The LCG produces the longest possible sequence
+// of 32 bit random numbers, each being unique in
+// that sequence (it has only 32 bits of state).
+// It suffers from 2 problems: a) Independence
+// isnt great, that is the (n+1)th number is
+// somewhat related to the preceding one, unlike
+// flipping a coin where knowing the past outcomes
+// dont help to predict the next result. b)
+// Taking parts of a LCG generated number can be
+// quite non-random: for example, looking at only
+// the least significant byte gives a permuted
+// 8-bit counter (that has a period length of only
+// 256). The advantage of an LCA is that it is
+// perfectly uniform when run for the entire period
+// length (and very uniform for smaller sequences
+// too, if the parameters are chosen carefully).
+//
+// ACGs have extremly long period lengths and
+// provide good independence. Unfortunately,
+// uniformity isnt not too great. Furthermore, I
+// didnt find any theoretically analysis of ACGs
+// that addresses uniformity.
+//
+// The RNG given below will return numbers
+// generated by an LCA that are permuted under
+// control of a ACG. 2 permutations take place: the
+// 4 bytes of one LCG generated number are
+// subjected to one of 16 permutations selected by
+// 4 bits of the ACG. The permutation a such that
+// byte of the result may come from each byte of
+// the LCG number. This effectively destroys the
+// structure within a word. Finally, the sequence
+// of such numbers is permuted within a range of
+// 256 numbers. This greatly improves independence.
+//
+//
+// Algorithm M as describes in Knuths "Art of Computer Programming",
+// Vol 2. 1969
+// is used with a linear congruential generator (to get a good uniform
+// distribution) that is permuted with a Fibonacci additive congruential
+// generator to get good independence.
+//
+// Bit, byte, and word distributions were extensively tested and pass
+// Chi-squared test near perfect scores (>7E8 numbers tested, Uniformity
+// assumption holds with probability > 0.999)
+//
+// Run-up tests for on 7E8 numbers confirm independence with
+// probability > 0.97.
+//
+// Plotting random points in 2d reveals no apparent structure.
+//
+// Autocorrelation on sequences of 5E5 numbers (A(i) = SUM X(n)*X(n-i),
+// i=1..512)
+// results in no obvious structure (A(i) ~ const).
+//
+// Except for speed and memory requirements, this generator outperforms
+// random() for all tests. (random() scored rather low on uniformity tests,
+// while independence test differences were less dramatic).
+//
+// AGN would like to..
+// thanks to M.Mauldin, H.Walker, J.Saxe and M.Molloy for inspiration & help.
+//
+// And I would (DGC) would like to thank Donald Kunth for AGN for letting me
+// use his extensions in this implementation.
+//
+
+//
+// Part of the table on page 28 of Knuth, vol II. This allows us
+// to adjust the size of the table at the expense of shorter sequences.
+//
+
+static randomStateTable[][3] = {
+{3,7,16}, {4,9, 32}, {3,10, 32}, {1,11, 32}, {1,15,64}, {3,17,128},
+{7,18,128}, {3,20,128}, {2,21, 128}, {1,22, 128}, {5,23, 128}, {3,25, 128},
+{2,29, 128}, {3,31, 128}, {13,33, 256}, {2,35, 256}, {11,36, 256},
+{14,39,256}, {3,41,256}, {9,49,256}, {3,52,256}, {24,55,256}, {7,57, 256},
+{19,58,256}, {38,89,512}, {17,95,512}, {6,97,512}, {11,98,512}, {-1,-1,-1} };
+
+//
+// spatial permutation table
+// RANDOM_PERM_SIZE must be a power of two
+//
+
+#define RANDOM_PERM_SIZE 64
+unsigned long randomPermutations[RANDOM_PERM_SIZE] = {
+0xffffffff, 0x00000000, 0x00000000, 0x00000000, // 3210
+0x0000ffff, 0x00ff0000, 0x00000000, 0xff000000, // 2310
+0xff0000ff, 0x0000ff00, 0x00000000, 0x00ff0000, // 3120
+0x00ff00ff, 0x00000000, 0xff00ff00, 0x00000000, // 1230
+
+0xffff0000, 0x000000ff, 0x00000000, 0x0000ff00, // 3201
+0x00000000, 0x00ff00ff, 0x00000000, 0xff00ff00, // 2301
+0xff000000, 0x00000000, 0x000000ff, 0x00ffff00, // 3102
+0x00000000, 0x00000000, 0x00000000, 0xffffffff, // 2103
+
+0xff00ff00, 0x00000000, 0x00ff00ff, 0x00000000, // 3012
+0x0000ff00, 0x00000000, 0x00ff0000, 0xff0000ff, // 2013
+0x00000000, 0x00000000, 0xffffffff, 0x00000000, // 1032
+0x00000000, 0x0000ff00, 0xffff0000, 0x000000ff, // 1023
+
+0x00000000, 0xffffffff, 0x00000000, 0x00000000, // 0321
+0x00ffff00, 0xff000000, 0x00000000, 0x000000ff, // 0213
+0x00000000, 0xff000000, 0x0000ffff, 0x00ff0000, // 0132
+0x00000000, 0xff00ff00, 0x00000000, 0x00ff00ff // 0123
+};
+
+//
+// SEED_TABLE_SIZE must be a power of 2
+//
+#define SEED_TABLE_SIZE 32
+static unsigned long seedTable[SEED_TABLE_SIZE] = {
+0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
+0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
+0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
+0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
+0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
+0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
+0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
+0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf
+};
+
+//
+// The LCG used to scramble the ACG
+//
+//
+// LC-parameter selection follows recommendations in
+// "Handbook of Mathematical Functions" by Abramowitz & Stegun 10th, edi.
+//
+// LC_A = 251^2, ~= sqrt(2^32) = 66049
+// LC_C = result of a long trial & error series = 3907864577
+//
+
+static const unsigned long LC_A = 66049;
+static const unsigned long LC_C = 3907864577;
+static inline unsigned long LCG(unsigned long x)
+{
+ return( x * LC_A + LC_C );
+}
+
+
+ACG::ACG(unsigned long seed, int size)
+{
+
+ initialSeed = seed;
+
+ //
+ // Determine the size of the state table
+ //
+
+ for (register int l = 0;
+ randomStateTable[l][0] != -1 && randomStateTable[l][1] < size;
+ l++);
+
+ if (randomStateTable[l][1] == -1) {
+ l--;
+ }
+
+ initialTableEntry = l;
+
+ stateSize = randomStateTable[ initialTableEntry ][ 1 ];
+ auxSize = randomStateTable[ initialTableEntry ][ 2 ];
+
+ //
+ // Allocate the state table & the auxillary table in a single malloc
+ //
+
+ state = new unsigned long[stateSize + auxSize];
+ auxState = &state[stateSize];
+
+ reset();
+}
+
+//
+// Initialize the state
+//
+void
+ACG::reset()
+{
+ register unsigned long u;
+
+ if (initialSeed < SEED_TABLE_SIZE) {
+ u = seedTable[ initialSeed ];
+ } else {
+ u = initialSeed ^ seedTable[ initialSeed & (SEED_TABLE_SIZE-1) ];
+ }
+
+
+ j = randomStateTable[ initialTableEntry ][ 0 ] - 1;
+ k = randomStateTable[ initialTableEntry ][ 1 ] - 1;
+
+ register int i;
+ for(i = 0; i < stateSize; i++) {
+ state[i] = u = LCG(u);
+ }
+
+ for (i = 0; i < auxSize; i++) {
+ auxState[i] = u = LCG(u);
+ }
+
+ k = u % stateSize;
+ int tailBehind = (stateSize - randomStateTable[ initialTableEntry ][ 0 ]);
+ j = k - tailBehind;
+ if (j < 0) {
+ j += stateSize;
+ }
+
+ lcgRecurr = u;
+
+ assert(sizeof(double) == 2 * sizeof(long));
+}
+
+ACG::~ACG()
+{
+ if (state) delete state;
+ state = 0;
+ // don't delete auxState, it's really an alias for state.
+}
+
+//
+// Returns 32 bits of random information.
+//
+
+unsigned long ACG::asLong()
+{
+ unsigned long result = state[k] + state[j];
+ state[k] = result;
+ j = (j <= 0) ? (stateSize-1) : (j-1);
+ k = (k <= 0) ? (stateSize-1) : (k-1);
+
+ short int auxIndex = (result >> 24) & (auxSize - 1);
+ register unsigned long auxACG = auxState[auxIndex];
+ auxState[auxIndex] = lcgRecurr = LCG(lcgRecurr);
+
+ //
+ // 3c is a magic number. We are doing four masks here, so we
+ // do not want to run off the end of the permutation table.
+ // This insures that we have always got four entries left.
+ //
+ register unsigned long *perm = & randomPermutations[result & 0x3c];
+
+ result = *(perm++) & auxACG;
+ result |= *(perm++) & ((auxACG << 24)
+ | ((auxACG >> 8)& 0xffffff));
+ result |= *(perm++) & ((auxACG << 16)
+ | ((auxACG >> 16) & 0xffff));
+ result |= *(perm++) & ((auxACG << 8)
+ | ((auxACG >> 24) & 0xff));
+
+ return(result);
+}
diff --git a/gnu/lib/libg++/g++-include/ACG.h b/gnu/lib/libg++/g++-include/ACG.h
new file mode 100644
index 00000000000..f78a54163a9
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/ACG.h
@@ -0,0 +1,71 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: ACG.h,v 1.1 1995/10/18 08:38:14 deraadt Exp $
+*/
+
+#ifndef _ACG_h
+#define _ACG_h 1
+
+#include <RNG.h>
+#include <math.h>
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+//
+// Additive number generator. This method is presented in Volume II
+// of The Art of Computer Programming by Knuth. I've coded the algorithm
+// and have added the extensions by Andres Nowatzyk of CMU to randomize
+// the result of algorithm M a bit by using an LCG & a spatial
+// permutation table.
+//
+// The version presented uses the same constants for the LCG that Andres
+// uses (chosen by trial & error). The spatial permutation table is
+// the same size (it's based on word size). This is for 32-bit words.
+//
+// The ``auxillary table'' used by the LCG table varies in size, and
+// is chosen to be the the smallest power of two which is larger than
+// twice the size of the state table.
+//
+
+class ACG : public RNG {
+
+ unsigned long initialSeed; // used to reset generator
+ int initialTableEntry;
+
+ unsigned long *state;
+ unsigned long *auxState;
+ short stateSize;
+ short auxSize;
+ unsigned long lcgRecurr;
+ short j;
+ short k;
+
+protected:
+
+public:
+ ACG(unsigned long seed = 0, int size = 55);
+ virtual ~ACG();
+ //
+ // Return a long-words word of random bits
+ //
+ virtual unsigned long asLong();
+ virtual void reset();
+};
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/AllocRing.cc b/gnu/lib/libg++/g++-include/AllocRing.cc
new file mode 100644
index 00000000000..5be1ff06f41
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/AllocRing.cc
@@ -0,0 +1,110 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <AllocRing.h>
+#include <new.h>
+
+AllocRing::AllocRing(int max)
+ :n(max), current(0), nodes(new AllocQNode[max])
+{
+ for (int i = 0; i < n; ++i)
+ {
+ nodes[i].ptr = 0;
+ nodes[i].sz = 0;
+ }
+}
+
+int AllocRing::find(void* p)
+{
+ if (p == 0) return -1;
+
+ for (int i = 0; i < n; ++i)
+ if (nodes[i].ptr == p)
+ return i;
+
+ return -1;
+}
+
+
+void AllocRing::clear()
+{
+ for (int i = 0; i < n; ++i)
+ {
+ if (nodes[i].ptr != 0)
+ {
+ delete(nodes[i].ptr);
+ nodes[i].ptr = 0;
+ }
+ nodes[i].sz = 0;
+ }
+ current = 0;
+}
+
+
+void AllocRing::free(void* p)
+{
+ int idx = find(p);
+ if (idx >= 0)
+ {
+ delete nodes[idx].ptr;
+ nodes[idx].ptr = 0;
+ }
+}
+
+AllocRing::~AllocRing()
+{
+ clear();
+}
+
+int AllocRing::contains(void* p)
+{
+ return find(p) >= 0;
+}
+
+static inline unsigned int good_size(unsigned int s)
+{
+ unsigned int req = s + 4;
+ unsigned int good = 8;
+ while (good < req) good <<= 1;
+ return good - 4;
+}
+
+void* AllocRing::alloc(int s)
+{
+ unsigned int size = good_size(s);
+
+ void* p;
+ if (nodes[current].ptr != 0 &&
+ nodes[current].sz >= int(size) &&
+ nodes[current].sz < int(4 * size))
+ p = nodes[current].ptr;
+ else
+ {
+ if (nodes[current].ptr != 0) delete nodes[current].ptr;
+ p = new char[size];
+ nodes[current].ptr = p;
+ nodes[current].sz = size;
+ }
+ ++current;
+ if (current >= n) current = 0;
+ return p;
+}
diff --git a/gnu/lib/libg++/g++-include/AllocRing.h b/gnu/lib/libg++/g++-include/AllocRing.h
new file mode 100644
index 00000000000..6a28b15b011
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/AllocRing.h
@@ -0,0 +1,63 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: AllocRing.h,v 1.1 1995/10/18 08:38:14 deraadt Exp $
+*/
+
+#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++/g++-include/Binomial.cc b/gnu/lib/libg++/g++-include/Binomial.cc
new file mode 100644
index 00000000000..7166e55927c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Binomial.cc
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Binomial.h>
+
+double Binomial::operator()()
+{
+ int s = 0;
+ for (int i = 0; i < pN; i++) {
+ if (pGenerator -> asDouble() < pU) {
+ s++;
+ }
+ }
+ return(double(s));
+}
+
diff --git a/gnu/lib/libg++/g++-include/Binomial.h b/gnu/lib/libg++/g++-include/Binomial.h
new file mode 100644
index 00000000000..097f9ee027b
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Binomial.h
@@ -0,0 +1,58 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Binomial.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#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++/g++-include/BitSet.cc b/gnu/lib/libg++/g++-include/BitSet.cc
new file mode 100644
index 00000000000..7255f3d6bc1
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/BitSet.cc
@@ -0,0 +1,1000 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ BitSet class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <BitSet.h>
+#include <std.h>
+#include <limits.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <new.h>
+#include <builtin.h>
+#include <string.h>
+#include <strstream.h>
+
+void BitSet::error(const char* msg) const
+{
+ (*lib_error_handler)("BitSet", msg);
+}
+
+// globals & constants
+
+BitSetRep _nilBitSetRep = { 0, 1, 0, {0} }; // nil BitSets point here
+
+#define ONES ((unsigned short)(~0L))
+#define MAXBitSetRep_SIZE ((1 << (sizeof(short)*CHAR_BIT - 1)) - 1)
+#define MINBitSetRep_SIZE 16
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
+
+// break things up into .s indices and positions
+
+
+// mask out bits from left
+
+static inline unsigned short lmask(int p)
+{
+ return ONES << p;
+}
+
+// mask out high bits
+
+static inline unsigned short rmask(int p)
+{
+ return ONES >> (BITSETBITS - 1 - p);
+}
+
+
+inline static BitSetRep* BSnew(int newlen)
+{
+ unsigned int siz = sizeof(BitSetRep) + newlen * sizeof(short)
+ + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINBitSetRep_SIZE;;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXBitSetRep_SIZE * sizeof(short))
+ (*lib_error_handler)("BitSet", "Requested length out of range");
+
+ BitSetRep* rep = (BitSetRep *) new char[allocsiz];
+ memset(rep, 0, allocsiz);
+ rep->sz = (allocsiz - sizeof(BitSetRep) + sizeof(short)) / sizeof(short);
+ return rep;
+}
+
+BitSetRep* BitSetalloc(BitSetRep* old, const unsigned short* src, int srclen,
+ int newvirt, int newlen)
+{
+ if (old == &_nilBitSetRep) old = 0;
+ BitSetRep* rep;
+ if (old == 0 || newlen >= old->sz)
+ rep = BSnew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->virt = newvirt;
+
+ if (srclen != 0 && src != rep->s)
+ memcpy(rep->s, src, srclen * sizeof(short));
+ // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
+ if (rep->virt)
+ memset(&rep->s[srclen], ONES, (newlen - srclen) * sizeof(short));
+ if (old != rep && old != 0) delete old;
+ return rep;
+}
+
+BitSetRep* BitSetresize(BitSetRep* old, int newlen)
+{
+ BitSetRep* rep;
+ if (old == 0 || old == &_nilBitSetRep)
+ {
+ rep = BSnew(newlen);
+ rep->virt = 0;
+ }
+ else if (newlen >= old->sz)
+ {
+ rep = BSnew(newlen);
+ memcpy(rep->s, old->s, old->len * sizeof(short));
+ rep->virt = old->virt;
+ // BUG fix: extend virtual bit! 20 Oct 1992 Kevin Karplus
+ if (rep->virt)
+ memset(&rep->s[old->len], ONES, (newlen - old->len) * sizeof(short));
+ delete old;
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+
+ return rep;
+}
+
+// same, for straight copy
+
+BitSetRep* BitSetcopy(BitSetRep* old, const BitSetRep* src)
+{
+ BitSetRep* rep;
+ if (old == &_nilBitSetRep) old = 0;
+ if (src == 0 || src == &_nilBitSetRep)
+ {
+ if (old == 0)
+ rep = BSnew(0);
+ else
+ rep = old;
+ rep->len = 0;
+ rep->virt = 0;
+ }
+ else if (old == src)
+ return old;
+ else
+ {
+ int newlen = src->len;
+ if (old == 0 || newlen > old->sz)
+ {
+ rep = BSnew(newlen);
+ if (old != 0) delete old;
+ }
+ else
+ rep = old;
+
+ memcpy(rep->s, src->s, newlen * sizeof(short));
+ rep->len = newlen;
+ rep->virt = src->virt;
+ }
+ return rep;
+}
+
+
+// remove unneeded top bits
+
+inline static void trim(BitSetRep* rep)
+{
+ int l = rep->len;
+ unsigned short* s = &(rep->s[l - 1]);
+
+ if (rep->virt == 0)
+ while (l > 0 && *s-- == 0) --l;
+ else
+ while (l > 0 && *s-- == ONES) --l;
+ rep->len = l;
+}
+
+int operator == (const BitSet& x, const BitSet& y)
+{
+ if (x.rep->virt != y.rep->virt)
+ return 0;
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ unsigned short* xs = x.rep->s;
+ unsigned short* ys = y.rep->s;
+ if (xl<=yl)
+ {
+ if (memcmp((void*)xs, (void*)ys, xl * sizeof(short)))
+ return 0;
+ for (register int i=xl; i<yl; i++)
+ if (ys[i])
+ return 0;
+ return 1;
+ }
+ else
+ {
+ if (memcmp((void*)xs, (void*)ys, yl * sizeof(short)))
+ return 0;
+ for (register int i=yl; i<xl; i++)
+ if (xs[i])
+ return 0;
+ return 1;
+ }
+}
+
+int operator <= (const BitSet& x, const BitSet& y)
+{
+ if (x.rep->virt > y.rep->virt)
+ return 0;
+
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ unsigned short* xs = x.rep->s;
+ unsigned short* ys = y.rep->s;
+ unsigned short* topx = &(xs[xl]);
+ unsigned short* topy = &(ys[yl]);
+
+ while (xs < topx && ys < topy)
+ {
+ unsigned short a = *xs++;
+ unsigned short b = *ys++;
+ if ((a | b) != b)
+ return 0;
+ }
+ if (xl == yl)
+ return x.rep->virt <= y.rep->virt;
+ else if (xl < yl)
+ return !x.rep->virt;
+ else
+ return y.rep->virt;
+}
+
+
+int operator < (const BitSet& x, const BitSet& y)
+{
+ if (x.rep->virt > y.rep->virt)
+ return 0;
+
+ int xl = x.rep->len;
+ int yl = y.rep->len;
+
+ unsigned short* xs = x.rep->s;
+ unsigned short* ys = y.rep->s;
+ unsigned short* topx = &(xs[xl]);
+ unsigned short* topy = &(ys[yl]);
+ int one_diff = 0;
+ while (xs < topx && ys < topy)
+ {
+ unsigned short a = *xs++;
+ unsigned short b = *ys++;
+ unsigned short c = a | b;
+ if (c != b)
+ return 0;
+ else if (c != a)
+ one_diff = 1;
+ }
+ if (xl == yl)
+ return x.rep->virt < y.rep->virt ||
+ (one_diff && x.rep->virt == y.rep->virt);
+ else if (xl < yl)
+ return !x.rep->virt;
+ else
+ return y.rep->virt;
+}
+
+
+
+int BitSet::empty() const
+{
+ if (rep->virt == 1)
+ return 0;
+
+ unsigned short* bots = rep->s;
+ unsigned short* s = &(bots[rep->len - 1]);
+ while (s >= bots) if (*s-- != 0) return 0;
+ return 1;
+}
+
+
+int BitSet::count(int b) const
+{
+ if (b == rep->virt)
+ return -1;
+ int l = 0;
+ unsigned short* s = rep->s;
+ unsigned short* tops = &(s[rep->len]);
+ if (b == 1)
+ {
+ while (s < tops)
+ {
+ unsigned short a = *s++;
+ for (int i = 0; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ ++l;
+ a >>= 1;
+ }
+ }
+ }
+ else
+ {
+ unsigned short maxbit = 1 << (BITSETBITS - 1);
+ while (s < tops)
+ {
+ unsigned short a = *s++;
+ for (int i = 0; i < BITSETBITS; ++i)
+ {
+ if ((a & maxbit) == 0)
+ ++l;
+ a <<= 1;
+ }
+ }
+ }
+ return l;
+}
+
+BitSetRep* BitSetcmpl(const BitSetRep* src, BitSetRep* r)
+{
+ r = BitSetcopy(r, src);
+ r->virt = !src->virt;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[r->len]);
+ if (r->len == 0)
+ *rs = ONES;
+ else
+ {
+ while (rs < topr)
+ {
+ unsigned short cmp = ~(*rs);
+ *rs++ = cmp;
+ }
+ }
+ trim(r);
+ return r;
+}
+
+
+BitSetRep* BitSetop(const BitSetRep* x, const BitSetRep* y,
+ BitSetRep* r, char op)
+{
+ int xrsame = x == r;
+ int yrsame = y == r;
+ int xv = x->virt;
+ int yv = y->virt;
+ int xl = x->len;
+ int yl = y->len;
+ int rl = (xl >= yl)? xl : yl;
+
+ r = BitSetresize(r, rl);
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+
+ int av, bv;
+ const unsigned short* as;
+ const unsigned short* topa;
+ const unsigned short* bs;
+ const unsigned short* topb;
+
+ if (xl <= yl)
+ {
+ as = (xrsame)? r->s : x->s;
+ av = xv;
+ topa = &(as[xl]);
+ bs = (yrsame)? r->s : y->s;
+ bv = yv;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ as = (yrsame)? r->s : y->s;
+ av = yv;
+ topa = &(as[yl]);
+ bs = (xrsame)? r->s : x->s;
+ bv = xv;
+ topb = &(bs[xl]);
+ if (op == '-') // reverse sense of difference
+ op = 'D';
+ }
+
+ switch (op)
+ {
+ case '&':
+ r->virt = av & bv;
+ while (as < topa) *rs++ = *as++ & *bs++;
+ if (av)
+ while (rs < topr) *rs++ = *bs++;
+ else
+ while (rs < topr) *rs++ = 0;
+ break;
+ case '|':
+ r->virt = av | bv;
+ while (as < topa) *rs++ = *as++ | *bs++;
+ if (av)
+ while (rs < topr) *rs++ = ONES;
+ else
+ while (rs < topr) *rs++ = *bs++;
+ break;
+ case '^':
+ r->virt = av ^ bv;
+ while (as < topa) *rs++ = *as++ ^ *bs++;
+ if (av)
+ while (rs < topr) *rs++ = ~(*bs++);
+ else
+ while (rs < topr) *rs++ = *bs++;
+ break;
+ case '-':
+ r->virt = av & ~(bv);
+ while (as < topa) *rs++ = *as++ & ~(*bs++);
+ if (av)
+ while (rs < topr) *rs++ = ~(*bs++);
+ else
+ while (rs < topr) *rs++ = 0;
+ break;
+ case 'D':
+ r->virt = ~(av) & (bv);
+ while (as < topa) *rs++ = ~(*as++) & (*bs++);
+ if (av)
+ while (rs < topr) *rs++ = 0;
+ else
+ while (rs < topr) *rs++ = *bs++;
+ break;
+ }
+ trim(r);
+ return r;
+}
+
+
+void BitSet::set(int p)
+{
+ if (p < 0) error("Illegal bit index");
+
+ int index = BitSet_index(p);
+ int pos = BitSet_pos(p);
+
+ if (index >= rep->len)
+ {
+ if (rep->virt)
+ return;
+ else
+ rep = BitSetresize(rep, index+1);
+ }
+
+ rep->s[index] |= (1 << pos);
+}
+
+void BitSet::clear()
+{
+ if (rep->len > 0) memset(rep->s, 0, rep->sz * sizeof(short));
+ rep->len = rep->virt = 0;
+}
+
+void BitSet::clear(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ int index = BitSet_index(p);
+ if (index >= rep->len)
+ {
+ if (rep->virt == 0)
+ return;
+ else
+ rep = BitSetresize(rep, index+1);
+ }
+ rep->s[index] &= ~(1 << BitSet_pos(p));
+}
+
+void BitSet::invert(int p)
+{
+ if (p < 0) error("Illegal bit index");
+ int index = BitSet_index(p);
+ if (index >= rep->len) rep = BitSetresize(rep, index+1);
+ rep->s[index] ^= (1 << BitSet_pos(p));
+}
+
+void BitSet::set(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+
+ if (rep->virt && index1 >= rep->len)
+ return;
+
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ rep = BitSetresize(rep, index2+1);
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (index2 == index1)
+ *s |= m1 & m2;
+ else
+ {
+ *s++ |= m1;
+ unsigned short* top = &(rep->s[index2]);
+ *top |= m2;
+ while (s < top)
+ *s++ = ONES;
+ }
+}
+
+void BitSet::clear(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+
+ if (!rep->virt && index1 >= rep->len)
+ return;
+
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ rep = BitSetresize(rep, index2+1);
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (index2 == index1)
+ *s &= ~(m1 & m2);
+ else
+ {
+ *s++ &= ~m1;
+ unsigned short* top = &(rep->s[index2]);
+ *top &= ~m2;
+ while (s < top)
+ *s++ = 0;
+ }
+}
+
+void BitSet::invert(int from, int to)
+{
+ if (from < 0 || from > to) error("Illegal bit index");
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ rep = BitSetresize(rep, index2+1);
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (index2 == index1)
+ *s ^= m1 & m2;
+ else
+ {
+ *s++ ^= m1;
+ unsigned short* top = &(rep->s[index2]);
+ *top ^= m2;
+ while (s < top)
+ {
+ unsigned short cmp = ~(*s);
+ *s++ = cmp;
+ }
+ }
+}
+
+
+int BitSet::test(int from, int to) const
+{
+ if (from < 0 || from > to) return 0;
+
+ int index1 = BitSet_index(from);
+ int pos1 = BitSet_pos(from);
+
+ if (index1 >= rep->len)
+ return rep->virt;
+
+ int index2 = BitSet_index(to);
+ int pos2 = BitSet_pos(to);
+
+ if (index2 >= rep->len)
+ {
+ if (rep->virt)
+ return 1;
+ else
+ {
+ index2 = rep->len - 1;
+ pos2 = BITSETBITS - 1;
+ }
+ }
+
+ unsigned short* s = &(rep->s[index1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+
+ if (index2 == index1)
+ return (*s & m1 & m2) != 0;
+ else
+ {
+ if (*s++ & m1)
+ return 1;
+ unsigned short* top = &(rep->s[index2]);
+ if (*top & m2)
+ return 1;
+ while (s < top)
+ if (*s++ != 0)
+ return 1;
+ return 0;
+ }
+}
+
+int BitSet::next(int p, int b) const
+{
+ ++p;
+ int index = BitSet_index(p);
+ int pos = BitSet_pos(p);
+
+ int l = rep->len;
+
+ if (index >= l)
+ {
+ if (rep->virt == b)
+ return p;
+ else
+ return -1;
+ }
+ int j = index;
+ unsigned short* s = rep->s;
+ unsigned short a = s[j] >> pos;
+ int i = pos;
+
+ if (b == 1)
+ {
+ for (; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ for (++j; j < l; ++j)
+ {
+ a = s[j];
+ for (i = 0; i < BITSETBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ }
+ if (rep->virt)
+ return j * BITSETBITS;
+ else
+ return -1;
+ }
+ else
+ {
+ for (; i < BITSETBITS; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ for (++j; j < l; ++j)
+ {
+ a = s[j];
+ if (a != ONES)
+ {
+ for (i = 0; i < BITSETBITS; ++i)
+ {
+ if ((a & 1) == 0)
+ return j * BITSETBITS + i;
+ a >>= 1;
+ }
+ }
+ }
+ if (!rep->virt)
+ return j * BITSETBITS;
+ else
+ return -1;
+ }
+}
+
+int BitSet::prev(int p, int b) const
+{
+ if (--p < 0)
+ return -1;
+
+ int index = BitSet_index(p);
+ int pos = BitSet_pos(p);
+
+ unsigned short* s = rep->s;
+ int l = rep->len;
+
+ if (index >= l)
+ {
+ if (rep->virt == b)
+ return p;
+ else
+ {
+ index = l - 1;
+ pos = BITSETBITS - 1;
+ }
+ }
+
+ int j = index;
+ unsigned short a = s[j];
+
+ int i = pos;
+ unsigned short maxbit = 1 << pos;
+
+ if (b == 1)
+ {
+ for (; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ maxbit = 1 << (BITSETBITS - 1);
+ for (--j; j >= 0; --j)
+ {
+ a = s[j];
+ for (i = BITSETBITS - 1; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ }
+ return -1;
+ }
+ else
+ {
+ if (a != ONES)
+ {
+ for (; i >= 0; --i)
+ {
+ if ((a & maxbit) == 0)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ }
+ maxbit = 1 << (BITSETBITS - 1);
+ for (--j; j >= 0; --j)
+ {
+ a = s[j];
+ if (a != ONES)
+ {
+ for (i = BITSETBITS - 1; i >= 0; --i)
+ {
+ if ((a & maxbit) == 0)
+ return j * BITSETBITS + i;
+ a <<= 1;
+ }
+ }
+ }
+ return -1;
+ }
+}
+
+int BitSet::last(int b) const
+{
+ if (b == rep->virt)
+ return -1;
+ else
+ return prev((rep->len) * BITSETBITS, b);
+}
+
+
+extern AllocRing _libgxx_fmtq;
+
+const char* BitSettoa(const BitSet& x, char f, char t, char star)
+{
+ trim(x.rep);
+ int wrksiz = (x.rep->len + 1) * BITSETBITS + 2;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ ostrstream stream(fmtbase, wrksiz);
+
+ x.printon(stream, f, t, star);
+ stream << ends;
+ return fmtbase;
+}
+
+#if defined(__GNUG__) && !defined(NO_NRV)
+
+BitSet shorttoBitSet(unsigned short w) return r
+{
+ r.rep = BitSetalloc(0, &w, 1, 0, 2); trim(r.rep);
+}
+
+BitSet longtoBitSet(unsigned long w) return r;
+{
+ unsigned short u[2];
+ u[0] = w & ((unsigned short)(~(0)));
+ u[1] = w >> BITSETBITS;
+ r.rep = BitSetalloc(0, &u[0], 2, 0, 3);
+ trim(r.rep);
+}
+
+BitSet atoBitSet(const char* s, char f, char t, char star) return r
+{
+ int sl = strlen(s);
+ if (sl != 0)
+ {
+ r.rep = BitSetresize(r.rep, sl / BITSETBITS + 1);
+ unsigned short* rs = r.rep->s;
+ unsigned short a = 0;
+ unsigned short m = 1;
+ char lastch = 0;
+ unsigned int i = 0;
+ unsigned int l = 1;
+ for(;;)
+ {
+ char ch = s[i];
+ if (ch == t)
+ a |= m;
+ else if (ch == star)
+ {
+ if (r.rep->virt = lastch == t)
+ *rs = a | ~(m - 1);
+ else
+ *rs = a;
+ break;
+ }
+ else if (ch != f)
+ {
+ *rs = a;
+ break;
+ }
+ lastch = ch;
+ if (++i == sl)
+ {
+ *rs = a;
+ break;
+ }
+ else if (i % BITSETBITS == 0)
+ {
+ *rs++ = a;
+ a = 0;
+ m = 1;
+ ++l;
+ }
+ else
+ m <<= 1;
+ }
+ r.rep->len = l;
+ trim(r.rep);
+ }
+ return;
+}
+
+#else
+
+BitSet shorttoBitSet(unsigned short w)
+{
+ BitSet r;
+ r.rep = BitSetalloc(0, &w, 1, 0, 2); trim(r.rep);
+ return r;
+}
+
+BitSet longtoBitSet(unsigned long w)
+{
+ BitSet r;
+ unsigned short u[2];
+ u[0] = w & ((unsigned short)(~(0)));
+ u[1] = w >> BITSETBITS;
+ r.rep = BitSetalloc(0, &u[0], 2, 0, 3);
+ trim(r.rep);
+ return r;
+}
+
+BitSet atoBitSet(const char* s, char f, char t, char star)
+{
+ BitSet r;
+ int sl = strlen(s);
+ if (sl != 0)
+ {
+ r.rep = BitSetresize(r.rep, sl / BITSETBITS + 1);
+ unsigned short* rs = r.rep->s;
+ unsigned short a = 0;
+ unsigned short m = 1;
+ char lastch = 0;
+ unsigned int i = 0;
+ unsigned int l = 1;
+ for(;;)
+ {
+ char ch = s[i];
+ if (ch == t)
+ a |= m;
+ else if (ch == star)
+ {
+ if (r.rep->virt = lastch == t)
+ *rs = a | ~(m - 1);
+ else
+ *rs = a;
+ break;
+ }
+ else if (ch != f)
+ {
+ *rs = a;
+ break;
+ }
+ lastch = ch;
+ if (++i == sl)
+ {
+ *rs = a;
+ break;
+ }
+ else if (i % BITSETBITS == 0)
+ {
+ *rs++ = a;
+ a = 0;
+ m = 1;
+ ++l;
+ }
+ else
+ m <<= 1;
+ }
+ r.rep->len = l;
+ trim(r.rep);
+ }
+ return r;
+}
+
+#endif
+
+ostream& operator << (ostream& s, const BitSet& x)
+{
+ if (s.opfx())
+ x.printon(s);
+ return s;
+}
+
+void BitSet::printon(ostream& os, char f, char t, char star) const
+// FIXME: Does not respect s.width()!
+{
+ trim(rep);
+ register streambuf* sb = os.rdbuf();
+ const unsigned short* s = rep->s;
+ const unsigned short* top = &(s[rep->len - 1]);
+
+ while (s < top)
+ {
+ unsigned short a = *s++;
+ for (int j = 0; j < BITSETBITS; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a >>= 1;
+ }
+ }
+
+ if (!rep->virt)
+ {
+ unsigned short a = *s;
+ if (rep->len != 0)
+ {
+ for (int j = 0; j < BITSETBITS && a != 0; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a >>= 1;
+ }
+ }
+ sb->sputc(f);
+ }
+ else
+ {
+ unsigned short a = *s;
+ unsigned short mask = ONES;
+ unsigned short himask = (1 << (BITSETBITS - 1)) - 1;
+ if (rep->len != 0)
+ {
+ for (int j = 0; j < BITSETBITS && a != mask; ++j)
+ {
+ sb->sputc((a & 1)? t : f);
+ a = (a >> 1) & himask;
+ mask = (mask >> 1) & himask;
+ }
+ }
+ sb->sputc(t);
+ }
+
+ sb->sputc(star);
+}
+
+int BitSet::OK() const
+{
+ int v = rep != 0; // have a rep
+ v &= rep->len <= rep->sz; // within bounds
+ v &= rep->virt == 0 || rep->virt == 1; // valid virtual bit
+ if (!v) error("invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/g++-include/BitSet.h b/gnu/lib/libg++/g++-include/BitSet.h
new file mode 100644
index 00000000000..23ce75a1d14
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/BitSet.h
@@ -0,0 +1,363 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: BitSet.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#ifndef _BitSet_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#define _BitSet_h 1
+
+#include <iostream.h>
+#include <limits.h>
+
+#define BITSETBITS (sizeof(short) * CHAR_BIT)
+
+struct BitSetRep
+{
+ unsigned short len; // number of shorts in s
+ unsigned short sz; // allocated slots
+ unsigned short virt; // virtual 0 or 1
+ unsigned short s[1]; // bits start here
+};
+
+extern BitSetRep* BitSetalloc(BitSetRep*, const unsigned short*,
+ int, int, int);
+extern BitSetRep* BitSetcopy(BitSetRep*, const BitSetRep*);
+extern BitSetRep* BitSetresize(BitSetRep*, int);
+extern BitSetRep* BitSetop(const BitSetRep*, const BitSetRep*,
+ BitSetRep*, char);
+extern BitSetRep* BitSetcmpl(const BitSetRep*, BitSetRep*);
+
+
+extern BitSetRep _nilBitSetRep;
+
+class BitSet;
+
+class BitSetBit
+{
+protected:
+ BitSet* src;
+ unsigned long pos;
+
+ public:
+ BitSetBit(BitSet* v, int p);
+ BitSetBit(const BitSetBit& b);
+ ~BitSetBit();
+ operator int();
+ int operator = (int b);
+};
+
+class BitSet
+{
+protected:
+ BitSetRep* rep;
+
+
+public:
+
+// constructors
+ BitSet();
+ BitSet(const BitSet&);
+
+ ~BitSet();
+
+ void operator = (const BitSet& y);
+
+// equality & subset tests
+
+ friend int operator == (const BitSet& x, const BitSet& y);
+ friend int operator != (const BitSet& x, const BitSet& y);
+ friend int operator < (const BitSet& x, const BitSet& y);
+ friend int operator <= (const BitSet& x, const BitSet& y);
+ friend int operator > (const BitSet& x, const BitSet& y);
+ friend int operator >= (const BitSet& x, const BitSet& y);
+
+
+// operations on self
+
+ void operator |= (const BitSet& y);
+ void operator &= (const BitSet& y);
+ void operator -= (const BitSet& y);
+ void operator ^= (const BitSet& y);
+
+ void complement();
+
+// individual bit manipulation
+
+ void set(int pos);
+ void set(int from, int to);
+ void set(); // set all
+
+ void clear(int pos);
+ void clear(int from, int to);
+ void clear(); // clear all
+
+ void invert(int pos);
+ void invert(int from, int to);
+
+ int test(int pos) const;
+ int test(int from, int to) const;
+
+ BitSetBit operator [] (int i);
+
+// iterators
+
+ int first(int b = 1) const;
+ int last(int b = 1) const;
+
+ int next(int pos, int b = 1) const;
+ int prev(int pos, int b = 1) const;
+ int previous(int pos, int b = 1) const /* Obsolete synonym */
+ { return prev(pos, b); }
+
+// status
+
+ int empty() const;
+ int virtual_bit() const;
+ int count(int b = 1) const;
+
+// convertors & IO
+
+ friend BitSet atoBitSet(const char* s,
+ char f='0', char t='1', char star='*');
+ // BitSettoa is deprecated; do not use in new programs.
+ friend const char* BitSettoa(const BitSet& x,
+ char f='0', char t='1', char star='*');
+
+ friend BitSet shorttoBitSet(unsigned short w);
+ friend BitSet longtoBitSet(unsigned long w);
+
+ friend ostream& operator << (ostream& s, const BitSet& x);
+ void printon(ostream& s,
+ char f='0', char t='1', char star='*') const;
+
+// procedural versions of operators
+
+ friend void and(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void or(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void xor(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void diff(const BitSet& x, const BitSet& y, BitSet& r);
+ friend void complement(const BitSet& x, BitSet& r);
+
+// misc
+
+ void error(const char* msg) const;
+ int OK() const;
+};
+
+
+typedef BitSet BitSetTmp;
+
+
+ BitSet operator | (const BitSet& x, const BitSet& y);
+ BitSet operator & (const BitSet& x, const BitSet& y);
+ BitSet operator - (const BitSet& x, const BitSet& y);
+ BitSet operator ^ (const BitSet& x, const BitSet& y);
+
+ BitSet operator ~ (const BitSet& x);
+
+// These are inlined regardless of optimization
+
+inline int BitSet_index(int l)
+{
+ return (unsigned)(l) / BITSETBITS;
+}
+
+inline int BitSet_pos(int l)
+{
+ return l & (BITSETBITS - 1);
+}
+
+
+inline BitSet::BitSet() : rep(&_nilBitSetRep) {}
+
+inline BitSet::BitSet(const BitSet& x) :rep(BitSetcopy(0, x.rep)) {}
+
+inline BitSet::~BitSet() { if (rep != &_nilBitSetRep) delete rep; }
+
+inline void BitSet::operator = (const BitSet& y)
+{
+ rep = BitSetcopy(rep, y.rep);
+}
+
+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(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 void BitSet::operator &= (const BitSet& y)
+{
+ and(*this, y, *this);
+}
+
+inline void BitSet::operator |= (const BitSet& y)
+{
+ or(*this, y, *this);
+}
+
+inline void BitSet::operator ^= (const BitSet& y)
+{
+ xor(*this, y, *this);
+}
+
+inline void BitSet::operator -= (const BitSet& y)
+{
+ diff(*this, y, *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()
+{
+ return src->test(pos);
+}
+
+inline int BitSetBit::operator = (int b)
+{
+ if (b) src->set(pos); else src->clear(pos); return b;
+}
+
+inline BitSetBit BitSet::operator [] (int i)
+{
+ if (i < 0) error("illegal bit index");
+ return BitSetBit(this, i);
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/BitString.cc b/gnu/lib/libg++/g++-include/BitString.cc
new file mode 100644
index 00000000000..261426c3c9d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/BitString.cc
@@ -0,0 +1,2080 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ BitString class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <BitString.h>
+#include <std.h>
+#include <limits.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <new.h>
+#include <builtin.h>
+#include <strstream.h>
+
+void BitString::error(const char* msg) const
+{
+ (*lib_error_handler)("BitString", msg);
+}
+
+// globals
+
+BitStrRep _nilBitStrRep = { 0, 1, {0} };
+
+BitString _nil_BitString;
+
+#define MINBitStrRep_SIZE 8
+#define MAXBitStrRep_SIZE ((1 << (sizeof(short)*CHAR_BIT - 1)) - 1)
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
+
+#define ONES ((unsigned short)(~0L))
+#define MAXBIT (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 unsigned short lmask(int p)
+{
+ if (p <= 0)
+ return ONES;
+ else
+ return ONES << p;
+}
+
+// mask out high bits
+
+static inline unsigned short rmask(int p)
+{
+ int s = BITSTRBITS - 1 - p;
+ if (s <= 0)
+ return ONES;
+ else
+ return ONES >> s;
+}
+
+
+// mask out unused bits in last word of rep
+
+inline static void check_last(BitStrRep* r)
+{
+ r->s[r->len / BITSTRBITS] &= ONES >> (BITSTRBITS - (r->len & (BITSTRBITS - 1)));
+}
+
+// merge bits from next word
+
+static inline unsigned short borrow_hi(const unsigned short a[], int ind,
+ int maxind, int p)
+{
+ if (ind < maxind)
+ return (a[ind] >> p) | (a[ind+1] << (BITSTRBITS - p));
+ else
+ return (a[ind] >> p);
+}
+
+// merge bits from prev word
+
+static inline unsigned short borrow_lo(const unsigned short a[], int ind,
+ int minind, int p)
+{
+ if (ind > minind)
+ return (a[ind] << (BITSTRBITS - 1 - p)) | (a[ind-1] >> (p + 1));
+ else
+ return (a[ind] << (BITSTRBITS - 1 - p));
+}
+
+// same with bounds check (for masks shorter than patterns)
+
+static inline unsigned short safe_borrow_hi(const unsigned short a[], int ind,
+ int maxind, int p)
+{
+ if (ind > maxind)
+ return 0;
+ else if (ind == maxind)
+ return(a[ind] >> p);
+ else
+ return (a[ind] >> p) | (a[ind+1] << (BITSTRBITS - p));
+}
+
+
+static inline unsigned short safe_borrow_lo(const unsigned short a[], int ind,
+ int minind, int p)
+{
+ if (ind < minind)
+ return 0;
+ else if (ind == minind)
+ return (a[ind] << (BITSTRBITS - 1 - p));
+ else
+ return (a[ind] << (BITSTRBITS - 1 - p)) | (a[ind-1] >> (p + 1));
+}
+
+// copy bits from a word boundary
+
+static inline void bit_copy(const unsigned short* ss, unsigned short* ds,
+ int nbits)
+{
+ if (ss != ds)
+ {
+ int n = (unsigned)(nbits) / BITSTRBITS;
+ if (n > 0) memmove((void*)ds, (const void*)ss, n * sizeof(short));
+ unsigned short m = ONES << (nbits & (BITSTRBITS - 1));
+ ds[n] = (ss[n] & ~m) | (ds[n] & m);
+ }
+}
+
+// clear bits from a word boundary
+
+static inline void bit_clear(unsigned short* ds, int nbits)
+{
+ int n = (unsigned)(nbits) / BITSTRBITS;
+ if (n > 0) memset((void*)ds, 0, n * sizeof(short));
+ ds[n] &= ONES << (nbits & (BITSTRBITS - 1));
+}
+
+
+
+// Copy ss from starts to fences-1 into ds starting at startd.
+// This will work even if ss & ds overlap.
+// The g++ optimizer does very good things with the messy shift expressions!
+
+static void bit_transfer(const unsigned short* ss, int starts, int fences,
+ unsigned short* ds, int startd)
+{
+ if (starts >= fences || ss == 0 || (ss == ds && starts == startd))
+ return;
+
+ int sind = BitStr_index(starts);
+ int spos = BitStr_pos(starts);
+ int dind = BitStr_index(startd);
+ int dpos = BitStr_pos(startd);
+
+ if (spos == 0 && dpos == 0)
+ {
+ bit_copy(&ss[sind], &ds[dind], fences - starts);
+ return;
+ }
+
+ int ends = fences - 1;
+ int endsind = BitStr_index(ends);
+ int endspos = BitStr_pos(ends);
+ int endd = startd + (ends - starts);
+ int enddind = BitStr_index(endd);
+ int enddpos = BitStr_pos(endd);
+
+ if (dind == enddind)
+ {
+ if (sind == endsind)
+ ds[dind] = (ds[dind] & ((ONES >> (BITSTRBITS - dpos)) |
+ (ONES << (enddpos + 1)))) |
+ (((ss[sind] >> spos) << dpos) &
+ ~((ONES >> (BITSTRBITS - dpos)) |
+ (ONES << (enddpos + 1))));
+ else
+ ds[dind] = (ds[dind] & ((ONES >> (BITSTRBITS - dpos)) |
+ (ONES << (enddpos + 1)))) |
+ ((((ss[sind] >> spos) |
+ (ss[sind+1] << (BITSTRBITS - spos)))
+ << dpos) &
+ ~((ONES >> (BITSTRBITS - dpos)) |
+ (ONES << (enddpos + 1))));
+ return;
+ }
+ else if (sind == endsind)
+ {
+ unsigned short saveend = (ds[enddind] & (ONES << (enddpos + 1))) |
+ (((ss[sind] << (BITSTRBITS - 1 - endspos)) >>
+ (BITSTRBITS - 1 - enddpos)) & ~(ONES << (enddpos + 1)));
+ ds[dind] = (ds[dind] & (ONES >> (BITSTRBITS - dpos))) |
+ (((ss[sind] >> spos) << dpos) & ~(ONES >> (BITSTRBITS - dpos)));
+ ds[enddind] = saveend;
+ return;
+ }
+
+ unsigned short saveend = (ds[enddind] & (ONES << (enddpos + 1))) |
+ ((((ss[endsind] << (BITSTRBITS - 1 - endspos)) |
+ (ss[endsind-1] >> (endspos + 1))) >>
+ (BITSTRBITS - 1 - enddpos)) & ~(ONES << (enddpos + 1)));
+ unsigned short savestart = (ds[dind] & (ONES >> (BITSTRBITS - dpos))) |
+ ((((ss[sind] >> spos) | (ss[sind+1] << (BITSTRBITS - spos))) << dpos)
+ & ~(ONES >> (BITSTRBITS - dpos)));
+
+
+ if (ds != ss || startd < starts)
+ {
+ int pos = spos - dpos;
+ if (pos < 0)
+ pos += BITSTRBITS;
+ else
+ ++sind;
+
+ for (;;) // lag by one in case of overlaps
+ {
+ if (dind == enddind - 1)
+ {
+ ds[dind] = savestart;
+ ds[enddind] = saveend;
+ return;
+ }
+ else
+ {
+ unsigned short tmp = ss[sind] >> pos;
+ if (++sind <= endsind) tmp |= ss[sind] << (BITSTRBITS - pos);
+ ds[dind++] = savestart;
+ savestart = tmp;
+ }
+ }
+ }
+ else
+ {
+ int pos = endspos - enddpos;
+ if (pos <= 0)
+ {
+ pos += BITSTRBITS;
+ --endsind;
+ }
+ for (;;)
+ {
+ if (enddind == dind + 1)
+ {
+ ds[enddind] = saveend;
+ ds[dind] = savestart;
+ return;
+ }
+ else
+ {
+ unsigned short tmp = ss[endsind] << (BITSTRBITS - pos);
+ if (--endsind >= sind) tmp |= ss[endsind] >> pos;
+ ds[enddind--] = saveend;
+ saveend = tmp;
+ }
+ }
+ }
+}
+
+// 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(short)
+ + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINBitStrRep_SIZE;;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXBitStrRep_SIZE * sizeof(short))
+ (*lib_error_handler)("BitString", "Requested length out of range");
+
+ BitStrRep* rep = (BitStrRep *) new char[allocsiz];
+ memset(rep, 0, allocsiz);
+ rep->sz = (allocsiz - sizeof(BitStrRep) + sizeof(short)) / sizeof(short);
+ return rep;
+}
+
+BitStrRep* BStr_alloc(BitStrRep* old, const unsigned short* 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))
+ bit_transfer(src, startpos, endp, rep->s, 0);
+
+ 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(short));
+ 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(short));
+ 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(short)) == 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 unsigned short* xs = x.rep->s;
+ const unsigned short* topx = &(xs[BitStr_len(xl)]);
+ const unsigned short* ys = y.rep->s;
+
+ while (xs < topx)
+ {
+ unsigned short a = *xs++;
+ unsigned short 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 unsigned short* xs = x.rep->s;
+ const unsigned short* ys = y.rep->s;
+ const unsigned short* topx = &(xs[BitStr_len(xl)]);
+ const unsigned short* topy = &(ys[BitStr_len(yl)]);
+ int one_diff = 0;
+ while (xs < topx)
+ {
+ unsigned short a = *xs++;
+ unsigned short b = *ys++;
+ unsigned short c = a | b;
+ if (c != b)
+ return 0;
+ else if (c != a)
+ one_diff = 1;
+ }
+ if (one_diff)
+ return 1;
+ else
+ {
+ while (ys < topy)
+ if (*ys++ != 0)
+ return 1;
+ return 0;
+ }
+}
+
+int lcompare(const BitString& x, const BitString& y)
+{
+ unsigned int xl = x.rep->len;
+ unsigned int yl = y.rep->len;
+
+ const unsigned short* xs = x.rep->s;
+ const unsigned short* topx = &(xs[BitStr_len(xl)]);
+ const unsigned short* ys = y.rep->s;
+ const unsigned short* topy = &(ys[BitStr_len(yl)]);
+
+ while (xs < topx && ys < topy)
+ {
+ unsigned short a = *xs++;
+ unsigned short b = *ys++;
+ if (a != b)
+ {
+ unsigned short mask = 1;
+ for (;;)
+ {
+ unsigned short abit = (a & mask) != 0;
+ unsigned short bbit = (b & mask) != 0;
+ int diff = abit - bbit;
+ if (diff != 0)
+ return diff;
+ else
+ mask <<= 1;
+ }
+ }
+ }
+ return xl - yl;
+}
+
+int BitString::count(unsigned int b) const
+{
+ check_last(rep);
+ int xwds = BitStr_len(rep->len);
+ int xlast = BitStr_pos(rep->len);
+ int l = 0;
+ const unsigned short* s = rep->s;
+ const unsigned short* tops = &(s[xwds - 1]);
+ unsigned short a;
+ int i;
+ if (b != 0)
+ {
+ while (s < tops)
+ {
+ a = *s++;
+ for (i = 0; i < BITSTRBITS && a != 0; ++i)
+ {
+ if (a & 1)
+ ++l;
+ a >>= 1;
+ }
+ }
+ a = *s;
+ for (i = 0; i < xlast && a != 0; ++i)
+ {
+ if (a & 1)
+ ++l;
+ a >>= 1;
+ }
+ }
+ else
+ {
+ unsigned short maxbit = 1 << (BITSTRBITS - 1);
+ while (s < tops)
+ {
+ a = *s++;
+ for (i = 0; i < BITSTRBITS; ++i)
+ {
+ if ((a & maxbit) == 0)
+ ++l;
+ a <<= 1;
+ }
+ }
+ maxbit = 1 << (xlast - 1);
+ a = *s;
+ for (i = 0; i < xlast; ++i)
+ {
+ if ((a & maxbit) == 0)
+ ++l;
+ a <<= 1;
+ }
+ }
+ return l;
+}
+
+
+BitStrRep* cmpl(const BitStrRep* src, BitStrRep* r)
+{
+ r = BStr_copy(r, src);
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[BitStr_len(r->len)]);
+ while (rs < topr)
+ {
+ unsigned short 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);
+
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[BitStr_len(rl)]);
+ const unsigned short* xs = (xrsame)? rs : x->s;
+ const unsigned short* 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);
+
+ unsigned short* rs = r->s;
+ const unsigned short* xs = (xrsame)? rs : x->s;
+ const unsigned short* topx = &(xs[BitStr_len(xl)]);
+ const unsigned short* ys = (yrsame)? rs : y->s;
+ const unsigned short* 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);
+
+ unsigned short* rs = r->s;
+ const unsigned short* xs = (xrsame)? rs : x->s;
+ const unsigned short* topx = &(xs[BitStr_len(xl)]);
+ const unsigned short* ys = (yrsame)? rs : y->s;
+ const unsigned short* 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);
+
+ unsigned short* rs = r->s;
+ const unsigned short* xs = (xrsame)? rs : x->s;
+ const unsigned short* topx = &(xs[BitStr_len(xl)]);
+ const unsigned short* ys = (yrsame)? rs : y->s;
+ const unsigned short* 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);
+ bit_transfer(r->s, 0, yl, r->s, xl);
+ }
+ else
+ {
+ BitStrRep* tmp = BStr_copy(0, y);
+ r = BStr_resize(r, rl);
+ bit_copy(x->s, r->s, xl);
+ bit_transfer(tmp->s, 0, yl, r->s, xl);
+ delete tmp;
+ }
+ }
+ else
+ {
+ r = BStr_resize(r, rl);
+ if (!xrsame) bit_copy(x->s, r->s, xl);
+ bit_transfer(y->s, 0, yl, r->s, xl);
+ }
+ 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) bit_copy(x->s, r->s, xl);
+ if (bit)
+ r->s[BitStr_index(xl)] |= (1 << (BitStr_pos(xl)));
+ else
+ r->s[BitStr_index(xl)] &= ~(1 << (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 unsigned short* xs = (xrsame)? r->s : x->s;
+ bit_transfer(xs, 0, xl, r->s, s);
+ bit_clear(r->s, s);
+ }
+ else if (xrsame)
+ {
+ r = BStr_resize(r, xl);
+ r->len = rl;
+ bit_transfer(r->s, -s, xl, r->s, 0);
+ }
+ else
+ {
+ r = BStr_resize(r, rl);
+ bit_transfer(x->s, -s, xl, r->s, 0);
+ }
+ 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)] |= (1 << (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)] |= (1 << (BitStr_pos(p)));
+ else
+ rep->s[BitStr_index(p)] &= ~(1 << (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)] &= ~(1 << (BitStr_pos(p)));
+}
+
+void BitString::clear()
+{
+ if (rep == &_nilBitStrRep) return;
+ bit_clear(rep->s, rep->len);
+}
+
+void BitString::set()
+{
+ if (rep == &_nilBitStrRep) return;
+ unsigned short* s = rep->s;
+ unsigned short* 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)] ^= (1 << (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);
+
+ int ind1 = BitStr_index(from);
+ int pos1 = BitStr_pos(from);
+ int ind2 = BitStr_index(to);
+ int pos2 = BitStr_pos(to);
+ unsigned short* s = &(rep->s[ind1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (ind2 == ind1)
+ *s |= m1 & m2;
+ else
+ {
+ *s++ |= m1;
+ unsigned short* top = &(rep->s[ind2]);
+ *top |= m2;
+ while (s < top)
+ *s++ = ONES;
+ }
+}
+
+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);
+
+ int ind1 = BitStr_index(from);
+ int pos1 = BitStr_pos(from);
+ int ind2 = BitStr_index(to);
+ int pos2 = BitStr_pos(to);
+ unsigned short* s = &(rep->s[ind1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (ind2 == ind1)
+ *s &= ~(m1 & m2);
+ else
+ {
+ *s++ &= ~m1;
+ unsigned short* top = &(rep->s[ind2]);
+ *top &= ~m2;
+ while (s < top)
+ *s++ = 0;
+ }
+}
+
+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);
+
+ int ind1 = BitStr_index(from);
+ int pos1 = BitStr_pos(from);
+ int ind2 = BitStr_index(to);
+ int pos2 = BitStr_pos(to);
+ unsigned short* s = &(rep->s[ind1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+ if (ind2 == ind1)
+ *s ^= m1 & m2;
+ else
+ {
+ *s++ ^= m1;
+ unsigned short* top = &(rep->s[ind2]);
+ *top ^= m2;
+ while (s < top)
+ {
+ unsigned short cmp = ~(*s);
+ *s++ = cmp;
+ }
+ }
+}
+
+
+int BitString::test(int from, int to) const
+{
+ if (from < 0 || from > to || (unsigned)(from) >= rep->len) return 0;
+
+ int ind1 = BitStr_index(from);
+ int pos1 = BitStr_pos(from);
+ int ind2 = BitStr_index(to);
+ int pos2 = BitStr_pos(to);
+
+ if ((unsigned)(to) >= rep->len)
+ {
+ ind2 = BitStr_index(rep->len - 1);
+ pos2 = BitStr_pos(rep->len - 1);
+ }
+
+ const unsigned short* s = &(rep->s[ind1]);
+ unsigned short m1 = lmask(pos1);
+ unsigned short m2 = rmask(pos2);
+
+ if (ind2 == ind1)
+ return (*s & m1 & m2) != 0;
+ else
+ {
+ if (*s++ & m1)
+ return 1;
+ unsigned short* top = &(rep->s[ind2]);
+ if (*top & m2)
+ return 1;
+ while (s < top)
+ if (*s++ != 0)
+ return 1;
+ return 0;
+ }
+}
+
+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 unsigned short* s = rep->s;
+ unsigned short 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 unsigned short* s = rep->s;
+
+ if ((unsigned)(p) >= rep->len)
+ {
+ ind = BitStr_index(rep->len - 1);
+ pos = BitStr_pos(rep->len - 1);
+ }
+
+ int j = ind;
+ unsigned short a = s[j];
+
+ int i = pos;
+ unsigned short maxbit = 1 << pos;
+
+ if (b != 0)
+ {
+ for (; i >= 0 && a != 0; --i)
+ {
+ if (a & maxbit)
+ return j * BITSTRBITS + i;
+ a <<= 1;
+ }
+ maxbit = 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 = 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 unsigned short* ys, int starty, int lengthy) const
+{
+ const unsigned short* 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);
+
+ unsigned short x = borrow_hi(xs, xind, rightxind, xpos);
+
+ int rightyind = BitStr_index(righty);
+ int rightypos = BitStr_pos(righty);
+ unsigned short y = borrow_hi(ys, yind, rightyind, ypos);
+ unsigned short 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;
+ unsigned short tx = borrow_hi(xs, xi, rightxind, xpos);
+ unsigned short 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);
+
+ unsigned short x = borrow_hi(xs, xind, rightxind, xpos);
+ unsigned short nextx = (xind >= rightxind) ? 0 : (xs[xind+1] >> xpos);
+
+ int rightyind = BitStr_index(righty);
+ int rightypos = BitStr_pos(righty);
+ unsigned short y = borrow_hi(ys, yind, rightyind, ypos);
+ unsigned short 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;
+ unsigned short tx = borrow_hi(xs, xi, rightxind, xpos);
+ unsigned short 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 unsigned short* xs, int startx, int lengthx) const
+{
+ const unsigned short* ys = pattern.rep->s;
+ const unsigned short* 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);
+
+ unsigned short x = safe_borrow_hi(xs, xind, rightxind, xpos);
+ unsigned short m = safe_borrow_hi(ms, 0, rightmind, 0);
+ unsigned short 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;
+ unsigned short tm = safe_borrow_hi(ms, yi, rightmind, 0);
+ unsigned short ty = safe_borrow_hi(ys, yi, rightyind, 0);
+ unsigned short 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);
+
+ unsigned short x = safe_borrow_hi(xs, xind, rightxind, xpos);
+ unsigned short m = safe_borrow_hi(ms, 0, rightmind, 0);
+ unsigned short y = safe_borrow_hi(ys, 0, rightyind, 0) & m;
+
+ unsigned short 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;
+ unsigned short tm = safe_borrow_hi(ms, yi, rightmind, 0);
+ unsigned short ty = safe_borrow_hi(ys, yi, rightyind, 0);
+ unsigned short 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 unsigned short* ys, int starty, int yl) const
+{
+ const unsigned short* 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 (;;)
+ {
+ unsigned short x = borrow_hi(xs, xi, rightxind, xpos);
+ unsigned short 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 unsigned short* xs, int startx,
+ int lengthx, int exact) const
+{
+ const unsigned short* ys = pattern.rep->s;
+ int righty = pattern.rep->len - 1;
+ unsigned short* 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(;;)
+ {
+ unsigned short m = safe_borrow_hi(ms, yind, rightmind, 0);
+ unsigned short x = safe_borrow_hi(xs, xind, rightxind, xpos) & m;
+ unsigned short y = safe_borrow_hi(ys, yind, rightyind, 0) & m;
+ if (x != y)
+ return 0;
+ else if (++yind > rightyind || ++xind > rightxind)
+ return 1;
+ }
+}
+
+void BitSubString::operator = (const BitString& y)
+{
+ if (&S == &_nil_BitString) return;
+ 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);
+ bit_transfer(oldtarg->s, 0, pos, targ->s, 0);
+ bit_transfer(y.rep->s, 0, ylen, targ->s, pos);
+ bit_transfer(oldtarg->s, pos+len, oldtarg->len, targ->s, pos + ylen);
+ delete oldtarg;
+ }
+ else if (len == ylen)
+ bit_transfer(y.rep->s, 0, len, targ->s, pos);
+ else if (ylen < len)
+ {
+ bit_transfer(y.rep->s, 0, ylen, targ->s, pos);
+ bit_transfer(targ->s, pos+len, targ->len, targ->s, pos + ylen);
+ targ->len = sl;
+ }
+ check_last(targ);
+ S.rep = targ;
+}
+
+void BitSubString::operator = (const BitSubString& y)
+{
+ if (&S == &_nil_BitString) return;
+ BitStrRep* targ = S.rep;
+
+ if (len == 0 || pos >= targ->len)
+ return;
+
+ 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);
+ bit_copy(oldtarg->s, targ->s, pos);
+ bit_transfer(y.S.rep->s, y.pos, y.pos+y.len, targ->s, pos);
+ bit_transfer(oldtarg->s, pos+len, oldtarg->len, targ->s, pos + y.len);
+ delete oldtarg;
+ }
+ else if (len == y.len)
+ bit_transfer(y.S.rep->s, y.pos, y.pos+y.len, targ->s, pos);
+ else if (y.len < len)
+ {
+ bit_transfer(y.S.rep->s, y.pos, y.pos+y.len, targ->s, pos);
+ bit_transfer(targ->s, pos+len, targ->len, targ->s, pos + y.len);
+ targ->len = sl;
+ }
+ check_last(targ);
+ S.rep = targ;
+}
+
+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(NO_NRV)
+
+BitString common_prefix(const BitString& x, const BitString& y, int startpos)
+ return 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;
+
+ const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
+ unsigned short a = *xs++;
+ unsigned int xp = startx;
+
+ const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
+ unsigned short b = *ys++;
+ unsigned int yp = starty;
+
+ for(; xp < xl && yp < yl; ++xp, ++yp)
+ {
+ unsigned short xbit = 1 << (BitStr_pos(xp));
+ unsigned short ybit = 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);
+}
+
+
+BitString common_suffix(const BitString& x, const BitString& y, int startpos)
+ return 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;
+
+ const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
+ unsigned short a = *xs--;
+ int xp = startx;
+
+ const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
+ unsigned short b = *ys--;
+ int yp = starty;
+
+ for(; xp >= 0 && yp >= 0; --xp, --yp)
+ {
+ unsigned short xbit = 1 << (BitStr_pos(xp));
+ unsigned short ybit = 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);
+}
+
+BitString reverse(const BitString& x) return r
+{
+ unsigned int yl = x.rep->len;
+ BitStrRep* y = BStr_resize(0, yl);
+ if (yl > 0)
+ {
+ const unsigned short* ls = x.rep->s;
+ unsigned short lm = 1;
+ unsigned short* rs = &(y->s[BitStr_index(yl - 1)]);
+ unsigned short rm = 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;
+}
+
+BitString atoBitString(const char* s, char f, char t) return res
+{
+ int sl = strlen(s);
+ BitStrRep* r = BStr_resize(0, sl);
+ if (sl != 0)
+ {
+ unsigned int rl = 0;
+ unsigned short* rs = r->s;
+ unsigned short a = 0;
+ unsigned short 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;
+}
+
+BitPattern atoBitPattern(const char* s, char f,char t,char x) return 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);
+ unsigned short* rs = r.pattern.rep->s;
+ unsigned short* ms = r.mask.rep->s;
+ unsigned short a = 0;
+ unsigned short b = 0;
+ unsigned short 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;
+}
+
+#else /* NO_NRV */
+
+BitString common_prefix(const BitString& x, const BitString& y, int startpos)
+{
+ BitString r;
+
+ unsigned int xl = x.rep->len;
+ unsigned int yl = y.rep->len;
+
+ int startx, starty;
+ if (startpos < 0)
+ {
+ startx = xl + startpos;
+ starty = yl + startpos;
+ }
+ else
+ startx = starty = startpos;
+
+ if (startx < 0 || startx >= xl || starty < 0 || starty >= yl)
+ return r;
+
+ const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
+ unsigned short a = *xs++;
+ int xp = startx;
+
+ const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
+ unsigned short b = *ys++;
+ int yp = starty;
+
+ for(; xp < xl && yp < yl; ++xp, ++yp)
+ {
+ unsigned short xbit = 1 << (BitStr_pos(xp));
+ unsigned short ybit = 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)
+{
+ BitString r;
+ unsigned int xl = x.rep->len;
+ unsigned int yl = y.rep->len;
+
+ int startx, starty;
+ if (startpos < 0)
+ {
+ startx = xl + startpos;
+ starty = yl + startpos;
+ }
+ else
+ startx = starty = startpos;
+
+ if (startx < 0 || startx >= xl || starty < 0 || starty >= yl)
+ return r;
+
+ const unsigned short* xs = &(x.rep->s[BitStr_index(startx)]);
+ unsigned short a = *xs--;
+ int xp = startx;
+
+ const unsigned short* ys = &(y.rep->s[BitStr_index(starty)]);
+ unsigned short b = *ys--;
+ int yp = starty;
+
+ for(; xp >= 0 && yp >= 0; --xp, --yp)
+ {
+ unsigned short xbit = 1 << (BitStr_pos(xp));
+ unsigned short ybit = 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)
+{
+ BitString r;
+ unsigned int yl = x.rep->len;
+ BitStrRep* y = BStr_resize(0, yl);
+ if (yl > 0)
+ {
+ const unsigned short* ls = x.rep->s;
+ unsigned short lm = 1;
+ unsigned short* rs = &(y->s[BitStr_index(yl - 1)]);
+ unsigned short rm = 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)
+{
+ BitString res;
+ int sl = strlen(s);
+ BitStrRep* r = BStr_resize(0, sl);
+ if (sl != 0)
+ {
+ unsigned int rl = 0;
+ unsigned short* rs = r->s;
+ unsigned short a = 0;
+ unsigned short 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)
+{
+ 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);
+ unsigned short* rs = r.pattern.rep->s;
+ unsigned short* ms = r.mask.rep->s;
+ unsigned short a = 0;
+ unsigned short b = 0;
+ unsigned short 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;
+}
+
+#endif
+
+extern AllocRing _libgxx_fmtq;
+
+void BitString::printon(ostream& os, char f, char t) const
+{
+ unsigned int xl = rep->len;
+ const unsigned short* ptr = rep->s;
+ register streambuf *sb = os.rdbuf();
+ unsigned short 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 unsigned short* ps = pattern.rep->s;
+ const unsigned short* ms = mask.rep->s;
+ unsigned short a = 0;
+ unsigned short 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++/g++-include/BitString.h b/gnu/lib/libg++/g++-include/BitString.h
new file mode 100644
index 00000000000..cc08b9f92b0
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/BitString.h
@@ -0,0 +1,759 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: BitString.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#ifndef _BitString_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#define _BitString_h 1
+
+#include <stream.h>
+#include <limits.h>
+
+#define BITSTRBITS (sizeof(short) * CHAR_BIT)
+
+struct BitStrRep
+{
+ unsigned int len; // length in bits
+ unsigned short sz; // allocated slots
+ unsigned short s[1]; // bits start here
+};
+
+extern BitStrRep* BStr_alloc(BitStrRep*, const unsigned short*, 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();
+
+ void operator = (const BitString&);
+ void 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 unsigned short*, int, int) const;
+ int match(int, int, int, const unsigned short*,int,int) const;
+ BitSubString _substr(int first, int l);
+
+public:
+
+// constructors
+ BitString();
+ BitString(const BitString&);
+ BitString(const BitSubString& y);
+
+ ~BitString();
+
+ void operator = (unsigned int bit);
+ void operator = (const BitString& y);
+ void 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
+
+ void operator |= (const BitString&);
+ void operator &= (const BitString&);
+ void operator -= (const BitString&);
+ void operator ^= (const BitString&);
+ void operator += (const BitString&);
+ void operator += (unsigned int b);
+ void operator <<=(int s);
+ void 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 unsigned short*, int, int) const;
+ int match(const unsigned short* 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;
+}
+
+#if defined(__GNUG__) && !defined(NO_NRV)
+
+inline BitString shorttoBitString(unsigned short w) return r
+{
+ r.rep = BStr_alloc(0, &w, 0, BITSTRBITS, BITSTRBITS);
+}
+
+inline BitString longtoBitString(unsigned long w) return r
+{
+ 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);
+}
+
+#else
+
+inline BitString shorttoBitString(unsigned short w)
+{
+ BitString r; r.rep = BStr_alloc(0, &w, 0, BITSTRBITS, BITSTRBITS); return r;
+}
+
+inline BitString longtoBitString(unsigned long w)
+{
+ BitString r;
+ 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);
+ return r;
+}
+
+#endif
+
+inline void BitString::operator = (const BitString& y)
+{
+ rep = BStr_copy(rep, y.rep);
+}
+
+inline void BitString::operator = (unsigned int b)
+{
+ unsigned short bit = b;
+ rep = BStr_alloc(rep, &bit, 0, 1, 1);
+}
+
+inline void BitString::operator=(const BitSubString& y)
+{
+ rep = BStr_alloc(rep, y.S.rep->s, y.pos, y.pos+y.len, y.len);
+}
+
+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 void BitString::operator &= (const BitString& y)
+{
+ and(*this, y, *this);
+}
+
+
+inline void BitString::operator |= (const BitString& y)
+{
+ or(*this, y, *this);
+}
+
+inline void BitString::operator ^= (const BitString& y)
+{
+ xor(*this, y, *this);
+}
+
+inline void BitString::operator <<= (int y)
+{
+ lshift(*this, y, *this);
+}
+
+inline void BitString::operator >>= (int y)
+{
+ rshift(*this, y, *this);
+}
+
+inline void BitString::operator -= (const BitString& y)
+{
+ diff(*this, y, *this);
+}
+
+inline void BitString::operator += (const BitString& y)
+{
+ cat(*this, y, *this);
+}
+
+inline void BitString::operator += (unsigned int y)
+{
+ cat(*this, y, *this);
+}
+
+inline void BitString::complement()
+{
+ ::complement(*this, *this);
+}
+
+#if defined(__GNUG__) && !defined(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++/g++-include/Complex.cc b/gnu/lib/libg++/g++-include/Complex.cc
new file mode 100644
index 00000000000..c1fb0fda71b
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Complex.cc
@@ -0,0 +1,262 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Complex.h>
+#include <std.h>
+#include <builtin.h>
+
+// error handling
+
+void default_Complex_error_handler(const char* msg)
+{
+ cerr << "Fatal Complex arithmetic error. " << msg << "\n";
+ exit(1);
+}
+
+one_arg_error_handler_t Complex_error_handler = default_Complex_error_handler;
+
+one_arg_error_handler_t set_Complex_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = Complex_error_handler;
+ Complex_error_handler = f;
+ return old;
+}
+
+void Complex::error(const char* msg) const
+{
+ (*Complex_error_handler)(msg);
+}
+
+/* from romine@xagsun.epm.ornl.gov */
+Complex /* const */ operator / (const Complex& x, const Complex& y)
+{
+ double den = fabs(y.real()) + fabs(y.imag());
+ if (den == 0.0) x.error ("Attempted division by zero.");
+ double xrden = x.real() / den;
+ double xiden = x.imag() / den;
+ double yrden = y.real() / den;
+ double yiden = y.imag() / den;
+ double nrm = yrden * yrden + yiden * yiden;
+ return Complex((xrden * yrden + xiden * yiden) / nrm,
+ (xiden * yrden - xrden * yiden) / nrm);
+}
+
+Complex& Complex::operator /= (const Complex& y)
+{
+ double den = fabs(y.real()) + fabs(y.imag());
+ if (den == 0.0) error ("Attempted division by zero.");
+ double xrden = re / den;
+ double xiden = im / den;
+ double yrden = y.real() / den;
+ double yiden = y.imag() / den;
+ double nrm = yrden * yrden + yiden * yiden;
+ re = (xrden * yrden + xiden * yiden) / nrm;
+ im = (xiden * yrden - xrden * yiden) / nrm;
+ return *this;
+}
+
+Complex /* const */ operator / (double x, const Complex& y)
+{
+ double den = norm(y);
+ if (den == 0.0) y.error ("Attempted division by zero.");
+ return Complex((x * y.real()) / den, -(x * y.imag()) / den);
+}
+
+Complex /* const */ operator / (const Complex& x, double y)
+{
+ if (y == 0.0) x.error ("Attempted division by zero.");
+ return Complex(x.real() / y, x.imag() / y);
+}
+
+
+Complex& Complex::operator /= (double y)
+{
+ if (y == 0.0) error ("Attempted division by zero.");
+ re /= y; im /= y;
+ return *this;
+}
+
+
+Complex /* const */ exp(const Complex& x)
+{
+ double r = exp(x.real());
+ return Complex(r * cos(x.imag()),
+ r * sin(x.imag()));
+}
+
+Complex /* const */ cosh(const Complex& x)
+{
+ return Complex(cos(x.imag()) * cosh(x.real()),
+ sin(x.imag()) * sinh(x.real()));
+}
+
+Complex /* const */ sinh(const Complex& x)
+{
+ return Complex(cos(x.imag()) * sinh(x.real()),
+ sin(x.imag()) * cosh(x.real()));
+}
+
+Complex /* const */ cos(const Complex& x)
+{
+ return Complex(cos(x.real()) * cosh(x.imag()),
+ -sin(x.real()) * sinh(x.imag()));
+}
+
+Complex /* const */ sin(const Complex& x)
+{
+ return Complex(sin(x.real()) * cosh(x.imag()),
+ cos(x.real()) * sinh(x.imag()));
+}
+
+Complex /* const */ log(const Complex& x)
+{
+ double h = hypot(x.real(), x.imag());
+ if (h <= 0.0) x.error("attempted log of zero magnitude number.");
+ return Complex(log(h), atan2(x.imag(), x.real()));
+}
+
+// Corrections based on reports from: thc@cs.brown.edu & saito@sdr.slb.com
+Complex /* const */ pow(const Complex& x, const Complex& p)
+{
+ double h = hypot(x.real(), x.imag());
+ if (h <= 0.0) x.error("attempted power of zero magnitude number.");
+
+ double a = atan2(x.imag(), x.real());
+ double lr = pow(h, p.real());
+ double li = p.real() * a;
+ if (p.imag() != 0.0)
+ {
+ lr /= exp(p.imag() * a);
+ li += p.imag() * log(h);
+ }
+ return Complex(lr * cos(li), lr * sin(li));
+}
+
+Complex /* const */ pow(const Complex& x, double p)
+{
+ double h = hypot(x.real(), x.imag());
+ if (h <= 0.0) x.error("attempted power of zero magnitude number.");
+ double lr = pow(h, p);
+ double a = atan2(x.imag(), x.real());
+ double li = p * a;
+ return Complex(lr * cos(li), lr * sin(li));
+}
+
+
+Complex /* const */ sqrt(const Complex& x)
+{
+ if (x.real() == 0.0 && x.imag() == 0.0)
+ return Complex(0.0, 0.0);
+ else
+ {
+ double s = sqrt((fabs(x.real()) + hypot(x.real(), x.imag())) * 0.5);
+ double d = (x.imag() / s) * 0.5;
+ if (x.real() > 0.0)
+ return Complex(s, d);
+ else if (x.imag() >= 0.0)
+ return Complex(d, s);
+ else
+ return Complex(-d, -s);
+ }
+}
+
+
+Complex /* const */ pow(const Complex& x, int p)
+{
+ if (p == 0)
+ return Complex(1.0, 0.0);
+ else if (x == 0.0)
+ return Complex(0.0, 0.0);
+ else
+ {
+ Complex res(1.0, 0.0);
+ Complex b = x;
+ if (p < 0)
+ {
+ p = -p;
+ b = 1.0 / b;
+ }
+ for(;;)
+ {
+ if (p & 1)
+ res *= b;
+ if ((p >>= 1) == 0)
+ return res;
+ else
+ b *= b;
+ }
+ }
+}
+
+ostream& operator << (ostream& s, const Complex& x)
+{
+ return s << "(" << x.real() << ", " << x.imag() << ")" ;
+}
+
+istream& operator >> (istream& s, Complex& x)
+{
+#ifdef _OLD_STREAMS
+ if (!s.good())
+ {
+ return s;
+ }
+#else
+ if (!s.ipfx(0))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+#endif
+ double r, i;
+ char ch;
+ s >> ws;
+ s.get(ch);
+ if (ch == '(')
+ {
+ s >> r;
+ s >> ws;
+ s.get(ch);
+ if (ch == ',')
+ {
+ s >> i;
+ s >> ws;
+ s .get(ch);
+ }
+ else
+ i = 0;
+ if (ch != ')')
+ s.clear(ios::failbit);
+ }
+ else
+ {
+ s.putback(ch);
+ s >> r;
+ i = 0;
+ }
+ x = Complex(r, i);
+ return s;
+}
+
+Complex operator * (const Complex& x, const Complex& y)
+{
+ return Complex(x.real() * y.real() - x.imag() * y.imag(),
+ x.real() * y.imag() + x.imag() * y.real());
+}
+
diff --git a/gnu/lib/libg++/g++-include/Complex.h b/gnu/lib/libg++/g++-include/Complex.h
new file mode 100644
index 00000000000..fa28a929d47
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Complex.h
@@ -0,0 +1,272 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Complex.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#ifndef _Complex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Complex_h 1
+
+
+#include <iostream.h>
+#include <math.h>
+
+class Complex
+{
+#ifdef __ATT_complex__
+public:
+#else
+protected:
+#endif
+
+ double re;
+ double im;
+
+public:
+
+ double real() const;
+ double imag() const;
+
+ Complex();
+ Complex(const Complex& y);
+ Complex(double r, double i=0);
+
+ ~Complex();
+
+ Complex& operator = (const Complex& y);
+
+ Complex& operator += (const Complex& y);
+ Complex& operator += (double y);
+ Complex& operator -= (const Complex& y);
+ Complex& operator -= (double y);
+ Complex& operator *= (const Complex& y);
+ Complex& operator *= (double y);
+
+ Complex& operator /= (const Complex& y);
+ Complex& operator /= (double y);
+
+ void error(const char* msg) const;
+};
+
+
+// non-inline functions
+
+Complex operator / (const Complex& x, const Complex& y);
+Complex operator / (const Complex& x, double y);
+Complex operator / (double x, const Complex& y);
+
+Complex cos(const Complex& x);
+Complex sin(const Complex& x);
+
+Complex cosh(const Complex& x);
+Complex sinh(const Complex& x);
+
+Complex exp(const Complex& x);
+Complex log(const Complex& x);
+
+Complex pow(const Complex& x, int p);
+Complex pow(const Complex& x, const Complex& p);
+Complex pow(const Complex& x, double y);
+Complex sqrt(const Complex& x);
+
+istream& operator >> (istream& s, Complex& x);
+ostream& operator << (ostream& s, const Complex& x);
+
+// other functions defined as inlines
+
+int operator == (const Complex& x, const Complex& y);
+int operator == (const Complex& x, double y);
+int operator != (const Complex& x, const Complex& y);
+int operator != (const Complex& x, double y);
+
+Complex operator - (const Complex& x);
+Complex conj(const Complex& x);
+Complex operator + (const Complex& x, const Complex& y);
+Complex operator + (const Complex& x, double y);
+Complex operator + (double x, const Complex& y);
+Complex operator - (const Complex& x, const Complex& y);
+Complex operator - (const Complex& x, double y);
+Complex operator - (double x, const Complex& y);
+Complex operator * (const Complex& x, const Complex& y);
+Complex operator * (const Complex& x, double y);
+Complex operator * (double x, const Complex& y);
+
+double real(const Complex& x);
+double imag(const Complex& x);
+double abs(const Complex& x);
+double norm(const Complex& x);
+double arg(const Complex& x);
+
+Complex polar(double r, double t = 0.0);
+
+
+// inline members
+
+inline double Complex::real() const { return re; }
+inline double Complex::imag() const { return im; }
+
+inline Complex::Complex() {}
+inline Complex::Complex(const Complex& y) :re(y.real()), im(y.imag()) {}
+inline Complex::Complex(double r, double i) :re(r), im(i) {}
+
+inline Complex::~Complex() {}
+
+inline Complex& Complex::operator = (const Complex& y)
+{
+ re = y.real(); im = y.imag(); return *this;
+}
+
+inline Complex& Complex::operator += (const Complex& y)
+{
+ re += y.real(); im += y.imag(); return *this;
+}
+
+inline Complex& Complex::operator += (double y)
+{
+ re += y; return *this;
+}
+
+inline Complex& Complex::operator -= (const Complex& y)
+{
+ re -= y.real(); im -= y.imag(); return *this;
+}
+
+inline Complex& Complex::operator -= (double y)
+{
+ re -= y; return *this;
+}
+
+inline Complex& Complex::operator *= (const Complex& y)
+{
+ double r = re * y.real() - im * y.imag();
+ im = re * y.imag() + im * y.real();
+ re = r;
+ return *this;
+}
+
+inline Complex& Complex::operator *= (double y)
+{
+ re *= y; im *= y; return *this;
+}
+
+
+// functions
+
+inline int operator == (const Complex& x, const Complex& y)
+{
+ return x.real() == y.real() && x.imag() == y.imag();
+}
+
+inline int operator == (const Complex& x, double y)
+{
+ return x.imag() == 0.0 && x.real() == y;
+}
+
+inline int operator != (const Complex& x, const Complex& y)
+{
+ return x.real() != y.real() || x.imag() != y.imag();
+}
+
+inline int operator != (const Complex& x, double y)
+{
+ return x.imag() != 0.0 || x.real() != y;
+}
+
+inline Complex operator - (const Complex& x)
+{
+ return Complex(-x.real(), -x.imag());
+}
+
+inline Complex conj(const Complex& x)
+{
+ return Complex(x.real(), -x.imag());
+}
+
+inline Complex operator + (const Complex& x, const Complex& y)
+{
+ return Complex(x.real() + y.real(), x.imag() + y.imag());
+}
+
+inline Complex operator + (const Complex& x, double y)
+{
+ return Complex(x.real() + y, x.imag());
+}
+
+inline Complex operator + (double x, const Complex& y)
+{
+ return Complex(x + y.real(), y.imag());
+}
+
+inline Complex operator - (const Complex& x, const Complex& y)
+{
+ return Complex(x.real() - y.real(), x.imag() - y.imag());
+}
+
+inline Complex operator - (const Complex& x, double y)
+{
+ return Complex(x.real() - y, x.imag());
+}
+
+inline Complex operator - (double x, const Complex& y)
+{
+ return Complex(x - y.real(), -y.imag());
+}
+
+inline Complex operator * (const Complex& x, double y)
+{
+ return Complex(x.real() * y, x.imag() * y);
+}
+
+inline Complex operator * (double x, const Complex& y)
+{
+ return Complex(x * y.real(), x * y.imag());
+}
+
+inline double real(const Complex& x)
+{
+ return x.real();
+}
+
+inline double imag(const Complex& x)
+{
+ return x.imag();
+}
+
+inline double abs(const Complex& x)
+{
+ return hypot(x.real(), x.imag());
+}
+
+inline double norm(const Complex& x)
+{
+ return (x.real() * x.real() + x.imag() * x.imag());
+}
+
+inline double arg(const Complex& x)
+{
+ return atan2(x.imag(), x.real());
+}
+
+inline Complex polar(double r, double t)
+{
+ return Complex(r * cos(t), r * sin(t));
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/CursesW.cc b/gnu/lib/libg++/g++-include/CursesW.cc
new file mode 100644
index 00000000000..9533f691556
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/CursesW.cc
@@ -0,0 +1,255 @@
+/*
+Copyright (C) 1989, 1992 Free Software Foundation
+ written by Eric Newton (newton@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <builtin.h>
+#include <values.h>
+#ifndef _OLD_STREAMS
+#include <strstream.h>
+//#include <ioprivate.h>
+#endif
+// Include CurseW.h and/or curses.h *after* iostream includes,
+// because curses.h defines a clear macro that conflicts with iostream. Sigh.
+#include <CursesW.h>
+
+#if _G_HAVE_CURSES
+
+int CursesWindow::count = 0;
+
+/*
+ * C++ interface to curses library.
+ *
+ */
+
+#if !defined(_IO_MAGIC) && !defined(HAVE_VSCANF) &&!defined vsscanf
+extern "C" int _doscan(FILE *, const char*, va_list args);
+
+static int vsscanf(char *buf, const char * fmt, va_list args)
+{
+ FILE b;
+#ifdef _IOSTRG
+ b._flag = _IOREAD|_IOSTRG;
+#else
+ b._flag = _IOREAD;
+#endif
+ b._base = (unsigned char*)buf;
+ b._ptr = (unsigned char*)buf;
+ b._cnt = BUFSIZ;
+ return _doscan(&b, fmt, args);
+}
+#endif
+
+/*
+ * varargs functions are handled conservatively:
+ * They interface directly into the underlying
+ * _doscan, _doprnt and/or vfprintf routines rather than
+ * assume that such things are handled compatibly in the curses library
+ */
+
+int CursesWindow::scanw(const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#ifdef VMS
+ int result = wscanw(w , fmt , args);
+#else /* NOT VMS */
+ char buf[BUFSIZ];
+ int result = wgetstr(w, buf);
+ if (result == OK) {
+
+#ifdef _IO_MAGIC /* GNU iostreams */
+ strstreambuf ss(buf, BUFSIZ);
+ result = ss.vscan(fmt, args);
+#else
+ result = vsscanf(buf, fmt, args);
+#endif
+ }
+#endif /* !VMS */
+ va_end(args);
+ return result;
+}
+
+int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buf[BUFSIZ];
+ int result = wmove(w, y, x);
+ if (result == OK)
+#ifdef VMS
+ result=wscanw(w , fmt , args);
+#else /* !VMS */
+ {
+ result = wgetstr(w, buf);
+ if (result == OK) {
+#ifdef _IO_MAGIC /* GNU iostreams */
+ strstreambuf ss(buf, BUFSIZ);
+ result = ss.vscan(fmt, args);
+#else
+ result = vsscanf(buf, fmt, args);
+#endif
+ }
+ }
+#endif /* !VMS */
+ va_end(args);
+ return result;
+}
+
+int CursesWindow::printw(const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buf[BUFSIZ];
+ vsprintf(buf, fmt, args);
+ va_end(args);
+ return waddstr(w, buf);
+}
+
+
+int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ int result = wmove(w, y, x);
+ if (result == OK)
+ {
+ char buf[BUFSIZ];
+ vsprintf(buf, fmt, args);
+ result = waddstr(w, buf);
+ }
+ va_end(args);
+ return result;
+}
+
+CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
+{
+ if (count==0)
+ initscr();
+
+ w = newwin(lines, cols, begin_y, begin_x);
+ if (w == 0)
+ {
+ (*lib_error_handler)("CursesWindow", "Cannot construct window");
+ }
+
+ alloced = 1;
+ subwins = par = sib = 0;
+ count++;
+}
+
+CursesWindow::CursesWindow(WINDOW* &window)
+{
+ if (count==0)
+ initscr();
+
+ w = window;
+ alloced = 0;
+ subwins = par = sib = 0;
+ count++;
+}
+
+CursesWindow::CursesWindow(CursesWindow& win, int l, int c,
+ int by, int bx, char absrel)
+{
+
+ if (absrel == 'r') // relative origin
+ {
+ by += win.begy();
+ bx += win.begx();
+ }
+
+ // Even though we treat subwindows as a tree, the standard curses
+ // library needs the `subwin' call to link to the root in
+ // order to correctly perform refreshes, etc.
+
+ CursesWindow* root = &win;
+ while (root->par != 0) root = root->par;
+
+ w = subwin(root->w, l, c, by, bx);
+ if (w == 0)
+ {
+ (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
+ }
+
+ par = &win;
+ sib = win.subwins;
+ win.subwins = this;
+ subwins = 0;
+ alloced = 1;
+ count++;
+}
+
+
+void CursesWindow::kill_subwindows()
+{
+ for (CursesWindow* p = subwins; p != 0; p = p->sib)
+ {
+ p->kill_subwindows();
+ if (p->alloced)
+ {
+ if (p->w != 0)
+ ::delwin(p->w);
+ p->alloced = 0;
+ }
+ p->w = 0; // cause a run-time error if anyone attempts to use...
+ }
+}
+
+CursesWindow::~CursesWindow()
+{
+ kill_subwindows();
+
+ if (par != 0) // Snip us from the parent's list of subwindows.
+ {
+ CursesWindow * win = par->subwins;
+ CursesWindow * trail = 0;
+ for (;;)
+ {
+ if (win == 0)
+ break;
+ else if (win == this)
+ {
+ if (trail != 0)
+ trail->sib = win->sib;
+ else
+ par->subwins = win->sib;
+ break;
+ }
+ else
+ {
+ trail = win;
+ win = win->sib;
+ }
+ }
+ }
+
+ if (alloced && w != 0)
+ delwin(w);
+
+ --count;
+ if (count == 0)
+ endwin();
+ else if (count < 0) // cannot happen!
+ {
+ (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
+ }
+}
+
+#endif /* _G_HAVE_CURSES */
diff --git a/gnu/lib/libg++/g++-include/CursesW.h b/gnu/lib/libg++/g++-include/CursesW.h
new file mode 100644
index 00000000000..ec378a3a424
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/CursesW.h
@@ -0,0 +1,581 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Eric Newton (newton@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: CursesW.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#ifndef _CursesWindow_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _CursesWindow_h
+
+#include <_G_config.h>
+#if _G_HAVE_CURSES
+#include <curses.h>
+
+/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro.
+ Undefine it here, because CursesWindow uses lines as a method. */
+#undef lines
+
+// "Convert" macros to inlines, if needed.
+#ifdef addch
+inline int (addch)(char ch) { return addch(ch); }
+#undef addch
+#endif
+#ifdef addstr
+/* The (char*) cast is to hack around missing const's */
+inline int (addstr)(const char * str) { return addstr((char*)str); }
+#undef addstr
+#endif
+#ifdef clear
+inline int (clear)() { return clear(); }
+#undef clear
+#endif
+#ifdef clearok
+inline int (clearok)(WINDOW* win, int bf) { return clearok(win, bf); }
+#undef clearok
+#else
+extern "C" int clearok(WINDOW*, int);
+#endif
+#ifdef clrtobot
+inline int (clrtobot)() { return clrtobot(); }
+#undef clrtobot
+#endif
+#ifdef clrtoeol
+inline int (clrtoeol)() { return clrtoeol(); }
+#undef clrtoeol
+#endif
+#ifdef delch
+inline int (delch)() { return delch(); }
+#undef delch
+#endif
+#ifdef deleteln
+inline int (deleteln)() { return deleteln(); }
+#undef deleteln
+#endif
+#ifdef erase
+inline int (erase)() { return erase(); }
+#undef erase
+#endif
+#ifdef flushok
+inline int (flushok)(WINDOW* _win, int _bf) { return flushok(_win, _bf); }
+#undef flushok
+#else
+#define _no_flushok
+#endif
+#ifdef getch
+inline int (getch)() { return getch(); }
+#undef getch
+#endif
+#ifdef getstr
+inline int (getstr)(char *_str) { return getstr(_str); }
+#undef getstr
+#endif
+#ifdef getyx
+inline void (getyx)(WINDOW* win, int& y, int& x) { getyx(win, y, x); }
+#undef getyx
+#endif
+#ifdef inch
+inline int (inch)() { return inch(); }
+#undef inch
+#endif
+#ifdef insch
+inline int (insch)(char c) { return insch(c); }
+#undef insch
+#endif
+#ifdef insertln
+inline int (insertln)() { return insertln(); }
+#undef insertln
+#endif
+#ifdef leaveok
+inline int (leaveok)(WINDOW* win, int bf) { return leaveok(win, bf); }
+#undef leaveok
+#else
+extern "C" int leaveok(WINDOW* win, int bf);
+#endif
+#ifdef move
+inline int (move)(int x, int y) { return move(x, y); }
+#undef move
+#endif
+#ifdef refresh
+inline int (rfresh)() { return refresh(); }
+#undef refresh
+#endif
+#ifdef scrollok
+inline int (scrollok)(WINDOW* win, int bf) { return scrollok(win, bf); }
+#undef scrollok
+#else
+#ifndef hpux
+extern "C" int scrollok(WINDOW*, int);
+#else
+extern "C" int scrollok(WINDOW*, char);
+#endif
+#endif
+#ifdef standend
+inline int (standend)() { return standend(); }
+#undef standend
+#endif
+#ifdef standout
+inline int (standout)() { return standout(); }
+#undef standout
+#endif
+#ifdef wstandend
+inline int (wstandend)(WINDOW *win) { return wstandend(win); }
+#undef wstandend
+#endif
+#ifdef wstandout
+inline int (wstandout)(WINDOW *win) { return wstandout(win); }
+#undef wstandout
+#endif
+#ifdef wattrset
+inline int (wattrset)(WINDOW *win, int att) { return wattrset(win, att); }
+#undef wattrset
+#endif
+#ifdef winch
+inline int (winch)(WINDOW* win) { return winch(win); }
+#undef winch
+#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++/g++-include/DLList.cc b/gnu/lib/libg++/g++-include/DLList.cc
new file mode 100644
index 00000000000..25c0be4e549
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/DLList.cc
@@ -0,0 +1,327 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _G_NO_TEMPLATES
+#ifdef __GNUG__
+//#pragma implementation
+#endif
+#include <values.h>
+#include <stream.h>
+#include <builtin.h>
+#include "DLList.h"
+
+void BaseDLList::error(const char* msg)
+{
+ (*lib_error_handler)("DLList", msg);
+}
+
+int BaseDLList::length()
+{
+ 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(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(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, 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, void *datum)
+{
+ if (p == 0) error("null Pix");
+ BaseDLNode* u = (BaseDLNode*) p;
+ BaseDLNode* t = copy_node(datum);
+ t->bk = u->bk;
+ t->fd = u;
+ u->bk->fd = t;
+ u->bk = t;
+ if (u == h) h = t;
+ return Pix(t);
+}
+
+void BaseDLList::join(BaseDLList& b)
+{
+ BaseDLNode* t = b.h;
+ b.h = 0;
+ if (h == 0)
+ h = t;
+ else if (t != 0)
+ {
+ BaseDLNode* l = t->bk;
+ h->bk->fd = t;
+ t->bk = h->bk;
+ h->bk = l;
+ l->fd = h;
+ }
+}
+
+int BaseDLList::owns(Pix p)
+{
+ BaseDLNode* t = h;
+ if (t != 0 && p != 0)
+ {
+ do
+ {
+ if (Pix(t) == p) return 1;
+ t = t->fd;
+ } while (t != h);
+ }
+ return 0;
+}
+
+void BaseDLList::del(Pix& p, int dir)
+{
+ if (p == 0) error("null Pix");
+ BaseDLNode* t = (BaseDLNode*) p;
+ if (t->fd == t)
+ {
+ h = 0;
+ p = 0;
+ }
+ else
+ {
+ if (dir < 0)
+ {
+ if (t == h)
+ p = 0;
+ else
+ p = Pix(t->bk);
+ }
+ else
+ {
+ if (t == h->bk)
+ p = 0;
+ else
+ p = Pix(t->fd);
+ }
+ t->bk->fd = t->fd;
+ t->fd->bk = t->bk;
+ if (t == h) h = t->fd;
+ }
+ delete t;
+}
+
+void BaseDLList::del_after(Pix& p)
+{
+ if (p == 0)
+ {
+ del_front();
+ return;
+ }
+
+ BaseDLNode* b = (BaseDLNode*) p;
+ BaseDLNode* t = b->fd;
+
+ if (b == t)
+ {
+ h = 0;
+ p = 0;
+ }
+ else
+ {
+ t->bk->fd = t->fd;
+ t->fd->bk = t->bk;
+ if (t == h) h = t->fd;
+ }
+ delete_node(t);
+}
+
+void BaseDLList::remove_front(void *dst)
+{
+ if (h == 0)
+ error("remove_front of empty list");
+ else {
+ BaseDLNode* t = h;
+ copy_item(dst, t->item());
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ h->fd->bk = h->bk;
+ h->bk->fd = h->fd;
+ h = h->fd;
+ }
+ delete_node(t);
+ }
+}
+
+void BaseDLList::del_front()
+{
+ if (h == 0)
+ error("del_front of empty list");
+ BaseDLNode* t = h;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ h->fd->bk = h->bk;
+ h->bk->fd = h->fd;
+ h = h->fd;
+ }
+ delete_node(t);
+}
+
+void BaseDLList::remove_rear(void *dst)
+{
+ if (h == 0)
+ error("remove_rear of empty list");
+ else
+ {
+ BaseDLNode* t = h->bk;
+ copy_item(dst, t->item());
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ t->fd->bk = t->bk;
+ t->bk->fd = t->fd;
+ }
+ delete_node(t);
+ }
+}
+
+void BaseDLList::del_rear()
+{
+ if (h == 0)
+ error("del_rear of empty list");
+ BaseDLNode* t = h->bk;
+ if (h->fd == h)
+ h = 0;
+ else
+ {
+ t->fd->bk = t->bk;
+ t->bk->fd = t->fd;
+ }
+ delete_node(t);
+}
+
+
+int BaseDLList::OK()
+{
+ int v = 1;
+ if (h != 0)
+ {
+ BaseDLNode* t = h;
+ long count = MAXLONG; // 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++/g++-include/DLList.h b/gnu/lib/libg++/g++-include/DLList.h
new file mode 100644
index 00000000000..80fe64359d1
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/DLList.h
@@ -0,0 +1,125 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: DLList.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#ifndef _DLList_h
+#ifdef __GNUG__
+//#pragma interface
+#endif
+#define _DLList_h 1
+
+#include <Pix.h>
+
+struct BaseDLNode {
+ BaseDLNode *bk;
+ BaseDLNode *fd;
+ void *item() {return (void*)(this+1);} //Return ((DLNode<T>*)this)->hd
+};
+
+template<class T>
+class DLNode : public BaseDLNode
+{
+ public:
+ T hd;
+ DLNode() { }
+ DLNode(const T& h, DLNode* p = 0, DLNode* n = 0)
+ : hd(h) { bk = p; fd = n; }
+ ~DLNode() { }
+};
+
+class BaseDLList {
+ protected:
+ BaseDLNode *h;
+
+ BaseDLList() { h = 0; }
+ void copy(const BaseDLList&);
+ BaseDLList& operator= (const BaseDLList& a);
+ virtual void delete_node(BaseDLNode*node) = 0;
+ virtual BaseDLNode* copy_node(void* datum) = 0;
+ virtual void copy_item(void *dst, void *src) = 0;
+ virtual ~BaseDLList() { }
+
+ Pix prepend(void*);
+ Pix append(void*);
+ Pix ins_after(Pix p, void *datum);
+ Pix ins_before(Pix p, void *datum);
+ void remove_front(void *dst);
+ void remove_rear(void *dst);
+ void join(BaseDLList&);
+
+ public:
+ int empty() { return h == 0; }
+ int length();
+ void clear();
+ void error(const char* msg);
+ int owns(Pix p);
+ int OK();
+ void del(Pix& p, int dir = 1);
+ void del_after(Pix& p);
+ void del_front();
+ void del_rear();
+};
+
+template <class T>
+class DLList : public BaseDLList {
+ //friend class <T>DLListTrav;
+
+ virtual void delete_node(BaseDLNode *node) { delete (DLNode<T>*)node; }
+ virtual BaseDLNode* copy_node(void *datum)
+ { return new DLNode<T>(*(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(T& item) {return BaseDLList::prepend(&item);}
+ Pix append(T& item) {return BaseDLList::append(&item);}
+
+ void join(DLList<T>& a) { BaseDLList::join(a); }
+
+ T& front() {
+ if (h == 0) error("front: empty list");
+ return ((DLNode<T>*)h)->hd; }
+ T& rear() {
+ if (h == 0) error("rear: empty list");
+ return ((DLNode<T>*)h->bk)->hd;
+ }
+ T remove_front() { T dst; BaseDLList::remove_front(&dst); return dst; }
+ T remove_rear() { T dst; BaseDLList::remove_rear(&dst); return dst; }
+
+ T& operator () (Pix p) {
+ if (p == 0) error("null Pix");
+ return ((DLNode<T>*)p)->hd;
+ }
+ Pix first() { return Pix(h); }
+ Pix last() { return (h == 0)? 0 : Pix(h->bk); }
+ void next(Pix& p)
+ { p = (p == 0 || p == h->bk)? 0 : Pix(((DLNode<T>*)p)->fd); }
+ void prev(Pix& p)
+ { p = (p == 0 || p == h)? 0 : Pix(((DLNode<T>*)p)->bk); }
+ Pix ins_after(Pix p, T& item) {return BaseDLList::ins_after(p, &item); }
+ Pix ins_before(Pix p, T& item) {return BaseDLList::ins_before(p, &item);}
+};
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/DiscUnif.cc b/gnu/lib/libg++/g++-include/DiscUnif.cc
new file mode 100644
index 00000000000..136ad11aba2
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/DiscUnif.cc
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <DiscUnif.h>
+
+double DiscreteUniform::operator()()
+{
+ long tmp = long(floor(delta * pGenerator -> asDouble()));
+ return( double(pLow + tmp) );
+}
+
diff --git a/gnu/lib/libg++/g++-include/DiscUnif.h b/gnu/lib/libg++/g++-include/DiscUnif.h
new file mode 100644
index 00000000000..86991000790
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/DiscUnif.h
@@ -0,0 +1,75 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: DiscUnif.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#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++/g++-include/Erlang.cc b/gnu/lib/libg++/g++-include/Erlang.cc
new file mode 100644
index 00000000000..da3e4e7bd06
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Erlang.cc
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Erlang.h>
+
+double Erlang::operator()()
+{
+ double prod = 1.0;
+
+ for (int i = 0; i < k; i++) {
+ prod *= pGenerator -> asDouble();
+ }
+ return(-log(prod)/a);
+}
diff --git a/gnu/lib/libg++/g++-include/Erlang.h b/gnu/lib/libg++/g++-include/Erlang.h
new file mode 100644
index 00000000000..54bcfcb69ab
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Erlang.h
@@ -0,0 +1,71 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Erlang.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+*/
+
+#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++/g++-include/Fix.cc b/gnu/lib/libg++/g++-include/Fix.cc
new file mode 100644
index 00000000000..0a5bc2d793b
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Fix.cc
@@ -0,0 +1,615 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+//
+// Fix.cc : variable length fixed point data type class functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <math.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <strstream.h>
+#include <Fix.h>
+
+// default parameters
+
+uint16 Fix_default_length = 16;
+int Fix_default_print_width = 8;
+
+Fix_peh Fix_overflow_handler = Fix_overflow_saturate;
+
+_Frep _Frep_0 = { 16, 1, 1, { 0 } };
+_Frep _Frep_m1 = { 16, 1, 1, { 0x8000 } };
+_Frep _Frep_quotient_bump = { 16, 1, 1, { 0x4000 } };
+
+// error handling
+
+void default_Fix_error_handler(const char* msg)
+{
+ cerr << "Fix: " << msg << "\n";
+ abort();
+}
+
+void default_Fix_range_error_handler(const char* msg)
+{
+ cerr << "Fix: range error in " << msg << "\n";
+ //abort();
+}
+
+one_arg_error_handler_t
+ Fix_error_handler = default_Fix_error_handler,
+ Fix_range_error_handler = default_Fix_range_error_handler;
+
+one_arg_error_handler_t set_Fix_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = Fix_error_handler;
+ Fix_error_handler = f;
+ return old;
+}
+
+one_arg_error_handler_t set_Fix_range_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = Fix_range_error_handler;
+ Fix_range_error_handler = f;
+ return old;
+}
+
+void Fix::error(const char* msg)
+{
+ (*Fix_error_handler)(msg);
+}
+
+void Fix::range_error(const char* msg)
+{
+ (*Fix_range_error_handler)(msg);
+}
+
+// _Frep allocation and initialization functions
+
+static inline _Fix _new_Fix(uint16 len)
+{
+ int siz = (((uint32 )len + 15) >> 4);
+ if (siz <= 0) siz = 1;
+ unsigned int allocsiz = (sizeof(_Frep) + (siz - 1) * sizeof(uint16));
+ _Fix z = (_Fix)(new char[allocsiz]);
+ memset(z, 0, allocsiz);
+ z->len = len;
+ z->siz = siz;
+ z->ref = 1;
+ return z;
+}
+
+_Fix new_Fix(uint16 len)
+{
+ return _new_Fix(len);
+}
+
+_Fix new_Fix(uint16 len, const _Fix x)
+{
+ _Fix z = _new_Fix(len);
+ return copy(x,z);
+}
+
+_Fix new_Fix(uint16 len, double d)
+{
+ _Fix z = _new_Fix(len);
+
+ if ( d == _Fix_max_value )
+ {
+ z->s[0] = 0x7fff;
+ for ( int i=1; i < z->siz; i++ )
+ z->s[i] = 0xffff;
+ }
+ else if ( d < _Fix_min_value || d > _Fix_max_value )
+ (*Fix_range_error_handler)("declaration");
+ else
+ {
+ if (d < 0)
+ d += 2.0;
+ d *= 32768;
+ for ( int i=0; i < z->siz; i++ )
+ {
+ z->s[i] = (uint16 )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(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(uint16* x, uint16* y, int siz)
+{
+ int diff = (int16 )*x - (int16 )*y;
+ while ( --siz && !diff )
+ diff = (int32 )(uint32 )*++x - (int32 )(uint32 )*++y;
+ return diff;
+}
+
+inline static int docmpz(uint16* x, int siz)
+{
+ while ( siz-- )
+ if ( *x++ ) return 1;
+ return 0;
+}
+
+int compare(const _Fix x, const _Fix y)
+{
+ if ( x->siz == y->siz )
+ return docmp(x->s, y->s, x->siz);
+ else
+ {
+ int r;
+ _Fix 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 add(_Fix x, _Fix y, _Fix r)
+{
+ uint16 xsign = x->s[0], ysign = y->s[0];
+ _Fix longer, shorter;
+ if ( x->len >= y->len )
+ longer = x, shorter = y;
+ else
+ longer = y, shorter = x;
+ if ( r == NULL )
+ r = new_Fix(longer->len);
+ for ( int i=r->siz-1; i >= longer->siz; i-- )
+ r->s[i] = 0;
+ for ( ; i >= shorter->siz; i-- )
+ r->s[i] = longer->s[i];
+ uint32 sum = 0, carry = 0;
+ for ( ; i >= 0; i-- )
+ {
+ sum = carry + (uint32 )x->s[i] + (uint32 )y->s[i];
+ carry = sum >> 16;
+ r->s[i] = sum;
+ }
+ if ( (xsign ^ sum) & (ysign ^ sum) & 0x8000 )
+ (*Fix_overflow_handler)(r);
+ return r;
+}
+
+_Fix subtract(_Fix x, _Fix y, _Fix r)
+{
+ uint16 xsign = x->s[0], ysign = y->s[0];
+ _Fix longer, shorter;
+ if ( x->len >= y->len )
+ longer = x, shorter = y;
+ else
+ longer = y, shorter = x;
+ if ( r == NULL )
+ r = new_Fix(longer->len);
+ for ( int i=r->siz-1; i >= longer->siz; i-- )
+ r->s[i] = 0;
+ for ( ; i >= shorter->siz; i-- )
+ r->s[i] = (longer == x ? x->s[i] : -y->s[i]);
+ int16 carry = 0;
+ uint32 sum = 0;
+ for ( ; i >= 0; i-- )
+ {
+ sum = (int32 )carry + (uint32 )x->s[i] - (uint32 )y->s[i];
+ carry = sum >> 16;
+ r->s[i] = sum;
+ }
+ if ( (xsign ^ sum) & (~ysign ^ sum) & 0x8000 )
+ (*Fix_overflow_handler)(r);
+ return r;
+}
+
+_Fix multiply(_Fix x, _Fix y, _Fix r)
+{
+ if ( r == NULL )
+ r = new_Fix(x->len + y->len);
+ int xsign = x->s[0] & 0x8000,
+ ysign = y->s[0] & 0x8000;
+ Fix X(x->len), Y(y->len);
+ if ( xsign )
+ x = negate(x,X.rep);
+ if ( ysign )
+ y = negate(y,Y.rep);
+ for ( int i=0; i < r->siz; i++ )
+ r->s[i] = 0;
+ for ( i=x->siz-1; i >= 0; i-- )
+ {
+ uint32 carry = 0;
+ for ( int j=y->siz-1; j >= 0; j-- )
+ {
+ int k = i + j + 1;
+ uint32 a = (uint32 )x->s[i] * (uint32 )y->s[j];
+ uint32 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 multiply(_Fix x, int y, _Fix r)
+{
+ if ( y != (int16 )y )
+ (*Fix_range_error_handler)("multiply by int -- int too large");
+ if ( r == NULL )
+ r = new_Fix(x->len);
+ for ( int i=r->siz-1; i >= x->siz; i-- )
+ r->s[i] = 0;
+ int32 a, carry = 0;
+ for ( ; i > 0; i-- )
+ {
+ a = (int32 )(uint32 )x->s[i] * y + carry;
+ r->s[i] = a;
+ carry = a >> 16; // assumes arithmetic right shift
+ }
+ a = (int32 )(int16 )x->s[0] * y + carry;
+ r->s[0] = a;
+ a &= 0xffff8000L;
+ if ( a != 0xffff8000L && a != 0L ) {
+ r->s[0] = 0x8000 ^ x->s[0] ^ y;
+ (*Fix_overflow_handler)(r);
+ }
+ return r;
+}
+
+_Fix divide(_Fix x, _Fix y, _Fix q, _Fix r)
+{
+ int xsign = x->s[0] & 0x8000,
+ ysign = y->s[0] & 0x8000;
+ if ( q == NULL )
+ q = new_Fix(x->len);
+ copy(&_Frep_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);
+ y = ( ysign ? negate(y,Y.rep) : copy(y,Y.rep) );
+ if ( !compare(y) )
+ (*Fix_range_error_handler)("division -- division by zero");
+ else if ( compare(x,y) >= 0 )
+ if ( compare(x,y) == 0 && (xsign ^ ysign) != 0 )
+ {
+ copy(&_Frep_m1,q);
+ copy(&_Frep_0,r);
+ }
+ else
+ (*Fix_range_error_handler)("division");
+ else
+ {
+ _Fix t;
+ Fix S(r->len),
+ W(q->len,&_Frep_quotient_bump);
+ for ( int i=1; i < q->len; i++ )
+ {
+ shift(y,-1,y);
+ subtract(r,y,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 shift(_Fix x, int y, _Fix r)
+{
+ if ( y == 0 )
+ return x;
+ else if ( r == NULL )
+ r = new_Fix(x->len);
+
+ int ay = abs((long) y),
+ ayh = ay >> 4,
+ ayl = ay & 0x0f;
+ int xl, u, ilow, ihigh;
+ uint16 *rs, *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;
+ uint16 xrmask = 0xffffL >> xr;
+ for ( int i=0; i < ilow; i++, rs+=u, xsl+=u, xsr+=u )
+ *rs = 0;
+ for ( ; i < ihigh; i++, rs+=u, xsl+=u, xsr+=u )
+ *rs = (*xsl << xl) + ((*xsr >> xr) & xrmask);
+ *rs = (y > 0 ? (*xsl << xl) : ((*xsr >> xr) & xrmask));
+ rs += u;
+ for ( ; ++i < r->siz; rs+=u )
+ *rs = 0;
+ return r;
+}
+
+_Fix negate(_Fix x, _Fix r)
+{
+ if ( r == NULL )
+ r = new_Fix(x->len);
+ uint32 carry = 1;
+ for ( int i=r->siz-1; i >= x->siz; i-- )
+ r->s[i] = 0;
+ for ( ; i >= 0; i-- )
+ {
+ uint32 a = (uint16 )~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
+{
+ char format[20];
+ double val = value(*this);
+ int old_precision = s.precision(width-3);
+ long old_flags = s.setf(ios::fixed, ios::fixed|ios::scientific);
+ if (val >= 0)
+ s << ' ';
+ s.width(width-2);
+ s << val;
+ s.precision(old_precision);
+ s.flags(old_flags);
+}
+
+char* Ftoa(Fix& x, int width)
+{
+ int wrksiz = width + 2;
+ char *fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ ostrstream stream(fmtbase, wrksiz);
+
+ x.printon(stream, width);
+ stream << ends;
+ return fmtbase;
+}
+
+extern Obstack _libgxx_io_ob;
+
+Fix Fix::operator %= (int y)
+{
+ Fix r((int )rep->len + y, *this); return *this = r;
+}
+
+istream& operator >> (istream& s, Fix& y)
+{
+ int got_one = 0;
+ if (!s.ipfx(0))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+
+ char sign = 0, point = 0;
+ char ch;
+ s >> ws;
+ if (!s.good())
+ {
+ s.clear(ios::failbit|s.rdstate());
+ return s;
+ }
+ while (s.get(ch))
+ {
+ if (ch == '-')
+ {
+ if (sign == 0)
+ {
+ sign = 1;
+ _libgxx_io_ob.grow(ch);
+ }
+ else
+ break;
+ }
+ if (ch == '.')
+ {
+ if (point == 0)
+ {
+ point = 1;
+ _libgxx_io_ob.grow(ch);
+ }
+ else
+ break;
+ }
+ else if (ch >= '0' && ch <= '9')
+ {
+ got_one = 1;
+ _libgxx_io_ob.grow(ch);
+ }
+ else
+ break;
+ }
+ char * p = (char*)(_libgxx_io_ob.finish(0));
+ if (s.good())
+ s.putback(ch);
+ if (!got_one)
+ s.clear(ios::failbit|s.rdstate());
+ else
+ y = atoF(p);
+ _libgxx_io_ob.free(p);
+ return s;
+}
+
+void show(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 set_overflow_handler(Fix_peh new_handler) {
+ Fix_peh old_handler = Fix_overflow_handler;
+ Fix_overflow_handler = new_handler;
+ return old_handler;
+}
+
+int Fix_set_default_length(int newlen)
+{
+ uint16 oldlen = Fix_default_length;
+ if ( newlen < _Fix_min_length || newlen > _Fix_max_length )
+ (*Fix_error_handler)("illegal length in Fix_set_default_length");
+ Fix_default_length = newlen;
+ return oldlen;
+}
+
+// overflow handlers
+
+void Fix_overflow_saturate(_Fix& r) {
+ if ( (int16 )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(_Fix&) {}
+
+void Fix_overflow_warning_saturate(_Fix& r) {
+ Fix_overflow_warning(r);
+ Fix_overflow_saturate(r);
+}
+
+void Fix_overflow_warning(_Fix&) {
+ cerr << "Fix: overflow warning\n";
+}
+
+void Fix_overflow_error(_Fix&) {
+ cerr << "Fix: overflow error\n";
+ abort();
+}
+
diff --git a/gnu/lib/libg++/g++-include/Fix.h b/gnu/lib/libg++/g++-include/Fix.h
new file mode 100644
index 00000000000..db1b7896183
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Fix.h
@@ -0,0 +1,471 @@
+//
+// Fix.h : variable length fixed point data type
+//
+// $Id: Fix.h,v 1.1 1995/10/18 08:38:15 deraadt Exp $
+//
+
+#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>
+
+typedef unsigned short uint16;
+typedef short int16;
+typedef unsigned long uint32;
+typedef long int32;
+
+#define _Fix_min_length 1
+#define _Fix_max_length 65535
+
+#define _Fix_min_value -1.0
+#define _Fix_max_value 1.0
+
+extern uint16 Fix_default_length;
+extern int Fix_default_print_width;
+
+struct _Frep // internal Fix representation
+{
+ uint16 len; // length in bits
+ uint16 siz; // allocated storage
+ int16 ref; // reference count
+ uint16 s[1]; // start of ushort array represention
+};
+
+typedef _Frep* _Fix;
+
+extern _Frep _Frep_0;
+extern _Frep _Frep_m1;
+extern _Frep _Frep_quotient_bump;
+
+class Fix
+{
+ _Fix rep;
+
+ Fix(_Fix);
+
+ void unique();
+
+public:
+ Fix();
+ Fix(Fix&);
+ Fix(double);
+ Fix(int);
+ Fix(int, const Fix&);
+ Fix(int, double);
+ Fix(int, const _Fix);
+
+ ~Fix();
+
+ Fix operator = (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 + (Fix&, Fix&);
+ friend Fix operator - (Fix&, Fix&);
+ friend Fix operator * (Fix&, Fix&);
+ friend Fix operator / (Fix&, Fix&);
+
+ friend Fix operator * (Fix&, int);
+ friend Fix operator * (int, Fix&);
+ friend Fix operator % (Fix&, int);
+ friend Fix operator << (Fix&, int);
+ friend Fix operator >> (Fix&, int);
+
+#ifdef __GNUG__
+ friend Fix operator <? (Fix&, Fix&); // min
+ friend Fix operator >? (Fix&, Fix&); // max
+#endif
+
+ Fix operator += (Fix&);
+ Fix operator -= (Fix&);
+ Fix operator *= (Fix&);
+ Fix operator /= (Fix&);
+
+ Fix operator *= (int);
+ Fix operator %= (int);
+ Fix operator <<=(int);
+ Fix operator >>=(int);
+
+ friend char* Ftoa(Fix&, int width = Fix_default_print_width);
+ void printon(ostream&, int width = Fix_default_print_width) const;
+ friend Fix atoF(const char*, int len = Fix_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(Fix&); // -1, 0, +1
+ friend Integer mantissa(Fix&); // integer representation
+ friend double value(const Fix&); // double value
+ friend int length(const Fix&); // field length
+ friend void show(Fix&); // show contents
+
+ // error handlers
+ void error(const char* msg); // error handler
+ void range_error(const char* msg); // range error handler
+
+ // internal class functions
+ friend void mask(_Fix);
+ friend int compare(const _Fix, const _Fix = &_Frep_0);
+
+ friend _Fix new_Fix(uint16);
+ friend _Fix new_Fix(uint16, const _Fix);
+ friend _Fix new_Fix(uint16, double);
+
+ friend _Fix copy(const _Fix, _Fix);
+ friend _Fix negate(_Fix, _Fix = NULL);
+ friend _Fix add(_Fix, _Fix, _Fix = NULL);
+ friend _Fix subtract(_Fix, _Fix, _Fix = NULL);
+ friend _Fix multiply(_Fix, _Fix, _Fix = NULL);
+ friend _Fix multiply(_Fix, int, _Fix = NULL);
+ friend _Fix divide(_Fix, _Fix, _Fix = NULL, _Fix = NULL);
+ friend _Fix shift(_Fix, int, _Fix = NULL);
+
+ // non-operator versions for user
+ friend void negate(Fix& x, Fix& r);
+ friend void add(Fix& x, Fix& y, Fix& r);
+ friend void subtract(Fix& x, Fix& y, Fix& r);
+ friend void multiply(Fix& x, Fix& y, Fix& r);
+ friend void divide(Fix& x, Fix& y, Fix& q, Fix& r);
+ friend void shift(Fix& x, int y, Fix& r);
+};
+
+// error handlers
+
+extern void
+ default_Fix_error_handler(const char*),
+ default_Fix_range_error_handler(const char*);
+
+extern one_arg_error_handler_t
+ Fix_error_handler,
+ Fix_range_error_handler;
+
+extern one_arg_error_handler_t
+ set_Fix_error_handler(one_arg_error_handler_t f),
+ set_Fix_range_error_handler(one_arg_error_handler_t f);
+
+typedef void (*Fix_peh)(_Fix&);
+extern Fix_peh Fix_overflow_handler;
+
+extern void
+ Fix_overflow_saturate(_Fix&),
+ Fix_overflow_wrap(_Fix&),
+ Fix_overflow_warning_saturate(_Fix&),
+ Fix_overflow_warning(_Fix&),
+ Fix_overflow_error(_Fix&);
+
+extern Fix_peh set_overflow_handler(Fix_peh);
+
+extern int Fix_set_default_length(int);
+
+// function definitions
+
+
+inline void Fix::unique()
+{
+ if ( rep->ref > 1 )
+ {
+ rep->ref--;
+ rep = new_Fix(rep->len,rep);
+ }
+}
+
+inline void mask (_Fix x)
+{
+ int n = x->len & 0x0f;
+ if ( n )
+ x->s[x->siz - 1] &= 0xffff0000 >> n;
+}
+
+inline _Fix copy(const _Fix from, _Fix to)
+{
+ uint16 *ts = to->s, *fs = from->s;
+ int ilim = to->siz < from->siz ? to->siz : from->siz;
+ for ( int i=0; i < ilim; i++ )
+ *ts++ = *fs++;
+ for ( ; i < to->siz; i++ )
+ *ts++ = 0;
+ mask(to);
+ return to;
+}
+
+inline Fix::Fix(_Fix f)
+{
+ rep = f;
+}
+
+inline Fix::Fix()
+{
+ rep = new_Fix(Fix_default_length);
+}
+
+inline Fix::Fix(int len)
+{
+ if ( len < _Fix_min_length || len > _Fix_max_length )
+ error("illegal length in declaration");
+ rep = new_Fix((uint16 )len);
+}
+
+inline Fix::Fix(double d)
+{
+ rep = new_Fix(Fix_default_length,d);
+}
+
+inline Fix::Fix(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((uint16 )len,y.rep);
+}
+
+inline Fix::Fix(int len, const _Fix fr)
+{
+ if ( len < 1 || len > 65535 )
+ error("illegal length in declaration");
+ rep = new_Fix((uint16 )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((uint16 )len,d);
+}
+
+inline Fix::~Fix()
+{
+ if ( --rep->ref <= 0 ) delete rep;
+}
+
+inline Fix Fix::operator = (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 compare(x.rep, y.rep) == 0;
+}
+
+inline int operator != (const Fix& x, const Fix& y)
+{
+ return compare(x.rep, y.rep) != 0;
+}
+
+inline int operator < (const Fix& x, const Fix& y)
+{
+ return compare(x.rep, y.rep) < 0;
+}
+
+inline int operator <= (const Fix& x, const Fix& y)
+{
+ return compare(x.rep, y.rep) <= 0;
+}
+
+inline int operator > (const Fix& x, const Fix& y)
+{
+ return compare(x.rep, y.rep) > 0;
+}
+
+inline int operator >= (const Fix& x, const Fix& y)
+{
+ return compare(x.rep, y.rep) >= 0;
+}
+
+inline Fix& Fix::operator + ()
+{
+ return *this;
+}
+
+inline Fix Fix::operator - ()
+{
+ _Fix r = negate(rep); return r;
+}
+
+inline Fix operator + (Fix& x, Fix& y)
+{
+ _Fix r = add(x.rep, y.rep); return r;
+}
+
+inline Fix operator - (Fix& x, Fix& y)
+{
+ _Fix r = subtract(x.rep, y.rep); return r;
+}
+
+inline Fix operator * (Fix& x, Fix& y)
+{
+ _Fix r = multiply(x.rep, y.rep); return r;
+}
+
+inline Fix operator * (Fix& x, int y)
+{
+ _Fix r = multiply(x.rep, y); return r;
+}
+
+inline Fix operator * (int y, Fix& x)
+{
+ _Fix r = multiply(x.rep, y); return r;
+}
+
+inline Fix operator / (Fix& x, Fix& y)
+{
+ _Fix r = divide(x.rep, y.rep); return r;
+}
+
+inline Fix Fix::operator += (Fix& y)
+{
+ unique(); add(rep, y.rep, rep); return *this;
+}
+
+inline Fix Fix::operator -= (Fix& y)
+{
+ unique(); subtract(rep, y.rep, rep); return *this;
+}
+
+inline Fix Fix::operator *= (Fix& y)
+{
+ unique(); multiply(rep, y.rep, rep); return *this;
+}
+
+inline Fix Fix::operator *= (int y)
+{
+ unique(); multiply(rep, y, rep); return *this;
+}
+
+inline Fix Fix::operator /= (Fix& y)
+{
+ unique(); divide(rep, y.rep, rep); return *this;
+}
+
+inline Fix operator % (Fix& x, int y)
+{
+ Fix r((int )x.rep->len + y, x); return r;
+}
+
+inline Fix operator << (Fix& x, int y)
+{
+ _Fix rep = shift(x.rep, y); return rep;
+}
+
+inline Fix operator >> (Fix& x, int y)
+{
+ _Fix rep = shift(x.rep, -y); return rep;
+}
+
+inline Fix Fix::operator <<= (int y)
+{
+ unique(); shift(rep, y, rep); return *this;
+}
+
+inline Fix Fix::operator >>= (int y)
+{
+ unique(); shift(rep, -y, rep); return *this;
+}
+
+#ifdef __GNUG__
+inline Fix operator <? (Fix& x, Fix& y)
+{
+ if ( compare(x.rep, y.rep) <= 0 ) return x; else return y;
+}
+
+inline Fix operator >? (Fix& x, Fix& y)
+{
+ if ( compare(x.rep, y.rep) >= 0 ) return x; else return y;
+}
+#endif
+
+inline Fix abs(Fix x)
+{
+ _Fix r = (compare(x.rep) >= 0 ? new_Fix(x.rep->len,x.rep) : negate(x.rep));
+ return r;
+}
+
+inline int sgn(Fix& x)
+{
+ int a = 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 (Fix& x, Fix& r)
+{
+ negate(x.rep, r.rep);
+}
+
+inline void add (Fix& x, Fix& y, Fix& r)
+{
+ add(x.rep, y.rep, r.rep);
+}
+
+inline void subtract (Fix& x, Fix& y, Fix& r)
+{
+ subtract(x.rep, y.rep, r.rep);
+}
+
+inline void multiply (Fix& x, Fix& y, Fix& r)
+{
+ multiply(x.rep, y.rep, r.rep);
+}
+
+inline void divide (Fix& x, Fix& y, Fix& q, Fix& r)
+{
+ divide(x.rep, y.rep, q.rep, r.rep);
+}
+
+inline void shift (Fix& x, int y, Fix& r)
+{
+ shift(x.rep, y, r.rep);
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Fix16.cc b/gnu/lib/libg++/g++-include/Fix16.cc
new file mode 100644
index 00000000000..a66bfbf9b19
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Fix16.cc
@@ -0,0 +1,238 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//
+// Fix.cc : fixed precision class support functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Fix16.h>
+
+// basic operators too large to be inline
+
+short Fix16::assign(double d)
+{
+ if (d == 1.0)
+ return Fix16_m_max;
+ else if (d > Fix16_max)
+ {
+ short i = Fix16_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix16_min)
+ {
+ short i = Fix16_m_min;
+ range_error(i);
+ return i;
+ }
+ else
+ return round(Fix16_mult * d);
+}
+
+long Fix32::assign(double d)
+{
+ if (d == 1.0)
+ return Fix32_m_max;
+ else if (d > Fix32_max)
+ {
+ long i = Fix32_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix32_min)
+ {
+ long i = Fix32_m_min;
+ range_error(i);
+ return i;
+ }
+ else
+ return round(Fix32_mult * d);
+}
+
+
+Fix32 operator * (const Fix32& a, const Fix32& b)
+{
+// break a and b into lo and hi parts, and do a multiple-precision
+// multiply, with rounding
+
+ int apos = (a.m >= 0);
+ unsigned long ua = (apos)? a.m : - a.m;
+ ua <<= 1; // ua is biased so result will be 31 bit mantissa, not 30:
+ unsigned long hi_a = (ua >> 16) & ((1 << 16) - 1);
+ unsigned long lo_a = ua & ((1 << 16) - 1);
+
+ int bpos = (b.m >= 0);
+ unsigned long ub = (bpos)? b.m : -b.m;
+ unsigned long hi_b = (ub >> 16) & ((1 << 16) - 1);
+ unsigned long lo_b = ub & ((1 << 16) - 1);
+
+ unsigned long r = lo_a * lo_b + (1 << 15);
+ r = (r >> 16) + hi_a * lo_b + lo_a * hi_b + (1 << 15);
+ r = (r >> 16) + hi_a * hi_b;
+ long p = (apos != bpos)? -r : r;
+ return Fix32(p);
+}
+
+Fix16 operator / (const Fix16& a, const Fix16& b)
+{
+ short q;
+ int apos = (a.m >= 0);
+ long la = (apos)? a.m : -a.m;
+ long scaled_a = la << 15;
+ int bpos = (b.m >= 0);
+ short sb = (bpos)? b.m: -b.m;
+ if (la >= sb)
+ {
+ q = (apos == bpos)? Fix16_m_max: Fix16_m_min;
+ a.range_error(q);
+ }
+ else
+ {
+ q = scaled_a / sb;
+ if ((scaled_a % sb) >= (sb / 2)) ++q;
+ if (apos != bpos) q = -q;
+ }
+ return Fix16(q);
+}
+
+Fix32 operator / (const Fix32& a, const Fix32& b)
+{
+ long q;
+ int apos = (a.m >= 0);
+ unsigned long la = (apos)? a.m : -a.m;
+ int bpos = (b.m >= 0);
+ unsigned long lb = (bpos)? b.m: -b.m;
+ if (la >= lb)
+ {
+ q = (apos == bpos)? Fix32_m_max: Fix32_m_min;
+ a.range_error(q);
+ }
+ else // standard shift-based division alg
+ {
+ q = 0;
+ long r = la;
+
+ for (int i = 32; i > 0; i--)
+ {
+ if ((unsigned)(r) > lb) {
+ q = (q << 1) | 1;
+ r -= lb;
+ }
+ else
+ q = (q << 1);
+ r <<= 1;
+ }
+
+ if (apos != bpos) q = -q; // Fix sign
+ }
+ return Fix32(q);
+}
+
+
+// error handling
+
+void Fix16::overflow(short& i) const
+{
+ (*Fix16_overflow_handler)(i);
+}
+
+void Fix32::overflow(long& i) const
+{
+ (*Fix32_overflow_handler)(i);
+}
+
+void Fix16::range_error(short& i) const
+{
+ (*Fix16_range_error_handler)(i);
+}
+
+void Fix32::range_error(long& i) const
+{
+ (*Fix32_range_error_handler)(i);
+}
+
+// data definitions
+
+Fix16_peh Fix16_overflow_handler = Fix16_overflow_saturate;
+Fix32_peh Fix32_overflow_handler = Fix32_overflow_saturate;
+
+Fix16_peh Fix16_range_error_handler = Fix16_warning;
+Fix32_peh Fix32_range_error_handler = Fix32_warning;
+
+//function definitions
+
+Fix16_peh set_Fix16_overflow_handler(Fix16_peh new_handler) {
+ Fix16_peh old_handler = Fix16_overflow_handler;
+ Fix16_overflow_handler = new_handler;
+ return old_handler;
+}
+
+Fix32_peh set_Fix32_overflow_handler(Fix32_peh new_handler) {
+ Fix32_peh old_handler = Fix32_overflow_handler;
+ Fix32_overflow_handler = new_handler;
+ return old_handler;
+}
+
+void set_overflow_handler(Fix16_peh handler16, Fix32_peh handler32) {
+ set_Fix16_overflow_handler(handler16);
+ set_Fix32_overflow_handler(handler32);
+}
+
+Fix16_peh set_Fix16_range_error_handler(Fix16_peh new_handler) {
+ Fix16_peh old_handler = Fix16_range_error_handler;
+ Fix16_range_error_handler = new_handler;
+ return old_handler;
+}
+
+Fix32_peh set_Fix32_range_error_handler(Fix32_peh new_handler) {
+ Fix32_peh old_handler = Fix32_range_error_handler;
+ Fix32_range_error_handler = new_handler;
+ return old_handler;
+}
+
+void set_range_error_handler(Fix16_peh handler16, Fix32_peh handler32) {
+ set_Fix16_range_error_handler(handler16);
+ set_Fix32_range_error_handler(handler32);
+}
+
+void Fix16_overflow_saturate(short& i)
+ { i = (i > 0 ? Fix16_m_min : Fix16_m_max); }
+void Fix16_ignore(short&) {}
+void Fix16_warning(short&)
+ { cerr << "warning: Fix16 result out of range\n"; }
+void Fix16_overflow_warning_saturate(short& i)
+ { cerr << "warning: Fix16 result out of range\n";
+ Fix16_overflow_saturate(i); }
+void Fix16_abort(short&)
+ { cerr << "error: Fix16 result out of range\n"; abort(); }
+
+void Fix32_ignore(long&) {}
+void Fix32_overflow_saturate(long& i)
+ { i = (i > 0 ? Fix32_m_min : Fix32_m_max); }
+void Fix32_warning(long&)
+ { cerr << "warning: Fix32 result out of range\n"; }
+void Fix32_overflow_warning_saturate(long& i)
+ { cerr << "warning: Fix32 result out of range\n";
+ Fix32_overflow_saturate(i); }
+void Fix32_abort(long&)
+ { cerr << "error: Fix32 result out of range\n"; abort(); }
+
diff --git a/gnu/lib/libg++/g++-include/Fix16.h b/gnu/lib/libg++/g++-include/Fix16.h
new file mode 100644
index 00000000000..37fb54f409b
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Fix16.h
@@ -0,0 +1,650 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Fix16.h,v 1.1 1995/10/18 08:38:16 deraadt Exp $
+*/
+
+#ifndef _Fix16_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Fix16_h 1
+
+#include <stream.h>
+#include <std.h>
+
+// constant definitions
+
+#define Fix16_fs ((double)((unsigned)(1 << 15)))
+
+#define Fix16_msb (1 << 15)
+#define Fix16_m_max ((1 << 15) - 1)
+#define Fix16_m_min ((short)(1 << 15))
+
+#define Fix16_mult Fix16_fs
+#define Fix16_div (1./Fix16_fs)
+#define Fix16_max (1. - .5/Fix16_fs)
+#define Fix16_min (-1.)
+
+
+#define Fix32_fs ((double)((unsigned long)(1 << 31)))
+
+#define Fix32_msb ((unsigned long)(1 << 31))
+#define Fix32_m_max ((long)((1 << 31) - 1))
+#define Fix32_m_min ((long)(1 << 31))
+
+#define Fix32_mult Fix32_fs
+#define Fix32_div (1./Fix32_fs)
+#define Fix32_max (1. - .5/Fix32_fs)
+#define Fix32_min (-1.)
+
+
+//
+// Fix16 class: 16-bit Fixed point data type
+//
+// consists of a 16-bit mantissa (sign bit & 15 data bits).
+//
+
+class Fix16
+{
+ friend class Fix32;
+
+ short m;
+
+ short round(double d);
+ short assign(double d);
+ Fix16(short i);
+ Fix16(int i);
+
+ operator double() const;
+
+
+public:
+ Fix16();
+ Fix16(const Fix16& f);
+ Fix16(double d);
+ Fix16(const Fix32& f);
+
+ ~Fix16();
+
+ Fix16& operator=(const Fix16& f);
+ Fix16& operator=(double d);
+ Fix16& operator=(const Fix32& f);
+
+ friend short& mantissa(Fix16& f);
+ friend const short& mantissa(const Fix16& f);
+ friend double value(const Fix16& f);
+
+ Fix16 operator + () const;
+ Fix16 operator - () const;
+
+ friend Fix16 operator + (const Fix16& f, const Fix16& g);
+ friend Fix16 operator - (const Fix16& f, const Fix16& g);
+ friend Fix32 operator * (const Fix16& f, const Fix16& g);
+ friend Fix16 operator / (const Fix16& f, const Fix16& g);
+ friend Fix16 operator << (const Fix16& f, int b);
+ friend Fix16 operator >> (const Fix16& f, int b);
+
+ Fix16& operator += (const Fix16& f);
+ Fix16& operator -= (const Fix16& f);
+ Fix16& operator *= (const Fix16& );
+ Fix16& operator /= (const Fix16& f);
+
+ Fix16& operator <<=(int b);
+ Fix16& operator >>=(int b);
+
+ friend int operator == (const Fix16& f, const Fix16& g);
+ friend int operator != (const Fix16& f, const Fix16& g);
+ friend int operator >= (const Fix16& f, const Fix16& g);
+ friend int operator <= (const Fix16& f, const Fix16& g);
+ friend int operator > (const Fix16& f, const Fix16& g);
+ friend int operator < (const Fix16& f, const Fix16& g);
+
+ friend istream& operator >> (istream& s, Fix16& f);
+ friend ostream& operator << (ostream& s, const Fix16& f);
+
+ void overflow(short&) const;
+ void range_error(short&) const;
+
+ friend Fix16 operator * (const Fix16& f, int g);
+ friend Fix16 operator * (int g, const Fix16& f);
+ Fix16& operator *= (int g);
+};
+
+
+//
+// Fix32 class: 32-bit Fixed point data type
+//
+// consists of a 32-bit mantissa (sign bit & 31 data bits).
+//
+
+class Fix32
+{
+ friend class Fix16;
+
+ long m;
+
+ long round(double d);
+ long assign(double d);
+
+ Fix32(long i);
+ operator double() const;
+
+
+public:
+ Fix32();
+ Fix32(const Fix32& f);
+ Fix32(const Fix16& f);
+ Fix32(double d);
+ ~Fix32();
+
+ Fix32& operator = (const Fix32& f);
+ Fix32& operator = (const Fix16& f);
+ Fix32& operator = (double d);
+
+ friend long& mantissa(Fix32& f);
+ friend const long& mantissa(const Fix32& f);
+ friend double value(const Fix32& f);
+
+ Fix32 operator + () const;
+ Fix32 operator - () const;
+
+ friend Fix32 operator + (const Fix32& f, const Fix32& g);
+ friend Fix32 operator - (const Fix32& f, const Fix32& g);
+ friend Fix32 operator * (const Fix32& f, const Fix32& g);
+ friend Fix32 operator / (const Fix32& f, const Fix32& g);
+ friend Fix32 operator << (const Fix32& f, int b);
+ friend Fix32 operator >> (const Fix32& f, int b);
+
+ friend Fix32 operator * (const Fix16& f, const Fix16& g);
+
+ Fix32& operator += (const Fix32& f);
+ Fix32& operator -= (const Fix32& f);
+ Fix32& operator *= (const Fix32& f);
+ Fix32& operator /= (const Fix32& f);
+ Fix32& operator <<=(int b);
+ Fix32& operator >>=(int b);
+
+ friend int operator == (const Fix32& f, const Fix32& g);
+ friend int operator != (const Fix32& f, const Fix32& g);
+ friend int operator >= (const Fix32& f, const Fix32& g);
+ friend int operator <= (const Fix32& f, const Fix32& g);
+ friend int operator > (const Fix32& f, const Fix32& g);
+ friend int operator < (const Fix32& f, const Fix32& g);
+
+ friend istream& operator >> (istream& s, Fix32& f);
+ friend ostream& operator << (ostream& s, const Fix32& f);
+
+ void overflow(long& i) const;
+ void range_error(long& i) const;
+
+ friend Fix32 operator * (const Fix32& f, int g);
+ friend Fix32 operator * (int g, const Fix32& f);
+ Fix32& operator *= (int g);
+};
+
+// active error handler declarations
+
+typedef void (*Fix16_peh)(short&);
+typedef void (*Fix32_peh)(long&);
+
+extern Fix16_peh Fix16_overflow_handler;
+extern Fix32_peh Fix32_overflow_handler;
+
+extern Fix16_peh Fix16_range_error_handler;
+extern Fix32_peh Fix32_range_error_handler;
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define set_overflow_handler sohndl
+#define set_range_error_handler srnghdl
+#endif
+
+
+// error handler declarations
+
+extern Fix16_peh set_Fix16_overflow_handler(Fix16_peh);
+extern Fix32_peh set_Fix32_overflow_handler(Fix32_peh);
+extern void set_overflow_handler(Fix16_peh, Fix32_peh);
+
+extern Fix16_peh set_Fix16_range_error_handler(Fix16_peh);
+extern Fix32_peh set_Fix32_range_error_handler(Fix32_peh);
+extern void set_range_error_handler(Fix16_peh, Fix32_peh);
+
+extern void
+ Fix16_ignore(short&),
+ Fix16_overflow_saturate(short&),
+ Fix16_overflow_warning_saturate(short&),
+ Fix16_warning(short&),
+ Fix16_abort(short&);
+
+extern void
+ Fix32_ignore(long&),
+ Fix32_overflow_saturate(long&),
+ Fix32_overflow_warning_saturate(long&),
+ Fix32_warning(long&),
+ Fix32_abort(long&);
+
+
+inline Fix16::~Fix16() {}
+
+inline short Fix16::round(double d)
+{
+ return short( (d >= 0)? d + 0.5 : d - 0.5);
+}
+
+inline Fix16::Fix16(short i)
+{
+ m = i;
+}
+
+inline Fix16::Fix16(int i)
+{
+ m = i;
+}
+
+inline Fix16::operator double() const
+{
+ return Fix16_div * m;
+}
+
+inline Fix16::Fix16()
+{
+ m = 0;
+}
+
+inline Fix16::Fix16(const Fix16& f)
+{
+ m = f.m;
+}
+
+inline Fix16::Fix16(double d)
+{
+ m = assign(d);
+}
+
+
+inline Fix16& Fix16::operator=(const Fix16& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix16& Fix16::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+
+inline Fix32::Fix32()
+{
+ m = 0;
+}
+
+inline Fix32::Fix32(long i)
+{
+ m = i;
+}
+
+inline Fix32:: operator double() const
+{
+ return Fix32_div * m;
+}
+
+
+inline Fix32::Fix32(const Fix32& f)
+{
+ m = f.m;
+}
+
+inline Fix32::Fix32(const Fix16& f)
+{
+ m = long(f.m) << 16;
+}
+
+inline Fix32::Fix32(double d)
+{
+ m = assign(d);
+}
+
+inline Fix16::Fix16(const Fix32& f)
+{
+ m = f.m >> 16;
+}
+
+
+inline Fix16& Fix16::operator=(const Fix32& f)
+{
+ m = f.m >> 16;
+ return *this;
+}
+
+inline Fix32& Fix32::operator=(const Fix32& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix32& Fix32::operator=(const Fix16& f)
+{
+ m = long(f.m) << 16;
+ return *this;
+}
+
+inline Fix32& Fix32::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+inline short& mantissa(Fix16& f)
+{
+ return f.m;
+}
+
+inline const short& mantissa(const Fix16& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix16& f)
+{
+ return double(f);
+}
+
+inline Fix16 Fix16::operator+() const
+{
+ return m;
+}
+
+inline Fix16 Fix16::operator-() const
+{
+ return -m;
+}
+
+inline Fix16 operator+(const Fix16& f, const Fix16& g)
+{
+ short sum = f.m + g.m;
+ if ( (f.m ^ sum) & (g.m ^ sum) & Fix16_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix16 operator-(const Fix16& f, const Fix16& g)
+{
+ short sum = f.m - g.m;
+ if ( (f.m ^ sum) & (-g.m ^ sum) & Fix16_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix32 operator*(const Fix16& f, const Fix16& g)
+{
+ return Fix32( long( long(f.m) * long(g.m) << 1));
+}
+
+inline Fix16 operator<<(const Fix16& a, int b)
+{
+ return a.m << b;
+}
+
+inline Fix16 operator>>(const Fix16& a, int b)
+{
+ return a.m >> b;
+}
+
+inline Fix16& Fix16:: operator+=(const Fix16& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix16& Fix16:: operator-=(const Fix16& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix16& Fix16::operator*=(const Fix16& f)
+{
+ return *this = *this * f;
+}
+
+inline Fix16& Fix16:: operator/=(const Fix16& f)
+{
+ return *this = *this / f;
+}
+
+inline Fix16& Fix16:: operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix16& Fix16:: operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline int operator==(const Fix16& f, const Fix16& g)
+{
+ return f.m == g.m;
+}
+
+inline int operator!=(const Fix16& f, const Fix16& g)
+{
+ return f.m != g.m;
+}
+
+inline int operator>=(const Fix16& f, const Fix16& g)
+{
+ return f.m >= g.m;
+}
+
+inline int operator<=(const Fix16& f, const Fix16& g)
+{
+ return f.m <= g.m;
+}
+
+inline int operator>(const Fix16& f, const Fix16& g)
+{
+ return f.m > g.m;
+}
+
+inline int operator<(const Fix16& f, const Fix16& g)
+{
+ return f.m < g.m;
+}
+
+inline istream& operator>>(istream& s, Fix16& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix16& f)
+{
+ return s << double(f);
+}
+
+
+inline Fix16 operator*(const Fix16& f, int g)
+{
+ return Fix16(short(f.m * g));
+}
+
+inline Fix16 operator*(int g, const Fix16& f)
+{
+ return f * g;
+}
+
+
+inline Fix16& Fix16::operator*=(int g)
+{
+ return *this = *this * g;
+}
+
+inline Fix32::~Fix32() {}
+
+inline long Fix32::round(double d)
+{
+ return long( (d >= 0)? d + 0.5 : d - 0.5);
+}
+
+inline long& mantissa(Fix32& f)
+{
+ return f.m;
+}
+
+inline const long& mantissa(const Fix32& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix32& f)
+{
+ return double(f);
+}
+
+inline Fix32 Fix32::operator+() const
+{
+ return m;
+}
+
+inline Fix32 Fix32::operator-() const
+{
+ return -m;
+}
+
+inline Fix32 operator+(const Fix32& f, const Fix32& g)
+{
+ long sum = f.m + g.m;
+ if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix32 operator-(const Fix32& f, const Fix32& g)
+{
+ long sum = f.m - g.m;
+ if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix32 operator<<(const Fix32& a, int b)
+{
+ return a.m << b;
+}
+
+inline Fix32 operator>>(const Fix32& a, int b)
+{
+ return a.m >> b;
+}
+
+inline Fix32& Fix32::operator+=(const Fix32& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix32& Fix32::operator-=(const Fix32& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix32& Fix32::operator*=(const Fix32& f)
+{
+ return *this = *this * f;
+}
+
+inline Fix32& Fix32::operator/=(const Fix32& f)
+{
+ return *this = *this / f;
+}
+
+
+inline Fix32& Fix32::operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix32& Fix32::operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline int operator==(const Fix32& f, const Fix32& g)
+{
+ return f.m == g.m;
+}
+
+inline int operator!=(const Fix32& f, const Fix32& g)
+{
+ return f.m != g.m;
+}
+
+inline int operator>=(const Fix32& f, const Fix32& g)
+{
+ return f.m >= g.m;
+}
+
+inline int operator<=(const Fix32& f, const Fix32& g)
+{
+ return f.m <= g.m;
+}
+
+inline int operator>(const Fix32& f, const Fix32& g)
+{
+ return f.m > g.m;
+}
+
+inline int operator<(const Fix32& f, const Fix32& g)
+{
+ return f.m < g.m;
+}
+
+inline istream& operator>>(istream& s, Fix32& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix32& f)
+{
+ return s << double(f);
+}
+
+inline Fix32 operator*(const Fix32& f, int g)
+{
+ return Fix32(long(f.m * g));
+}
+
+inline Fix32 operator*(int g, const Fix32& f)
+{
+ return f * g;
+}
+
+
+
+inline Fix32& Fix32::operator*=(int g)
+{
+ return *this = *this * g;
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Fix24.cc b/gnu/lib/libg++/g++-include/Fix24.cc
new file mode 100644
index 00000000000..22e23dcbcf2
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Fix24.cc
@@ -0,0 +1,327 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//
+// Fix24.cc : fixed precision class support functions
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Fix24.h>
+
+// basic operators too large to be inline
+
+long Fix24::assign(double d)
+{
+ if (d == 1.0)
+ return Fix24_m_max;
+ else if (d > Fix24_max)
+ {
+ long i = Fix24_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix24_min)
+ {
+ long i = Fix24_m_min;
+ range_error(i);
+ return i;
+ }
+ else {
+ d = (long) (d * (1 << 24) + ((d >= 0)? 0.5 : -0.5)); // Round to 24 bits
+ return ((long) d) << (Fix24_shift - 24); /* Convert to integer format */
+ }
+}
+
+twolongs Fix48::assign(double d)
+{
+ if (d == 1.0)
+ return Fix48_m_max;
+ else if (d > Fix48_max)
+ {
+ twolongs i = Fix48_m_max;
+ range_error(i);
+ return i;
+ }
+ else if (d < Fix48_min)
+ {
+ twolongs i = Fix48_m_min;
+ range_error(i);
+ return i;
+ }
+ else {
+ twolongs i;
+ int sign = (d < 0);
+
+/* First, convert the absolute value of d to a 48-bit integer format */
+ if (d < 0) d = -d;
+ i.u = ((long)(d *= Fix24_mult)) & 0xffffff00;
+ i.l = ((unsigned long)((d - i.u)* (Fix24_mult / (1 << 7)))) & 0xffffff00;
+
+/* Calculate the two's complement if d was negative */
+ if (sign) {
+ unsigned long oldlower = i.l;
+ i.l = (~i.l + 1) & 0xffffff00;
+ i.u = (~i.u + (((oldlower ^ i.l) & Fix24_msb)? 0 : 1)) & 0xffffff00;
+ }
+ return i;
+ }
+}
+
+
+Fix48 operator * (const Fix24& a, const Fix24& b)
+{
+// break a and b into lo and hi parts, and do a multiple-precision
+// multiply, with rounding
+
+ int apos = (a.m >= 0);
+ unsigned long ua = (apos)? a.m : - a.m;
+ ua <<= 1; // ua is biased so result will be 47 bit mantissa, not 46:
+ unsigned long hi_a = (ua >> 16) & ((1 << 16) - 1);
+ unsigned long lo_a = ua & ((1 << 16) - 1);
+
+ int bpos = (b.m >= 0);
+ unsigned long ub = (bpos)? b.m : -b.m;
+ unsigned long hi_b = (ub >> 16) & ((1 << 16) - 1);
+ unsigned long lo_b = ub & ((1 << 16) - 1);
+
+ unsigned long
+ hi_r = hi_a * hi_b,
+ mi_r = hi_a * lo_b + lo_a * hi_b,
+ lo_r = lo_a * lo_b,
+ rl = ((hi_r << 16) & 0x00ffffffL) + (mi_r & 0x00ffffffL) + (lo_r >> 16);
+ twolongs r;
+ r.u = (hi_r & 0xffffff00L) + ((mi_r >> 16) & 0x0000ff00L)
+ + ((rl >> 16) & 0x0000ff00L);
+ r.l = rl << 8;
+
+ if ( apos != bpos ) {
+ unsigned long l = r.l;
+ r.l = -r.l;
+ r.u = (~r.u + ((l ^ r.l) & Fix24_msb ? 0 : Fix24_lsb)) & 0xffffff00;
+ }
+ return r;
+}
+
+Fix24 operator / (const Fix24& a, const Fix24& b)
+{
+ long q;
+ int apos = (a.m >= 0);
+ unsigned long la = (apos)? a.m : -a.m;
+ int bpos = (b.m >= 0);
+ unsigned long lb = (bpos)? b.m: -b.m;
+ if (la >= lb)
+ {
+ q = (apos == bpos)? Fix24_m_max: Fix24_m_min;
+ a.range_error(q);
+ }
+ else // standard shift-based division alg
+ {
+ q = 0;
+ long r = la;
+
+ for (int i = 32; i > 0; i--)
+ {
+ if ((unsigned)(r) > lb) {
+ q = (q << 1) | 1;
+ r -= lb;
+ }
+ else
+ q = (q << 1);
+ r <<= 1;
+ }
+
+ q += 0x80; // Round result to 24 bits
+ if (apos != bpos) q = -q; // Fix sign
+ }
+ return (q & ~0xFF);
+}
+
+
+Fix48 operator + (const Fix48& f, const Fix48& g)
+{
+ long lo_r = (f.m.l >> 8) + (g.m.l >> 8);
+ twolongs r;
+ r.u = f.m.u + g.m.u + (lo_r & 0x01000000L ? 0x00000100L : 0);
+ r.l = lo_r << 8;
+
+ if ( (f.m.u ^ r.u) & (g.m.u ^ r.u) & Fix24_msb )
+ f.overflow(r);
+ return r;
+}
+
+Fix48 operator - (const Fix48& f, const Fix48& g)
+{
+ unsigned lo_r = (f.m.l >> 8) - (g.m.l >> 8);
+ twolongs r;
+ r.u = f.m.u - g.m.u - (lo_r & 0x01000000L ? 0x00000100L: 0);
+ r.l = lo_r << 8;
+
+ if ( ((f.m.u ^ r.u) & (-g.m.u ^ r.u) & Fix24_msb) && g.m.u )
+ f.overflow(r);
+ return r;
+}
+
+Fix48 operator * (const Fix48& a, int b)
+{
+ twolongs r;
+ int bpos = (b >= 0);
+ unsigned ub = (bpos)? b : -b;
+ if ( ub >= 65536L ) {
+ r = (bpos)? Fix48_m_max : Fix48_m_min;
+ a.range_error(r);
+ }
+ else {
+ unsigned long
+ lo_r = (a.m.l & 0xffff) * ub,
+ mi_r = ((a.m.l >> 16) & 0xffff) * ub,
+ hi_r = a.m.u * ub;
+ r.l = lo_r + (mi_r << 16);
+ r.u = hi_r + ((mi_r >> 8) & 0x00ffff00L);
+ if ( !bpos ) {
+ unsigned long l = r.l;
+ r.l = -r.l;
+ r.u = ~r.u + ((l ^ r.l) & Fix24_msb ? 0 : Fix24_lsb);
+ }
+ }
+ return r;
+}
+
+Fix48 operator << (const Fix48& a, int b)
+{
+ twolongs r; r.u = 0; r.l = 0;
+ if ( b >= 0 )
+ if ( b < 24 ) {
+ r.u = (a.m.u << b) + ((a.m.l >> (24 - b)) & 0xffffff00L);
+ r.l = a.m.l << b;
+ }
+ else if ( b < 48 ) {
+ r.u = a.m.l << (b - 24);
+ }
+ return r;
+}
+
+Fix48 operator >> (const Fix48& a, int b)
+{
+ twolongs r; r.u = 0; r.l = 0;
+ if ( b >= 0 )
+ if ( b < 24 ) {
+ r.l = (a.m.u << (24 - b)) + ((a.m.l >> b) & 0xffffff00L);
+ r.u = (a.m.u >> b) & 0xffffff00L;
+ }
+ else if ( b < 48 ) {
+ r.l = (a.m.u >> (b - 24)) & 0xffffff00L;
+ r.u = (a.m.u >> 24) & 0xffffff00L;
+ }
+ else {
+ r.l = (a.m.u >> 24) & 0xffffff00L;
+ r.u = r.l;
+ }
+ return r;
+}
+
+// error handling
+
+void Fix24::overflow(long& i) const
+{
+ (*Fix24_overflow_handler)(i);
+}
+
+void Fix48::overflow(twolongs& i) const
+{
+ (*Fix48_overflow_handler)(i);
+}
+
+void Fix24::range_error(long& i) const
+{
+ (*Fix24_range_error_handler)(i);
+}
+
+void Fix48::range_error(twolongs& i) const
+{
+ (*Fix48_range_error_handler)(i);
+}
+
+// data definitions
+
+Fix24_peh Fix24_overflow_handler = Fix24_overflow_saturate;
+Fix48_peh Fix48_overflow_handler = Fix48_overflow_saturate;
+
+Fix24_peh Fix24_range_error_handler = Fix24_warning;
+Fix48_peh Fix48_range_error_handler = Fix48_warning;
+
+//function definitions
+
+Fix24_peh set_Fix24_overflow_handler(Fix24_peh new_handler) {
+ Fix24_peh old_handler = Fix24_overflow_handler;
+ Fix24_overflow_handler = new_handler;
+ return old_handler;
+}
+
+Fix48_peh set_Fix48_overflow_handler(Fix48_peh new_handler) {
+ Fix48_peh old_handler = Fix48_overflow_handler;
+ Fix48_overflow_handler = new_handler;
+ return old_handler;
+}
+
+void set_overflow_handler(Fix24_peh handler24, Fix48_peh handler48) {
+ set_Fix24_overflow_handler(handler24);
+ set_Fix48_overflow_handler(handler48);
+}
+
+Fix24_peh set_Fix24_range_error_handler(Fix24_peh new_handler) {
+ Fix24_peh old_handler = Fix24_range_error_handler;
+ Fix24_range_error_handler = new_handler;
+ return old_handler;
+}
+
+Fix48_peh set_Fix48_range_error_handler(Fix48_peh new_handler) {
+ Fix48_peh old_handler = Fix48_range_error_handler;
+ Fix48_range_error_handler = new_handler;
+ return old_handler;
+}
+
+void set_range_error_handler(Fix24_peh handler24, Fix48_peh handler48) {
+ set_Fix24_range_error_handler(handler24);
+ set_Fix48_range_error_handler(handler48);
+}
+
+void Fix24_overflow_saturate(long& i)
+ { i = (i > 0 ? Fix24_m_min : Fix24_m_max); }
+void Fix24_ignore(long&) {}
+void Fix24_warning(long&)
+ { cerr << "warning: Fix24 result out of range\n"; }
+void Fix24_overflow_warning_saturate(long& i)
+ { cerr << "warning: Fix24 result out of range\n";
+ Fix24_overflow_saturate(i); }
+void Fix24_abort(long&)
+ { cerr << "error: Fix24 result out of range\n"; abort(); }
+
+void Fix48_ignore(twolongs&) {}
+void Fix48_overflow_saturate(twolongs& i)
+ { i = (i.u > 0 ? Fix48_m_min : Fix48_m_max); }
+void Fix48_warning(twolongs&)
+ { cerr << "warning: Fix48 result out of range\n"; }
+void Fix48_overflow_warning_saturate(twolongs& i)
+ { cerr << "warning: Fix48 result out of range\n";
+ Fix48_overflow_saturate(i); }
+void Fix48_abort(twolongs&)
+ { cerr << "error: Fix48 result out of range\n"; abort(); }
+
diff --git a/gnu/lib/libg++/g++-include/Fix24.h b/gnu/lib/libg++/g++-include/Fix24.h
new file mode 100644
index 00000000000..6de676c08eb
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Fix24.h
@@ -0,0 +1,599 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
+ adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Fix24.h,v 1.1 1995/10/18 08:38:16 deraadt Exp $
+*/
+
+#ifndef _Fix24_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Fix24_h 1
+
+#include <stream.h>
+#include <std.h>
+
+// extra type definitions
+
+typedef struct {
+ long u;
+ unsigned long l;
+} twolongs;
+
+// constant definitions
+
+static const int
+ Fix24_shift = 31;
+
+static const double
+ Fix24_fs = 2147483648., // 2^Fix24_shift
+ Fix24_mult = Fix24_fs,
+ Fix24_div = 1./Fix24_fs,
+ Fix24_max = 1. - .5/Fix24_fs,
+ Fix24_min = -1.;
+
+static const unsigned long
+ Fix24_msb = 0x80000000L,
+ Fix24_lsb = 0x00000100L,
+ Fix24_m_max = 0x7fffff00L,
+ Fix24_m_min = 0x80000000L;
+
+static const double
+ Fix48_fs = 36028797018963968., // 2^(24+Fix24_shift)
+ Fix48_max = 1. - .5/Fix48_fs,
+ Fix48_min = -1.,
+ Fix48_div_u = 1./Fix24_fs,
+ Fix48_div_l = 1./Fix48_fs;
+
+static const twolongs
+ Fix48_msb = { 0x80000000L, 0L },
+ Fix48_lsb = { 0L, 0x00000100L },
+ Fix48_m_max = { 0x7fffff00L, 0xffffff00L },
+ Fix48_m_min = { 0x80000000L, 0L };
+
+//
+// Fix24 class: 24-bit Fixed point data type
+//
+// consists of a 24-bit mantissa (sign bit & 23 data bits).
+//
+
+class Fix24
+{
+ friend class Fix48;
+
+ long m;
+
+ long assign(double d);
+ operator double() const;
+ Fix24(long i);
+ Fix24(int i);
+
+
+public:
+ Fix24();
+ Fix24(const Fix24& f);
+ Fix24(double d);
+ Fix24(const Fix48& f);
+
+ ~Fix24();
+
+ Fix24& operator=(const Fix24& f);
+ Fix24& operator=(double d);
+ Fix24& operator=(const Fix48& f);
+
+ friend long& mantissa(Fix24& f);
+ friend const long& mantissa(const Fix24& f);
+ friend double value(const Fix24& f);
+
+ Fix24 operator + () const;
+ Fix24 operator - () const;
+
+ friend Fix24 operator + (const Fix24& f, const Fix24& g);
+ friend Fix24 operator - (const Fix24& f, const Fix24& g);
+ friend Fix48 operator * (const Fix24& f, const Fix24& g);
+ friend Fix24 operator * (const Fix24& f, int g);
+ friend Fix24 operator * (int g, const Fix24& f);
+ friend Fix24 operator / (const Fix24& f, const Fix24& g);
+ friend Fix24 operator << (const Fix24& f, int b);
+ friend Fix24 operator >> (const Fix24& f, int b);
+
+ Fix24& operator += (const Fix24& f);
+ Fix24& operator -= (const Fix24& f);
+ Fix24& operator *= (const Fix24& f);
+ Fix24& operator *= (int b);
+ Fix24& operator /= (const Fix24& f);
+
+ Fix24& operator <<=(int b);
+ Fix24& operator >>=(int b);
+
+ friend int operator == (const Fix24& f, const Fix24& g);
+ friend int operator != (const Fix24& f, const Fix24& g);
+ friend int operator >= (const Fix24& f, const Fix24& g);
+ friend int operator <= (const Fix24& f, const Fix24& g);
+ friend int operator > (const Fix24& f, const Fix24& g);
+ friend int operator < (const Fix24& f, const Fix24& g);
+
+ friend istream& operator >> (istream& s, Fix24& f);
+ friend ostream& operator << (ostream& s, const Fix24& f);
+
+ void overflow(long&) const;
+ void range_error(long&) const;
+};
+
+
+//
+// Fix48 class: 48-bit Fixed point data type
+//
+// consists of a 48-bit mantissa (sign bit & 47 data bits).
+//
+
+class Fix48
+{
+ friend class Fix24;
+
+ twolongs m;
+
+ twolongs assign(double d);
+ operator double() const;
+ Fix48(twolongs i);
+
+public:
+ Fix48();
+ Fix48(const Fix48& f);
+ Fix48(const Fix24& f);
+ Fix48(double d);
+ ~Fix48();
+
+ Fix48& operator = (const Fix48& f);
+ Fix48& operator = (const Fix24& f);
+ Fix48& operator = (double d);
+
+ friend twolongs& mantissa(Fix48& f);
+ friend const twolongs& mantissa(const Fix48& f);
+ friend double value(const Fix48& f);
+
+ Fix48 operator + () const;
+ Fix48 operator - () const;
+
+ friend Fix48 operator + (const Fix48& f, const Fix48& g);
+ friend Fix48 operator - (const Fix48& f, const Fix48& g);
+ friend Fix48 operator * (const Fix48& f, int g);
+ friend Fix48 operator * (int g, const Fix48& f);
+ friend Fix48 operator << (const Fix48& f, int b);
+ friend Fix48 operator >> (const Fix48& f, int b);
+
+ friend Fix48 operator * (const Fix24& f, const Fix24& g);
+
+ Fix48& operator += (const Fix48& f);
+ Fix48& operator -= (const Fix48& f);
+ Fix48& operator *= (int b);
+ Fix48& operator <<=(int b);
+ Fix48& operator >>=(int b);
+
+ friend int operator == (const Fix48& f, const Fix48& g);
+ friend int operator != (const Fix48& f, const Fix48& g);
+ friend int operator >= (const Fix48& f, const Fix48& g);
+ friend int operator <= (const Fix48& f, const Fix48& g);
+ friend int operator > (const Fix48& f, const Fix48& g);
+ friend int operator < (const Fix48& f, const Fix48& g);
+
+ friend istream& operator >> (istream& s, Fix48& f);
+ friend ostream& operator << (ostream& s, const Fix48& f);
+
+ void overflow(twolongs& i) const;
+ void range_error(twolongs& i) const;
+};
+
+
+// active error handler declarations
+
+typedef void (*Fix24_peh)(long&);
+typedef void (*Fix48_peh)(twolongs&);
+
+extern Fix24_peh Fix24_overflow_handler;
+extern Fix48_peh Fix48_overflow_handler;
+
+extern Fix24_peh Fix24_range_error_handler;
+extern Fix48_peh Fix48_range_error_handler;
+
+
+// error handler declarations
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define set_overflow_handler sohndl
+#define set_range_error_handler srnghdl
+#endif
+
+extern Fix24_peh set_Fix24_overflow_handler(Fix24_peh);
+extern Fix48_peh set_Fix48_overflow_handler(Fix48_peh);
+extern void set_overflow_handler(Fix24_peh, Fix48_peh);
+
+extern Fix24_peh set_Fix24_range_error_handler(Fix24_peh);
+extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh);
+extern void set_range_error_handler(Fix24_peh, Fix48_peh);
+
+extern void
+ Fix24_ignore(long&),
+ Fix24_overflow_saturate(long&),
+ Fix24_overflow_warning_saturate(long&),
+ Fix24_warning(long&),
+ Fix24_abort(long&);
+
+extern void
+ Fix48_ignore(twolongs&),
+ Fix48_overflow_saturate(twolongs&),
+ Fix48_overflow_warning_saturate(twolongs&),
+ Fix48_warning(twolongs&),
+ Fix48_abort(twolongs&);
+
+
+inline Fix24::~Fix24() {}
+
+inline Fix24::Fix24(long i)
+{
+ m = i;
+}
+
+inline Fix24::Fix24(int i)
+{
+ m = i;
+}
+
+inline Fix24::operator double() const
+{
+ return Fix24_div * m;
+}
+
+inline Fix24::Fix24()
+{
+ m = 0;
+}
+
+inline Fix24::Fix24(const Fix24& f)
+{
+ m = f.m;
+}
+
+inline Fix24::Fix24(double d)
+{
+ m = assign(d);
+}
+
+inline Fix24::Fix24(const Fix48& f)
+{
+ m = f.m.u;
+}
+
+inline Fix24& Fix24::operator=(const Fix24& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix24& Fix24::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+inline Fix24& Fix24::operator=(const Fix48& f)
+{
+ m = f.m.u;
+ return *this;
+}
+
+inline long& mantissa(Fix24& f)
+{
+ return f.m;
+}
+
+inline const long& mantissa(const Fix24& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix24& f)
+{
+ return double(f);
+}
+
+inline Fix24 Fix24::operator+() const
+{
+ return m;
+}
+
+inline Fix24 Fix24::operator-() const
+{
+ return -m;
+}
+
+inline Fix24 operator+(const Fix24& f, const Fix24& g)
+{
+ long sum = f.m + g.m;
+ if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix24 operator-(const Fix24& f, const Fix24& g)
+{
+ long sum = f.m - g.m;
+ if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb )
+ f.overflow(sum);
+ return sum;
+}
+
+inline Fix24 operator*(const Fix24& a, int b)
+{
+ return a.m * b;
+}
+
+inline Fix24 operator*(int b, const Fix24& a)
+{
+ return a * b;
+}
+
+inline Fix24 operator<<(const Fix24& a, int b)
+{
+ return a.m << b;
+}
+
+inline Fix24 operator>>(const Fix24& a, int b)
+{
+ return (a.m >> b) & 0xffffff00L;
+}
+
+inline Fix24& Fix24:: operator+=(const Fix24& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix24& Fix24:: operator-=(const Fix24& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix24& Fix24::operator*=(const Fix24& f)
+{
+ return *this = *this * f;
+}
+
+inline Fix24& Fix24:: operator/=(const Fix24& f)
+{
+ return *this = *this / f;
+}
+
+inline Fix24& Fix24:: operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix24& Fix24:: operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline Fix24& Fix24::operator*=(int b)
+{
+ return *this = *this * b;
+}
+
+inline int operator==(const Fix24& f, const Fix24& g)
+{
+ return f.m == g.m;
+}
+
+inline int operator!=(const Fix24& f, const Fix24& g)
+{
+ return f.m != g.m;
+}
+
+inline int operator>=(const Fix24& f, const Fix24& g)
+{
+ return f.m >= g.m;
+}
+
+inline int operator<=(const Fix24& f, const Fix24& g)
+{
+ return f.m <= g.m;
+}
+
+inline int operator>(const Fix24& f, const Fix24& g)
+{
+ return f.m > g.m;
+}
+
+inline int operator<(const Fix24& f, const Fix24& g)
+{
+ return f.m < g.m;
+}
+
+inline istream& operator>>(istream& s, Fix24& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix24& f)
+{
+ return s << double(f);
+}
+
+inline Fix48::~Fix48() {}
+
+inline Fix48::Fix48(twolongs i)
+{
+ m = i;
+}
+
+inline Fix48:: operator double() const
+{
+/*
+ * Note: can't simply do Fix48_div_u * m.u + Fix48_div_l * m.l, because
+ * m.u is signed and m.l is unsigned.
+ */
+ return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l :
+ (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00))
+ + Fix48_div_l * m.l) - 2;
+}
+
+inline Fix48::Fix48()
+{
+ m.u = 0;
+ m.l = 0;
+}
+
+inline Fix48::Fix48(const Fix48& f)
+{
+ m = f.m;
+}
+
+inline Fix48::Fix48(const Fix24& f)
+{
+ m.u = f.m;
+ m.l = 0;
+}
+
+inline Fix48::Fix48(double d)
+{
+ m = assign(d);
+}
+
+inline Fix48& Fix48::operator=(const Fix48& f)
+{
+ m = f.m;
+ return *this;
+}
+
+inline Fix48& Fix48::operator=(const Fix24& f)
+{
+ m.u = f.m;
+ m.l = 0;
+ return *this;
+}
+
+inline Fix48& Fix48::operator=(double d)
+{
+ m = assign(d);
+ return *this;
+}
+
+inline twolongs& mantissa(Fix48& f)
+{
+ return f.m;
+}
+
+inline const twolongs& mantissa(const Fix48& f)
+{
+ return f.m;
+}
+
+inline double value(const Fix48& f)
+{
+ return double(f);
+}
+
+inline Fix48 Fix48::operator+() const
+{
+ return m;
+}
+
+inline Fix48 Fix48::operator-() const
+{
+ twolongs n;
+ n.l = -m.l;
+ n.u = ~m.u + ((n.l ^ m.l) & Fix24_msb ? 0 : Fix24_lsb);
+ return Fix48(n);
+}
+
+inline Fix48 operator*(int b, const Fix48& a)
+{
+ return a * b;
+}
+
+inline Fix48& Fix48::operator+=(const Fix48& f)
+{
+ return *this = *this + f;
+}
+
+inline Fix48& Fix48::operator-=(const Fix48& f)
+{
+ return *this = *this - f;
+}
+
+inline Fix48& Fix48::operator*=(int b)
+{
+ return *this = *this * b;
+}
+
+inline Fix48& Fix48::operator<<=(int b)
+{
+ return *this = *this << b;
+}
+
+inline Fix48& Fix48::operator>>=(int b)
+{
+ return *this = *this >> b;
+}
+
+inline int operator==(const Fix48& f, const Fix48& g)
+{
+ return f.m.u == g.m.u && f.m.l == g.m.l;
+}
+
+inline int operator!=(const Fix48& f, const Fix48& g)
+{
+ return f.m.u != g.m.u || f.m.l != g.m.l;
+}
+
+inline int operator>=(const Fix48& f, const Fix48& g)
+{
+ return f.m.u >= g.m.u || (f.m.u == g.m.u && f.m.l >= g.m.l);
+}
+
+inline int operator<=(const Fix48& f, const Fix48& g)
+{
+ return f.m.u <= g.m.u || (f.m.u == g.m.u && f.m.l <= g.m.l);
+}
+
+inline int operator>(const Fix48& f, const Fix48& g)
+{
+ return f.m.u > g.m.u || (f.m.u == g.m.u && f.m.l > g.m.l);
+}
+
+inline int operator<(const Fix48& f, const Fix48& g)
+{
+ return f.m.u < g.m.u || (f.m.u == g.m.u && f.m.l < g.m.l);
+}
+
+inline istream& operator>>(istream& s, Fix48& f)
+{
+ double d;
+ s >> d;
+ f = d;
+ return s;
+}
+
+inline ostream& operator<<(ostream& s, const Fix48& f)
+{
+ return s << double(f);
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Geom.cc b/gnu/lib/libg++/g++-include/Geom.cc
new file mode 100644
index 00000000000..0353738a3dd
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Geom.cc
@@ -0,0 +1,30 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Geom.h>
+
+double Geometric::operator()()
+{
+ int samples;
+ for (samples = 1; pGenerator -> asDouble() < pMean; samples++);
+ return((double) samples);
+}
+
diff --git a/gnu/lib/libg++/g++-include/Geom.h b/gnu/lib/libg++/g++-include/Geom.h
new file mode 100644
index 00000000000..ba920184b79
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Geom.h
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Geom.h,v 1.1 1995/10/18 08:38:16 deraadt Exp $
+*/
+
+#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++/g++-include/GetOpt.cc b/gnu/lib/libg++/g++-include/GetOpt.cc
new file mode 100644
index 00000000000..16c647ddb6c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/GetOpt.cc
@@ -0,0 +1,253 @@
+/*
+Getopt for GNU.
+Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+(Modified by Douglas C. Schmidt for use with GNU G++.)
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+/* AIX requires the alloca decl to be the first thing in the file. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#elif defined(sparc)
+#include <alloca.h>
+extern "C" void *__builtin_alloca(...);
+#elif defined(_AIX)
+#pragma alloca
+#else
+char *alloca ();
+#endif
+#include <GetOpt.h>
+
+char* GetOpt::nextchar = 0;
+int GetOpt::first_nonopt = 0;
+int GetOpt::last_nonopt = 0;
+
+GetOpt::GetOpt (int argc, char **argv, const char *optstring)
+ :opterr (1), nargc (argc), nargv (argv), noptstring (optstring)
+{
+ /* Initialize the internal data when the first call is made.
+ Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind = 1;
+ optarg = nextchar = 0;
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ ordering = RETURN_IN_ORDER;
+ else if (getenv ("_POSIX_OPTION_ORDER") != 0)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+}
+
+void
+GetOpt::exchange (char **argv)
+{
+ int nonopts_size
+ = (last_nonopt - first_nonopt) * sizeof (char *);
+ char **temp = (char **) alloca (nonopts_size);
+
+ /* Interchange the two blocks of data in argv. */
+
+ memcpy (temp, &argv[first_nonopt], nonopts_size);
+ memcpy (&argv[first_nonopt], &argv[last_nonopt],
+ (optind - last_nonopt) * sizeof (char *));
+ memcpy (&argv[first_nonopt + optind - last_nonopt], temp,
+ nonopts_size);
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of theoption characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns `EOF'.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ A colon in OPTSTRING means that the previous character is an option
+ that wants an argument. The argument is taken from the rest of the
+ current ARGV-element, or from the following ARGV-element,
+ and returned in `optarg'.
+
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg'.
+
+ If OPTSTRING starts with `-', it requests a different method of handling the
+ non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
+
+int
+GetOpt::operator () (void)
+{
+ if (nextchar == 0 || *nextchar == 0)
+ {
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange (nargv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Now skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < nargc
+ && (nargv[optind][0] != '-'
+ || nargv[optind][1] == 0))
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* Special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != nargc && !strcmp (nargv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange (nargv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = nargc;
+
+ optind = nargc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == nargc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return EOF;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (nargv[optind][0] != '-' || nargv[optind][1] == 0)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return EOF;
+ optarg = nargv[optind++];
+ return 0;
+ }
+
+ /* We have found another option-ARGV-element.
+ Start decoding its characters. */
+
+ nextchar = nargv[optind] + 1;
+ }
+
+ /* Look at and handle the next option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = (char *) strchr (noptstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == 0)
+ optind++;
+
+ if (temp == 0 || c == ':')
+ {
+ if (opterr != 0)
+ {
+ if (c < 040 || c >= 0177)
+ fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+ nargv[0], c);
+ else
+ fprintf (stderr, "%s: unrecognized option `-%c'\n",
+ nargv[0], c);
+ }
+ return '?';
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != 0)
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = 0;
+ nextchar = 0;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != 0)
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == nargc)
+ {
+ if (opterr != 0)
+ fprintf (stderr, "%s: no argument for `-%c' option\n",
+ nargv[0], c);
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = nargv[optind++];
+ nextchar = 0;
+ }
+ }
+ return c;
+ }
+}
diff --git a/gnu/lib/libg++/g++-include/GetOpt.h b/gnu/lib/libg++/g++-include/GetOpt.h
new file mode 100644
index 00000000000..fa5cd2e8094
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/GetOpt.h
@@ -0,0 +1,130 @@
+/* Getopt for GNU.
+ Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+ (Modified by Douglas C. Schmidt for use with GNU G++.)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: GetOpt.h,v 1.1 1995/10/18 08:38:16 deraadt Exp $
+*/
+
+/* 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++/g++-include/HypGeom.cc b/gnu/lib/libg++/g++-include/HypGeom.cc
new file mode 100644
index 00000000000..50d95867d3d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/HypGeom.cc
@@ -0,0 +1,30 @@
+
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <HypGeom.h>
+
+double HyperGeometric::operator()()
+{
+ double d = (pGenerator -> asDouble() > pP) ? (1.0 - pP) : (pP);
+ return(-pMean * log(pGenerator -> asDouble()) / (2.0 * d) );
+}
+
diff --git a/gnu/lib/libg++/g++-include/HypGeom.h b/gnu/lib/libg++/g++-include/HypGeom.h
new file mode 100644
index 00000000000..97e59b98460
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/HypGeom.h
@@ -0,0 +1,73 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: HypGeom.h,v 1.1 1995/10/18 08:38:16 deraadt Exp $
+*/
+
+#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++/g++-include/Integer.cc b/gnu/lib/libg++/g++-include/Integer.cc
new file mode 100644
index 00000000000..f4ec47e6699
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Integer.cc
@@ -0,0 +1,2423 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ Some of the following algorithms are very loosely based on those from
+ MIT C-Scheme bignum.c, which is
+ Copyright (c) 1987 Massachusetts Institute of Technology
+
+ with other guidance from Knuth, vol. 2
+
+ Thanks to the creators of the algorithms.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <ctype.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <Obstack.h>
+#include <AllocRing.h>
+#include <new.h>
+#include <builtin.h>
+#include <Integer.h>
+
+#ifndef HUGE_VAL
+#ifdef HUGE
+#define HUGE_VAL HUGE
+#else
+#define HUGE_VAL DBL_MAX
+#endif
+#endif
+
+/*
+ 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
+
+IntRep _ZeroRep = {1, 0, 1, {0}};
+IntRep _OneRep = {1, 0, 1, {1}};
+IntRep _MinusOneRep = {1, 0, 0, {1}};
+
+
+// utilities to extract and transfer bits
+
+// get low bits
+
+inline static unsigned short extract(unsigned long x)
+{
+ return x & I_MAXNUM;
+}
+
+// transfer high bits to low
+
+inline static unsigned long down(unsigned long x)
+{
+ return (x >> I_SHIFT) & I_MAXNUM;
+}
+
+// transfer low bits to high
+
+inline static unsigned long up(unsigned long x)
+{
+ return x << I_SHIFT;
+}
+
+// compare two equal-length reps
+
+inline static int docmp(const unsigned short* x, const unsigned short* y, int l)
+{
+ int diff = 0;
+ const unsigned short* xs = &(x[l]);
+ const unsigned short* ys = &(y[l]);
+ while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
+ return diff;
+}
+
+// figure out max length of result of +, -, etc.
+
+inline static int calc_len(int len1, int len2, int pad)
+{
+ return (len1 >= len2)? len1 + pad : len2 + pad;
+}
+
+// ensure len & sgn are correct
+
+inline static void Icheck(IntRep* rep)
+{
+ int l = rep->len;
+ const unsigned short* p = &(rep->s[l]);
+ while (l > 0 && *--p == 0) --l;
+ if ((rep->len = l) == 0) rep->sgn = I_POSITIVE;
+}
+
+
+// zero out the end of a rep
+
+inline static void Iclear_from(IntRep* rep, int p)
+{
+ unsigned short* cp = &(rep->s[p]);
+ const unsigned short* cf = &(rep->s[rep->len]);
+ while(cp < cf) *cp++ = 0;
+}
+
+// copy parts of a rep
+
+static inline void scpy(const unsigned short* src, unsigned short* dest,int nb)
+{
+ while (--nb >= 0) *dest++ = *src++;
+}
+
+// make sure an argument is valid
+
+static inline void nonnil(const IntRep* rep)
+{
+ if (rep == 0)
+ (*lib_error_handler)("Integer", "operation on uninitialized Integer");
+}
+
+// allocate a new Irep. Pad to something close to a power of two.
+
+inline static IntRep* Inew(int newlen)
+{
+ unsigned int siz = sizeof(IntRep) + newlen * sizeof(short) +
+ MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINIntRep_SIZE;
+ while (allocsiz < siz) allocsiz <<= 1; // find a power of 2
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXIntRep_SIZE * sizeof(short))
+ (*lib_error_handler)("Integer", "Requested length out of range");
+
+ IntRep* rep = (IntRep *) new char[allocsiz];
+ rep->sz = (allocsiz - sizeof(IntRep) + sizeof(short)) / sizeof(short);
+ return rep;
+}
+
+// allocate: use the bits in src if non-null, clear the rest
+
+IntRep* Ialloc(IntRep* old, const unsigned short* src, int srclen, int newsgn,
+ int newlen)
+{
+ IntRep* rep;
+ if (old == 0 || newlen > old->sz)
+ rep = Inew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->sgn = newsgn;
+
+ scpy(src, rep->s, srclen);
+ Iclear_from(rep, srclen);
+
+ if (old != rep && old != 0 && !STATIC_IntRep(old)) delete old;
+ return rep;
+}
+
+// allocate and clear
+
+IntRep* Icalloc(IntRep* old, int newlen)
+{
+ IntRep* rep;
+ if (old == 0 || newlen > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ rep = Inew(newlen);
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->sgn = I_POSITIVE;
+ Iclear_from(rep, 0);
+
+ return rep;
+}
+
+// reallocate
+
+IntRep* Iresize(IntRep* old, int newlen)
+{
+ IntRep* rep;
+ unsigned short oldlen;
+ if (old == 0)
+ {
+ oldlen = 0;
+ rep = Inew(newlen);
+ rep->sgn = I_POSITIVE;
+ }
+ else
+ {
+ oldlen = old->len;
+ if (newlen > old->sz)
+ {
+ rep = Inew(newlen);
+ scpy(old->s, rep->s, oldlen);
+ rep->sgn = old->sgn;
+ if (!STATIC_IntRep(old)) delete old;
+ }
+ else
+ rep = old;
+ }
+
+ rep->len = newlen;
+ Iclear_from(rep, oldlen);
+
+ return rep;
+}
+
+
+// same, for straight copy
+
+IntRep* Icopy(IntRep* old, const IntRep* src)
+{
+ if (old == src) return old;
+ IntRep* rep;
+ if (src == 0)
+ {
+ if (old == 0)
+ rep = Inew(0);
+ else
+ {
+ rep = old;
+ Iclear_from(rep, 0);
+ }
+ rep->len = 0;
+ rep->sgn = I_POSITIVE;
+ }
+ else
+ {
+ int newlen = src->len;
+ if (old == 0 || newlen > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ rep = Inew(newlen);
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+ rep->sgn = src->sgn;
+
+ scpy(src->s, rep->s, newlen);
+ }
+
+ return rep;
+}
+
+// allocate & copy space for a long
+
+IntRep* Icopy_long(IntRep* old, long x)
+{
+ int newsgn = (x >= 0);
+ IntRep* rep = Icopy_ulong(old, newsgn ? x : -x);
+ rep->sgn = newsgn;
+ return rep;
+}
+
+IntRep* Icopy_ulong(IntRep* old, unsigned long x)
+{
+ unsigned short src[SHORT_PER_LONG];
+
+ unsigned short srclen = 0;
+ while (x != 0)
+ {
+ src[srclen++] = extract(x);
+ x = down(x);
+ }
+
+ IntRep* rep;
+ if (old == 0 || srclen > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ rep = Inew(srclen);
+ }
+ else
+ rep = old;
+
+ rep->len = srclen;
+ rep->sgn = I_POSITIVE;
+
+ scpy(src, rep->s, srclen);
+
+ return rep;
+}
+
+// special case for zero -- it's worth it!
+
+IntRep* Icopy_zero(IntRep* old)
+{
+ if (old == 0 || STATIC_IntRep(old))
+ return &_ZeroRep;
+
+ old->len = 0;
+ old->sgn = I_POSITIVE;
+
+ return old;
+}
+
+// special case for 1 or -1
+
+IntRep* Icopy_one(IntRep* old, int newsgn)
+{
+ if (old == 0 || 1 > old->sz)
+ {
+ if (old != 0 && !STATIC_IntRep(old)) delete old;
+ return newsgn==I_NEGATIVE ? &_MinusOneRep : &_OneRep;
+ }
+
+ old->sgn = newsgn;
+ old->len = 1;
+ old->s[0] = 1;
+
+ return old;
+}
+
+// convert to a legal two's complement long if possible
+// if too big, return most negative/positive value
+
+long Itolong(const IntRep* rep)
+{
+ if ((unsigned)(rep->len) > (unsigned)(SHORT_PER_LONG))
+ return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
+ else if (rep->len == 0)
+ return 0;
+ else if ((unsigned)(rep->len) < (unsigned)(SHORT_PER_LONG))
+ {
+ unsigned long a = rep->s[rep->len-1];
+ if (SHORT_PER_LONG > 2) // normally optimized out
+ {
+ for (int i = rep->len - 2; i >= 0; --i)
+ a = up(a) | rep->s[i];
+ }
+ return (rep->sgn == I_POSITIVE)? a : -((long)a);
+ }
+ else
+ {
+ unsigned long a = rep->s[SHORT_PER_LONG - 1];
+ if (a >= I_MINNUM)
+ return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
+ else
+ {
+ a = up(a) | rep->s[SHORT_PER_LONG - 2];
+ if (SHORT_PER_LONG > 2)
+ {
+ for (int i = SHORT_PER_LONG - 3; i >= 0; --i)
+ a = up(a) | rep->s[i];
+ }
+ return (rep->sgn == I_POSITIVE)? a : -((long)a);
+ }
+ }
+}
+
+// test whether op long() will work.
+// careful about asymmetry between LONG_MIN & LONG_MAX
+
+int Iislong(const IntRep* rep)
+{
+ unsigned int l = rep->len;
+ if (l < SHORT_PER_LONG)
+ return 1;
+ else if (l > SHORT_PER_LONG)
+ return 0;
+ else if ((unsigned)(rep->s[SHORT_PER_LONG - 1]) < (unsigned)(I_MINNUM))
+ return 1;
+ else if (rep->sgn == I_NEGATIVE && rep->s[SHORT_PER_LONG - 1] == I_MINNUM)
+ {
+ for (unsigned int i = 0; i < SHORT_PER_LONG - 1; ++i)
+ if (rep->s[i] != 0)
+ return 0;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+// 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;
+ }
+}
+
+// comparison functions
+
+int compare(const IntRep* x, const IntRep* y)
+{
+ int diff = x->sgn - y->sgn;
+ if (diff == 0)
+ {
+ diff = x->len - y->len;
+ if (diff == 0)
+ diff = docmp(x->s, y->s, x->len);
+ if (x->sgn == I_NEGATIVE)
+ diff = -diff;
+ }
+ return diff;
+}
+
+int ucompare(const IntRep* x, const IntRep* y)
+{
+ int diff = x->len - y->len;
+ if (diff == 0)
+ {
+ int l = x->len;
+ const unsigned short* xs = &(x->s[l]);
+ const unsigned short* ys = &(y->s[l]);
+ while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
+ }
+ return diff;
+}
+
+int compare(const IntRep* x, long y)
+{
+ int xl = x->len;
+ int xsgn = x->sgn;
+ if (y == 0)
+ {
+ if (xl == 0)
+ return 0;
+ else if (xsgn == I_NEGATIVE)
+ return -1;
+ else
+ return 1;
+ }
+ else
+ {
+ int ysgn = y >= 0;
+ unsigned long uy = (ysgn)? y : -y;
+ int diff = xsgn - ysgn;
+ if (diff == 0)
+ {
+ diff = xl - SHORT_PER_LONG;
+ if (diff <= 0)
+ {
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+ diff = xl - yl;
+ if (diff == 0)
+ diff = docmp(x->s, tmp, xl);
+ }
+ if (xsgn == I_NEGATIVE)
+ diff = -diff;
+ }
+ return diff;
+ }
+}
+
+int ucompare(const IntRep* x, long y)
+{
+ int xl = x->len;
+ if (y == 0)
+ return xl;
+ else
+ {
+ unsigned long uy = (y >= 0)? y : -y;
+ int diff = xl - SHORT_PER_LONG;
+ if (diff <= 0)
+ {
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+ diff = xl - yl;
+ if (diff == 0)
+ diff = docmp(x->s, tmp, xl);
+ }
+ return diff;
+ }
+}
+
+
+
+// arithmetic functions
+
+IntRep* add(const IntRep* x, int negatex,
+ const IntRep* y, int negatey, IntRep* r)
+{
+ nonnil(x);
+ nonnil(y);
+
+ int xl = x->len;
+ int yl = y->len;
+
+ int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
+ int ysgn = (negatey && yl != 0) ? !y->sgn : y->sgn;
+
+ int xrsame = x == r;
+ int yrsame = y == r;
+
+ if (yl == 0)
+ r = Ialloc(r, x->s, xl, xsgn, xl);
+ else if (xl == 0)
+ r = Ialloc(r, y->s, yl, ysgn, yl);
+ else if (xsgn == ysgn)
+ {
+ if (xrsame || yrsame)
+ r = Iresize(r, calc_len(xl, yl, 1));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 1));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topa;
+ const unsigned short* topb;
+ if (xl >= yl)
+ {
+ as = (xrsame)? r->s : x->s;
+ topa = &(as[xl]);
+ bs = (yrsame)? r->s : y->s;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ bs = (xrsame)? r->s : x->s;
+ topb = &(bs[xl]);
+ as = (yrsame)? r->s : y->s;
+ topa = &(as[yl]);
+ }
+ unsigned long sum = 0;
+ while (bs < topb)
+ {
+ sum += (unsigned long)(*as++) + (unsigned long)(*bs++);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && as < topa)
+ {
+ sum += (unsigned long)(*as++);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ if (sum != 0)
+ *rs = extract(sum);
+ else if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ else
+ {
+ int comp = ucompare(x, y);
+ if (comp == 0)
+ r = Icopy_zero(r);
+ else
+ {
+ if (xrsame || yrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ unsigned short* rs = r->s;
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topa;
+ const unsigned short* topb;
+ if (comp > 0)
+ {
+ as = (xrsame)? r->s : x->s;
+ topa = &(as[xl]);
+ bs = (yrsame)? r->s : y->s;
+ topb = &(bs[yl]);
+ r->sgn = xsgn;
+ }
+ else
+ {
+ bs = (xrsame)? r->s : x->s;
+ topb = &(bs[xl]);
+ as = (yrsame)? r->s : y->s;
+ topa = &(as[yl]);
+ r->sgn = ysgn;
+ }
+ unsigned long hi = 1;
+ while (bs < topb)
+ {
+ hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ while (hi == 0 && as < topa)
+ {
+ hi = (unsigned long)(*as++) + I_MAXNUM;
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+
+IntRep* add(const IntRep* x, int negatex, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+ int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
+ int xrsame = x == r;
+
+ int ysgn = (y >= 0);
+ unsigned long uy = (ysgn)? y : -y;
+
+ if (y == 0)
+ r = Ialloc(r, x->s, xl, xsgn, xl);
+ else if (xl == 0)
+ r = Icopy_long(r, y);
+ else if (xsgn == ysgn)
+ {
+ if (xrsame)
+ r = Iresize(r, calc_len(xl, SHORT_PER_LONG, 1));
+ else
+ r = Icalloc(r, calc_len(xl, SHORT_PER_LONG, 1));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ const unsigned short* as = (xrsame)? r->s : x->s;
+ const unsigned short* topa = &(as[xl]);
+ unsigned long sum = 0;
+ while (as < topa && uy != 0)
+ {
+ unsigned long u = extract(uy);
+ uy = down(uy);
+ sum += (unsigned long)(*as++) + u;
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && as < topa)
+ {
+ sum += (unsigned long)(*as++);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ if (sum != 0)
+ *rs = extract(sum);
+ else if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ else
+ {
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+ int comp = xl - yl;
+ if (comp == 0)
+ comp = docmp(x->s, tmp, yl);
+ if (comp == 0)
+ r = Icopy_zero(r);
+ else
+ {
+ if (xrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ unsigned short* rs = r->s;
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topa;
+ const unsigned short* topb;
+ if (comp > 0)
+ {
+ as = (xrsame)? r->s : x->s;
+ topa = &(as[xl]);
+ bs = tmp;
+ topb = &(bs[yl]);
+ r->sgn = xsgn;
+ }
+ else
+ {
+ bs = (xrsame)? r->s : x->s;
+ topb = &(bs[xl]);
+ as = tmp;
+ topa = &(as[yl]);
+ r->sgn = ysgn;
+ }
+ unsigned long hi = 1;
+ while (bs < topb)
+ {
+ hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ while (hi == 0 && as < topa)
+ {
+ hi = (unsigned long)(*as++) + I_MAXNUM;
+ *rs++ = extract(hi);
+ hi = down(hi);
+ }
+ if (rs != as)
+ while (as < topa)
+ *rs++ = *as++;
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+
+IntRep* multiply(const IntRep* x, const IntRep* y, IntRep* r)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ int rl = xl + yl;
+ int rsgn = x->sgn == y->sgn;
+ int xrsame = x == r;
+ int yrsame = y == r;
+ int xysame = x == y;
+
+ if (xl == 0 || yl == 0)
+ r = Icopy_zero(r);
+ else if (xl == 1 && x->s[0] == 1)
+ r = Icopy(r, y);
+ else if (yl == 1 && y->s[0] == 1)
+ r = Icopy(r, x);
+ else if (!(xysame && xrsame))
+ {
+ if (xrsame || yrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+
+ // use best inner/outer loop params given constraints
+ unsigned short* currentr;
+ const unsigned short* bota;
+ const unsigned short* as;
+ const unsigned short* botb;
+ const unsigned short* topb;
+ if (xrsame)
+ {
+ currentr = &(rs[xl-1]);
+ bota = rs;
+ as = currentr;
+ botb = y->s;
+ topb = &(botb[yl]);
+ }
+ else if (yrsame)
+ {
+ currentr = &(rs[yl-1]);
+ bota = rs;
+ as = currentr;
+ botb = x->s;
+ topb = &(botb[xl]);
+ }
+ else if (xl <= yl)
+ {
+ currentr = &(rs[xl-1]);
+ bota = x->s;
+ as = &(bota[xl-1]);
+ botb = y->s;
+ topb = &(botb[yl]);
+ }
+ else
+ {
+ currentr = &(rs[yl-1]);
+ bota = y->s;
+ as = &(bota[yl-1]);
+ botb = x->s;
+ topb = &(botb[xl]);
+ }
+
+ while (as >= bota)
+ {
+ unsigned long ai = (unsigned long)(*as--);
+ unsigned short* rs = currentr--;
+ *rs = 0;
+ if (ai != 0)
+ {
+ unsigned long sum = 0;
+ const unsigned short* bs = botb;
+ while (bs < topb)
+ {
+ sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && rs < topr)
+ {
+ sum += (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ }
+ }
+ }
+ else // x, y, and r same; compute over diagonals
+ {
+ r = Iresize(r, rl);
+ unsigned short* botr = r->s;
+ unsigned short* topr = &(botr[rl]);
+ unsigned short* rs = &(botr[rl - 2]);
+
+ const unsigned short* bota = (xrsame)? botr : x->s;
+ const unsigned short* loa = &(bota[xl - 1]);
+ const unsigned short* hia = loa;
+
+ for (; rs >= botr; --rs)
+ {
+ const unsigned short* h = hia;
+ const unsigned short* l = loa;
+ unsigned long prod = (unsigned long)(*h) * (unsigned long)(*l);
+ *rs = 0;
+
+ for(;;)
+ {
+ unsigned short* rt = rs;
+ unsigned long sum = prod + (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ while (sum != 0 && rt < topr)
+ {
+ sum += (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ }
+ if (h > l)
+ {
+ rt = rs;
+ sum = prod + (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ while (sum != 0 && rt < topr)
+ {
+ sum += (unsigned long)(*rt);
+ *rt++ = extract(sum);
+ sum = down(sum);
+ }
+ if (--h >= ++l)
+ prod = (unsigned long)(*h) * (unsigned long)(*l);
+ else
+ break;
+ }
+ else
+ break;
+ }
+ if (loa > bota)
+ --loa;
+ else
+ --hia;
+ }
+ }
+ r->sgn = rsgn;
+ Icheck(r);
+ return r;
+}
+
+
+IntRep* multiply(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+
+ if (xl == 0 || y == 0)
+ r = Icopy_zero(r);
+ else if (y == 1)
+ r = Icopy(r, x);
+ else
+ {
+ int ysgn = y >= 0;
+ int rsgn = x->sgn == ysgn;
+ unsigned long uy = (ysgn)? y : -y;
+ unsigned short tmp[SHORT_PER_LONG];
+ int yl = 0;
+ while (uy != 0)
+ {
+ tmp[yl++] = extract(uy);
+ uy = down(uy);
+ }
+
+ int rl = xl + yl;
+ int xrsame = x == r;
+ if (xrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+ unsigned short* currentr;
+ const unsigned short* bota;
+ const unsigned short* as;
+ const unsigned short* botb;
+ const unsigned short* topb;
+
+ if (xrsame)
+ {
+ currentr = &(rs[xl-1]);
+ bota = rs;
+ as = currentr;
+ botb = tmp;
+ topb = &(botb[yl]);
+ }
+ else if (xl <= yl)
+ {
+ currentr = &(rs[xl-1]);
+ bota = x->s;
+ as = &(bota[xl-1]);
+ botb = tmp;
+ topb = &(botb[yl]);
+ }
+ else
+ {
+ currentr = &(rs[yl-1]);
+ bota = tmp;
+ as = &(bota[yl-1]);
+ botb = x->s;
+ topb = &(botb[xl]);
+ }
+
+ while (as >= bota)
+ {
+ unsigned long ai = (unsigned long)(*as--);
+ unsigned short* rs = currentr--;
+ *rs = 0;
+ if (ai != 0)
+ {
+ unsigned long sum = 0;
+ const unsigned short* bs = botb;
+ while (bs < topb)
+ {
+ sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ while (sum != 0 && rs < topr)
+ {
+ sum += (unsigned long)(*rs);
+ *rs++ = extract(sum);
+ sum = down(sum);
+ }
+ }
+ }
+ r->sgn = rsgn;
+ }
+ Icheck(r);
+ return r;
+}
+
+
+// main division routine
+
+static void do_divide(unsigned short* rs,
+ const unsigned short* ys, int yl,
+ unsigned short* qs, int ql)
+{
+ const unsigned short* topy = &(ys[yl]);
+ unsigned short d1 = ys[yl - 1];
+ unsigned short d2 = ys[yl - 2];
+
+ int l = ql - 1;
+ int i = l + yl;
+
+ for (; l >= 0; --l, --i)
+ {
+ unsigned short qhat; // guess q
+ if (d1 == rs[i])
+ qhat = I_MAXNUM;
+ else
+ {
+ unsigned long lr = up((unsigned long)rs[i]) | rs[i-1];
+ qhat = lr / d1;
+ }
+
+ for(;;) // adjust q, use docmp to avoid overflow problems
+ {
+ unsigned short ts[3];
+ unsigned long prod = (unsigned long)d2 * (unsigned long)qhat;
+ ts[0] = extract(prod);
+ prod = down(prod) + (unsigned long)d1 * (unsigned long)qhat;
+ ts[1] = extract(prod);
+ ts[2] = extract(down(prod));
+ if (docmp(ts, &(rs[i-2]), 3) > 0)
+ --qhat;
+ else
+ break;
+ };
+
+ // multiply & subtract
+
+ const unsigned short* yt = ys;
+ unsigned short* rt = &(rs[l]);
+ unsigned long prod = 0;
+ unsigned long hi = 1;
+ while (yt < topy)
+ {
+ prod = (unsigned long)qhat * (unsigned long)(*yt++) + down(prod);
+ hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(extract(prod));
+ *rt++ = extract(hi);
+ hi = down(hi);
+ }
+ hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(down(prod));
+ *rt = extract(hi);
+ hi = down(hi);
+
+ // off-by-one, add back
+
+ if (hi == 0)
+ {
+ --qhat;
+ yt = ys;
+ rt = &(rs[l]);
+ hi = 0;
+ while (yt < topy)
+ {
+ hi = (unsigned long)(*rt) + (unsigned long)(*yt++) + down(hi);
+ *rt++ = extract(hi);
+ }
+ *rt = 0;
+ }
+ if (qs != 0)
+ qs[l] = qhat;
+ }
+}
+
+// divide by single digit, return remainder
+// if q != 0, then keep the result in q, else just compute rem
+
+static int unscale(const unsigned short* x, int xl, unsigned short y,
+ unsigned short* q)
+{
+ if (xl == 0 || y == 1)
+ return 0;
+ else if (q != 0)
+ {
+ unsigned short* botq = q;
+ unsigned short* qs = &(botq[xl - 1]);
+ const unsigned short* xs = &(x[xl - 1]);
+ unsigned long rem = 0;
+ while (qs >= botq)
+ {
+ rem = up(rem) | *xs--;
+ unsigned long u = rem / y;
+ *qs-- = extract(u);
+ rem -= u * y;
+ }
+ int r = extract(rem);
+ return r;
+ }
+ else // same loop, a bit faster if just need rem
+ {
+ const unsigned short* botx = x;
+ const unsigned short* xs = &(botx[xl - 1]);
+ unsigned long rem = 0;
+ while (xs >= botx)
+ {
+ rem = up(rem) | *xs--;
+ unsigned long u = rem / y;
+ rem -= u * y;
+ }
+ int r = extract(rem);
+ return r;
+ }
+}
+
+
+IntRep* div(const IntRep* x, const IntRep* y, IntRep* q)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ int comp = ucompare(x, y);
+ int xsgn = x->sgn;
+ int ysgn = y->sgn;
+
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ q = Icopy_zero(q);
+ else if (comp == 0)
+ q = Icopy_one(q, samesign);
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ unscale(q->s, q->len, y->s[0], q->s);
+ }
+ else
+ {
+ IntRep* yy = 0;
+ IntRep* r = 0;
+ unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
+ if (prescale != 1 || y == q)
+ {
+ yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ yy = (IntRep*)y;
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+ do_divide(r->s, yy->s, yl, q->s, ql);
+
+ if (yy != y && !STATIC_IntRep(yy)) delete yy;
+ if (!STATIC_IntRep(r)) delete r;
+ }
+ q->sgn = samesign;
+ Icheck(q);
+ return q;
+}
+
+IntRep* div(const IntRep* x, long y, IntRep* q)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ unsigned short ys[SHORT_PER_LONG];
+ unsigned long u;
+ int ysgn = y >= 0;
+ if (ysgn)
+ u = y;
+ else
+ u = -y;
+ int yl = 0;
+ while (u != 0)
+ {
+ ys[yl++] = extract(u);
+ u = down(u);
+ }
+
+ int comp = xl - yl;
+ if (comp == 0) comp = docmp(x->s, ys, xl);
+
+ int xsgn = x->sgn;
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ q = Icopy_zero(q);
+ else if (comp == 0)
+ {
+ q = Icopy_one(q, samesign);
+ }
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ unscale(q->s, q->len, ys[0], q->s);
+ }
+ else
+ {
+ IntRep* r = 0;
+ unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
+ if (prescale != 1)
+ {
+ unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
+ ys[0] = extract(prod);
+ prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
+ ys[1] = extract(prod);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+ do_divide(r->s, ys, yl, q->s, ql);
+
+ if (!STATIC_IntRep(r)) delete r;
+ }
+ q->sgn = samesign;
+ Icheck(q);
+ return q;
+}
+
+
+void divide(const Integer& Ix, long y, Integer& Iq, long& rem)
+{
+ const IntRep* x = Ix.rep;
+ nonnil(x);
+ IntRep* q = Iq.rep;
+ int xl = x->len;
+ if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ unsigned short ys[SHORT_PER_LONG];
+ unsigned long u;
+ int ysgn = y >= 0;
+ if (ysgn)
+ u = y;
+ else
+ u = -y;
+ int yl = 0;
+ while (u != 0)
+ {
+ ys[yl++] = extract(u);
+ u = down(u);
+ }
+
+ int comp = xl - yl;
+ if (comp == 0) comp = docmp(x->s, ys, xl);
+
+ int xsgn = x->sgn;
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ {
+ rem = Itolong(x);
+ q = Icopy_zero(q);
+ }
+ else if (comp == 0)
+ {
+ q = Icopy_one(q, samesign);
+ rem = 0;
+ }
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ rem = unscale(q->s, q->len, ys[0], q->s);
+ }
+ else
+ {
+ IntRep* r = 0;
+ unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
+ if (prescale != 1)
+ {
+ unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
+ ys[0] = extract(prod);
+ prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
+ ys[1] = extract(prod);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+
+ do_divide(r->s, ys, yl, q->s, ql);
+
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ Icheck(r);
+ rem = Itolong(r);
+ if (!STATIC_IntRep(r)) delete r;
+ }
+ rem = abs(rem);
+ if (xsgn == I_NEGATIVE) rem = -rem;
+ q->sgn = samesign;
+ Icheck(q);
+ Iq.rep = q;
+}
+
+
+void divide(const Integer& Ix, const Integer& Iy, Integer& Iq, Integer& Ir)
+{
+ const IntRep* x = Ix.rep;
+ nonnil(x);
+ const IntRep* y = Iy.rep;
+ nonnil(y);
+ IntRep* q = Iq.rep;
+ IntRep* r = Ir.rep;
+
+ int xl = x->len;
+ int yl = y->len;
+ if (yl == 0)
+ (*lib_error_handler)("Integer", "attempted division by zero");
+
+ int comp = ucompare(x, y);
+ int xsgn = x->sgn;
+ int ysgn = y->sgn;
+
+ int samesign = xsgn == ysgn;
+
+ if (comp < 0)
+ {
+ q = Icopy_zero(q);
+ r = Icopy(r, x);
+ }
+ else if (comp == 0)
+ {
+ q = Icopy_one(q, samesign);
+ r = Icopy_zero(r);
+ }
+ else if (yl == 1)
+ {
+ q = Icopy(q, x);
+ int rem = unscale(q->s, q->len, y->s[0], q->s);
+ r = Icopy_long(r, rem);
+ if (rem != 0)
+ r->sgn = xsgn;
+ }
+ else
+ {
+ IntRep* yy = 0;
+ unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
+ if (prescale != 1 || y == q || y == r)
+ {
+ yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ yy = (IntRep*)y;
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ int ql = xl - yl + 1;
+
+ q = Icalloc(q, ql);
+ do_divide(r->s, yy->s, yl, q->s, ql);
+
+ if (yy != y && !STATIC_IntRep(yy)) delete yy;
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ }
+ q->sgn = samesign;
+ Icheck(q);
+ Iq.rep = q;
+ Icheck(r);
+ Ir.rep = r;
+}
+
+IntRep* mod(const IntRep* x, const IntRep* y, IntRep* r)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ int comp = ucompare(x, y);
+ int xsgn = x->sgn;
+
+ if (comp < 0)
+ r = Icopy(r, x);
+ else if (comp == 0)
+ r = Icopy_zero(r);
+ else if (yl == 1)
+ {
+ int rem = unscale(x->s, xl, y->s[0], 0);
+ r = Icopy_long(r, rem);
+ if (rem != 0)
+ r->sgn = xsgn;
+ }
+ else
+ {
+ IntRep* yy = 0;
+ unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
+ if (prescale != 1 || y == r)
+ {
+ yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ yy = (IntRep*)y;
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ do_divide(r->s, yy->s, yl, 0, xl - yl + 1);
+
+ if (yy != y && !STATIC_IntRep(yy)) delete yy;
+
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+IntRep* mod(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
+
+ unsigned short ys[SHORT_PER_LONG];
+ unsigned long u;
+ int ysgn = y >= 0;
+ if (ysgn)
+ u = y;
+ else
+ u = -y;
+ int yl = 0;
+ while (u != 0)
+ {
+ ys[yl++] = extract(u);
+ u = down(u);
+ }
+
+ int comp = xl - yl;
+ if (comp == 0) comp = docmp(x->s, ys, xl);
+
+ int xsgn = x->sgn;
+
+ if (comp < 0)
+ r = Icopy(r, x);
+ else if (comp == 0)
+ r = Icopy_zero(r);
+ else if (yl == 1)
+ {
+ int rem = unscale(x->s, xl, ys[0], 0);
+ r = Icopy_long(r, rem);
+ if (rem != 0)
+ r->sgn = xsgn;
+ }
+ else
+ {
+ unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
+ if (prescale != 1)
+ {
+ unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
+ ys[0] = extract(prod);
+ prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
+ ys[1] = extract(prod);
+ r = multiply(x, ((long)prescale & I_MAXNUM), r);
+ }
+ else
+ {
+ r = Icalloc(r, xl + 1);
+ scpy(x->s, r->s, xl);
+ }
+
+ do_divide(r->s, ys, yl, 0, xl - yl + 1);
+
+ if (prescale != 1)
+ {
+ Icheck(r);
+ unscale(r->s, r->len, prescale, r->s);
+ }
+ }
+ Icheck(r);
+ return r;
+}
+
+IntRep* lshift(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (xl == 0 || y == 0)
+ {
+ r = Icopy(r, x);
+ return r;
+ }
+
+ int xrsame = x == r;
+ int rsgn = x->sgn;
+
+ long ay = (y < 0)? -y : y;
+ int bw = ay / I_SHIFT;
+ int sw = ay % I_SHIFT;
+
+ if (y > 0)
+ {
+ int rl = bw + xl + 1;
+ if (xrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+
+ unsigned short* botr = r->s;
+ unsigned short* rs = &(botr[rl - 1]);
+ const unsigned short* botx = (xrsame)? botr : x->s;
+ const unsigned short* xs = &(botx[xl - 1]);
+ unsigned long a = 0;
+ while (xs >= botx)
+ {
+ a = up(a) | ((unsigned long)(*xs--) << sw);
+ *rs-- = extract(down(a));
+ }
+ *rs-- = extract(a);
+ while (rs >= botr)
+ *rs-- = 0;
+ }
+ else
+ {
+ int rl = xl - bw;
+ if (rl < 0)
+ r = Icopy_zero(r);
+ else
+ {
+ if (xrsame)
+ r = Iresize(r, rl);
+ else
+ r = Icalloc(r, rl);
+ int rw = I_SHIFT - sw;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[rl]);
+ const unsigned short* botx = (xrsame)? rs : x->s;
+ const unsigned short* xs = &(botx[bw]);
+ const unsigned short* topx = &(botx[xl]);
+ unsigned long a = (unsigned long)(*xs++) >> sw;
+ while (xs < topx)
+ {
+ a |= (unsigned long)(*xs++) << rw;
+ *rs++ = extract(a);
+ a = down(a);
+ }
+ *rs++ = extract(a);
+ if (xrsame) topr = (unsigned short*)topx;
+ while (rs < topr)
+ *rs++ = 0;
+ }
+ }
+ r->sgn = rsgn;
+ Icheck(r);
+ return r;
+}
+
+IntRep* lshift(const IntRep* x, const IntRep* yy, int negatey, IntRep* r)
+{
+ long y = Itolong(yy);
+ if (negatey)
+ y = -y;
+
+ return lshift(x, y, r);
+}
+
+IntRep* bitop(const IntRep* x, const IntRep* y, IntRep* r, char op)
+{
+ nonnil(x);
+ nonnil(y);
+ int xl = x->len;
+ int yl = y->len;
+ int xsgn = x->sgn;
+ int xrsame = x == r;
+ int yrsame = y == r;
+ if (xrsame || yrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[r->len]);
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topb;
+ if (xl >= yl)
+ {
+ as = (xrsame)? rs : x->s;
+ bs = (yrsame)? rs : y->s;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ bs = (xrsame)? rs : x->s;
+ topb = &(bs[xl]);
+ as = (yrsame)? rs : y->s;
+ }
+
+ switch (op)
+ {
+ case '&':
+ while (bs < topb) *rs++ = *as++ & *bs++;
+ while (rs < topr) *rs++ = 0;
+ break;
+ case '|':
+ while (bs < topb) *rs++ = *as++ | *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ case '^':
+ while (bs < topb) *rs++ = *as++ ^ *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ }
+ Icheck(r);
+ return r;
+}
+
+IntRep* bitop(const IntRep* x, long y, IntRep* r, char op)
+{
+ nonnil(x);
+ unsigned short tmp[SHORT_PER_LONG];
+ unsigned long u;
+ int newsgn;
+ if (newsgn = (y >= 0))
+ u = y;
+ else
+ u = -y;
+
+ int l = 0;
+ while (u != 0)
+ {
+ tmp[l++] = extract(u);
+ u = down(u);
+ }
+
+ int xl = x->len;
+ int yl = l;
+ int xsgn = x->sgn;
+ int xrsame = x == r;
+ if (xrsame)
+ r = Iresize(r, calc_len(xl, yl, 0));
+ else
+ r = Icalloc(r, calc_len(xl, yl, 0));
+ r->sgn = xsgn;
+ unsigned short* rs = r->s;
+ unsigned short* topr = &(rs[r->len]);
+ const unsigned short* as;
+ const unsigned short* bs;
+ const unsigned short* topb;
+ if (xl >= yl)
+ {
+ as = (xrsame)? rs : x->s;
+ bs = tmp;
+ topb = &(bs[yl]);
+ }
+ else
+ {
+ bs = (xrsame)? rs : x->s;
+ topb = &(bs[xl]);
+ as = tmp;
+ }
+
+ switch (op)
+ {
+ case '&':
+ while (bs < topb) *rs++ = *as++ & *bs++;
+ while (rs < topr) *rs++ = 0;
+ break;
+ case '|':
+ while (bs < topb) *rs++ = *as++ | *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ case '^':
+ while (bs < topb) *rs++ = *as++ ^ *bs++;
+ while (rs < topr) *rs++ = *as++;
+ break;
+ }
+ Icheck(r);
+ return r;
+}
+
+
+
+IntRep* compl(const IntRep* src, IntRep* r)
+{
+ nonnil(src);
+ r = Icopy(r, src);
+ unsigned short* s = r->s;
+ unsigned short* top = &(s[r->len - 1]);
+ while (s < top)
+ {
+ unsigned short cmp = ~(*s);
+ *s++ = cmp;
+ }
+ unsigned short a = *s;
+ unsigned short b = 0;
+ while (a != 0)
+ {
+ b <<= 1;
+ if (!(a & 1)) b |= 1;
+ a >>= 1;
+ }
+ *s = b;
+ Icheck(r);
+ return r;
+}
+
+void (setbit)(Integer& x, long b)
+{
+ if (b >= 0)
+ {
+ int bw = (unsigned long)b / I_SHIFT;
+ int sw = (unsigned long)b % I_SHIFT;
+ int xl = x.rep ? x.rep->len : 0;
+ if (xl <= bw)
+ x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));
+ x.rep->s[bw] |= (1 << sw);
+ Icheck(x.rep);
+ }
+}
+
+void clearbit(Integer& x, long b)
+{
+ if (b >= 0)
+ {
+ if (x.rep == 0)
+ x.rep = &_ZeroRep;
+ else
+ {
+ int bw = (unsigned long)b / I_SHIFT;
+ int sw = (unsigned long)b % I_SHIFT;
+ if (x.rep->len > bw)
+ x.rep->s[bw] &= ~(1 << sw);
+ }
+ Icheck(x.rep);
+ }
+}
+
+int testbit(const Integer& x, long b)
+{
+ if (x.rep != 0 && b >= 0)
+ {
+ int bw = (unsigned long)b / I_SHIFT;
+ int sw = (unsigned long)b % I_SHIFT;
+ return (bw < x.rep->len && (x.rep->s[bw] & (1 << sw)) != 0);
+ }
+ else
+ return 0;
+}
+
+// A version of knuth's algorithm B / ex. 4.5.3.34
+// A better version that doesn't bother shifting all of `t' forthcoming
+
+IntRep* gcd(const IntRep* x, const IntRep* y)
+{
+ nonnil(x);
+ nonnil(y);
+ int ul = x->len;
+ int vl = y->len;
+
+ if (vl == 0)
+ return Ialloc(0, x->s, ul, I_POSITIVE, ul);
+ else if (ul == 0)
+ return Ialloc(0, y->s, vl, I_POSITIVE, vl);
+
+ IntRep* u = Ialloc(0, x->s, ul, I_POSITIVE, ul);
+ IntRep* v = Ialloc(0, y->s, vl, I_POSITIVE, vl);
+
+// find shift so that both not even
+
+ long k = 0;
+ int l = (ul <= vl)? ul : vl;
+ int cont = 1;
+ for (int i = 0; i < l && cont; ++i)
+ {
+ unsigned long a = (i < ul)? u->s[i] : 0;
+ unsigned long b = (i < vl)? v->s[i] : 0;
+ for (int j = 0; j < I_SHIFT; ++j)
+ {
+ if ((a | b) & 1)
+ {
+ cont = 0;
+ break;
+ }
+ else
+ {
+ ++k;
+ a >>= 1;
+ b >>= 1;
+ }
+ }
+ }
+
+ if (k != 0)
+ {
+ u = lshift(u, -k, u);
+ v = lshift(v, -k, v);
+ }
+
+ IntRep* t;
+ if (u->s[0] & 01)
+ t = Ialloc(0, v->s, v->len, !v->sgn, v->len);
+ else
+ t = Ialloc(0, u->s, u->len, u->sgn, u->len);
+
+ while (t->len != 0)
+ {
+ long s = 0; // shift t until odd
+ cont = 1;
+ int tl = t->len;
+ for (i = 0; i < tl && cont; ++i)
+ {
+ unsigned long a = t->s[i];
+ for (int j = 0; j < I_SHIFT; ++j)
+ {
+ if (a & 1)
+ {
+ cont = 0;
+ break;
+ }
+ else
+ {
+ ++s;
+ a >>= 1;
+ }
+ }
+ }
+
+ if (s != 0) t = lshift(t, -s, t);
+
+ if (t->sgn == I_POSITIVE)
+ {
+ u = Icopy(u, t);
+ t = add(t, 0, v, 1, t);
+ }
+ else
+ {
+ v = Ialloc(v, t->s, t->len, !t->sgn, t->len);
+ t = add(t, 0, u, 0, t);
+ }
+ }
+ if (!STATIC_IntRep(t)) delete t;
+ if (!STATIC_IntRep(v)) delete v;
+ if (k != 0) u = lshift(u, k, u);
+ return u;
+}
+
+
+
+long lg(const IntRep* x)
+{
+ nonnil(x);
+ int xl = x->len;
+ if (xl == 0)
+ return 0;
+
+ long l = (xl - 1) * I_SHIFT - 1;
+ unsigned short a = x->s[xl-1];
+
+ while (a != 0)
+ {
+ a = a >> 1;
+ ++l;
+ }
+ return l;
+}
+
+IntRep* power(const IntRep* x, long y, IntRep* r)
+{
+ nonnil(x);
+ int sgn;
+ if (x->sgn == I_POSITIVE || (!(y & 1)))
+ sgn = I_POSITIVE;
+ else
+ sgn = I_NEGATIVE;
+
+ int xl = x->len;
+
+ if (y == 0 || (xl == 1 && x->s[0] == 1))
+ r = Icopy_one(r, sgn);
+ else if (xl == 0 || y < 0)
+ r = Icopy_zero(r);
+ else if (y == 1 || y == -1)
+ r = Icopy(r, x);
+ else
+ {
+ int maxsize = ((lg(x) + 1) * y) / I_SHIFT + 2; // pre-allocate space
+ IntRep* b = Ialloc(0, x->s, xl, I_POSITIVE, maxsize);
+ b->len = xl;
+ r = Icalloc(r, maxsize);
+ r = Icopy_one(r, I_POSITIVE);
+ for(;;)
+ {
+ if (y & 1)
+ r = multiply(r, b, r);
+ if ((y >>= 1) == 0)
+ break;
+ else
+ b = multiply(b, b, b);
+ }
+ if (!STATIC_IntRep(b)) delete b;
+ }
+ r->sgn = sgn;
+ Icheck(r);
+ return r;
+}
+
+IntRep* abs(const IntRep* src, IntRep* dest)
+{
+ nonnil(src);
+ if (src != dest)
+ dest = Icopy(dest, src);
+ dest->sgn = I_POSITIVE;
+ return dest;
+}
+
+IntRep* negate(const IntRep* src, IntRep* dest)
+{
+ nonnil(src);
+ if (src != dest)
+ dest = Icopy(dest, src);
+ if (dest->len != 0)
+ dest->sgn = !dest->sgn;
+ return dest;
+}
+
+#if defined(__GNUG__) && !defined(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;
+ int gap = s - p;
+ 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& s, Integer& y)
+{
+#ifdef _OLD_STREAMS
+ if (!s.good())
+ return s;
+#else
+ if (!s.ipfx(0))
+ {
+ s.clear(ios::failbit|s.rdstate());
+ return s;
+ }
+#endif
+ s >> ws;
+ if (!s.good())
+ {
+ s.clear(ios::failbit|s.rdstate());
+ return s;
+ }
+
+#ifdef _OLD_STREAMS
+ int know_base = 0;
+ int base = 10;
+#else
+ int know_base = s.flags() & (ios::oct | ios::hex | ios::dec);
+ int base = (s.flags() & ios::oct) ? 8 : (s.flags() & ios::hex) ? 16 : 10;
+#endif
+
+ int got_one = 0;
+ char sgn = 0;
+ char ch;
+ y.rep = Icopy_zero(y.rep);
+
+ while (s.get(ch))
+ {
+ if (ch == '-')
+ {
+ if (sgn == 0)
+ sgn = '-';
+ else
+ break;
+ }
+ else if (!know_base & !got_one && ch == '0')
+ base = 8, got_one = 1;
+ else if (!know_base & !got_one && base == 8 && (ch == 'X' || ch == 'x'))
+ base = 16;
+ else if (base == 8)
+ {
+ if (ch >= '0' && ch <= '7')
+ {
+ long digit = ch - '0';
+ y <<= 3;
+ y += digit;
+ got_one = 1;
+ }
+ else
+ break;
+ }
+ else if (base == 16)
+ {
+ long 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 = base;
+ if (digit < base)
+ {
+ y <<= 4;
+ y += digit;
+ got_one = 1;
+ }
+ else
+ break;
+ }
+ else if (base == 10)
+ {
+ if (ch >= '0' && ch <= '9')
+ {
+ long digit = ch - '0';
+ y *= 10;
+ y += digit;
+ got_one = 1;
+ }
+ else
+ break;
+ }
+ else
+ abort(); // can't happen for now
+ }
+ if (s.good())
+ s.putback(ch);
+ if (!got_one)
+ s.clear(ios::failbit|s.rdstate());
+
+ if (sgn == '-')
+ y.negate();
+
+ return s;
+}
+
+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++/g++-include/Integer.h b/gnu/lib/libg++/g++-include/Integer.h
new file mode 100644
index 00000000000..7f044c1af9e
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Integer.h
@@ -0,0 +1,1104 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Integer.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#ifndef _Integer_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Integer_h 1
+
+#include <iostream.h>
+
+struct IntRep // internal Integer representations
+{
+ unsigned short len; // current length
+ unsigned short sz; // allocated space (0 means static).
+ short sgn; // 1 means >= 0; 0 means < 0
+ unsigned short s[1]; // represented as ushort array starting here
+};
+
+// True if REP is staticly (or manually) allocated,
+// and should not be deleted by an Integer destructor.
+#define STATIC_IntRep(rep) ((rep)->sz==0)
+
+extern IntRep* Ialloc(IntRep*, const unsigned short *, int, int, int);
+extern IntRep* Icalloc(IntRep*, int);
+extern IntRep* Icopy_ulong(IntRep*, unsigned long);
+extern IntRep* Icopy_long(IntRep*, long);
+extern IntRep* Icopy(IntRep*, const IntRep*);
+extern IntRep* Iresize(IntRep*, int);
+extern IntRep* add(const IntRep*, int, const IntRep*, int, IntRep*);
+extern IntRep* add(const IntRep*, int, long, IntRep*);
+extern IntRep* multiply(const IntRep*, const IntRep*, IntRep*);
+extern IntRep* multiply(const IntRep*, long, IntRep*);
+extern IntRep* lshift(const IntRep*, long, IntRep*);
+extern IntRep* lshift(const IntRep*, const IntRep*, int, IntRep*);
+extern IntRep* bitop(const IntRep*, const IntRep*, IntRep*, char);
+extern IntRep* bitop(const IntRep*, long, IntRep*, char);
+extern IntRep* power(const IntRep*, long, IntRep*);
+extern IntRep* div(const IntRep*, const IntRep*, IntRep*);
+extern IntRep* mod(const IntRep*, const IntRep*, IntRep*);
+extern IntRep* div(const IntRep*, long, IntRep*);
+extern IntRep* mod(const IntRep*, long, IntRep*);
+extern IntRep* compl(const IntRep*, IntRep*);
+extern IntRep* abs(const IntRep*, IntRep*);
+extern IntRep* negate(const IntRep*, IntRep*);
+extern IntRep* pow(const IntRep*, long);
+extern IntRep* gcd(const IntRep*, const IntRep* y);
+extern int compare(const IntRep*, const IntRep*);
+extern int compare(const IntRep*, long);
+extern int ucompare(const IntRep*, const IntRep*);
+extern int ucompare(const IntRep*, long);
+extern char* Itoa(const IntRep* x, int base = 10, int width = 0);
+extern char* cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base,
+ int showbase, int width, int align_right,
+ char fillchar, char Xcase, int showpos);
+extern IntRep* atoIntRep(const char* s, int base = 10);
+extern long Itolong(const IntRep*);
+extern double Itodouble(const IntRep*);
+extern int Iislong(const IntRep*);
+extern int Iisdouble(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();
+
+ void operator = (const Integer&);
+ void operator = (long);
+
+// unary operations to self
+
+ void operator ++ ();
+ void operator -- ();
+ void negate(); // negate in-place
+ void abs(); // absolute-value in-place
+ void complement(); // bitwise complement in-place
+
+// assignment-based operations
+
+ void operator += (const Integer&);
+ void operator -= (const Integer&);
+ void operator *= (const Integer&);
+ void operator /= (const Integer&);
+ void operator %= (const Integer&);
+ void operator <<=(const Integer&);
+ void operator >>=(const Integer&);
+ void operator &= (const Integer&);
+ void operator |= (const Integer&);
+ void operator ^= (const Integer&);
+
+ void operator += (long);
+ void operator -= (long);
+ void operator *= (long);
+ void operator /= (long);
+ void operator %= (long);
+ void operator <<=(long);
+ void operator >>=(long);
+ void operator &= (long);
+ void operator |= (long);
+ void operator ^= (long);
+
+// (constructive binary operations are inlined below)
+
+#ifdef __GNUG__
+ 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 { return Iisdouble(rep); }
+
+#if 0
+ // There two operators cause a number of ambiguities.
+ operator long() const { return Itolong(rep); }
+ operator double() const { return Itodouble(rep); }
+#endif
+ long as_long() const { return Itolong(rep); }
+ double as_double() const { return Itodouble(rep); }
+
+ 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 void Integer::operator = (const Integer& y)
+{
+ rep = Icopy(rep, y.rep);
+}
+
+inline void Integer::operator = (long y)
+{
+ rep = Icopy_long(rep, y);
+}
+
+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 void Integer::operator += (const Integer& y)
+{
+ add(*this, y, *this);
+}
+
+inline void Integer::operator += (long y)
+{
+ add(*this, y, *this);
+}
+
+inline void Integer::operator ++ ()
+{
+ add(*this, 1, *this);
+}
+
+
+inline void Integer::operator -= (const Integer& y)
+{
+ sub(*this, y, *this);
+}
+
+inline void Integer::operator -= (long y)
+{
+ sub(*this, y, *this);
+}
+
+inline void Integer::operator -- ()
+{
+ add(*this, -1, *this);
+}
+
+
+
+inline void Integer::operator *= (const Integer& y)
+{
+ mul(*this, y, *this);
+}
+
+inline void Integer::operator *= (long y)
+{
+ mul(*this, y, *this);
+}
+
+
+inline void Integer::operator &= (const Integer& y)
+{
+ and(*this, y, *this);
+}
+
+inline void Integer::operator &= (long y)
+{
+ and(*this, y, *this);
+}
+
+inline void Integer::operator |= (const Integer& y)
+{
+ or(*this, y, *this);
+}
+
+inline void Integer::operator |= (long y)
+{
+ or(*this, y, *this);
+}
+
+
+inline void Integer::operator ^= (const Integer& y)
+{
+ xor(*this, y, *this);
+}
+
+inline void Integer::operator ^= (long y)
+{
+ xor(*this, y, *this);
+}
+
+
+
+inline void Integer::operator /= (const Integer& y)
+{
+ div(*this, y, *this);
+}
+
+inline void Integer::operator /= (long y)
+{
+ div(*this, y, *this);
+}
+
+
+inline void Integer::operator <<= (const Integer& y)
+{
+ lshift(*this, y, *this);
+}
+
+inline void Integer::operator <<= (long y)
+{
+ lshift(*this, y, *this);
+}
+
+
+inline void Integer::operator >>= (const Integer& y)
+{
+ rshift(*this, y, *this);
+}
+
+inline void Integer::operator >>= (long y)
+{
+ rshift(*this, y, *this);
+}
+
+#ifdef __GNUG__
+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(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 void Integer::operator %= (const Integer& y)
+{
+ *this = *this % y; // mod(*this, y, *this) doesn't work.
+}
+
+inline void Integer::operator %= (long y)
+{
+ *this = *this % y; // mod(*this, y, *this) doesn't work.
+}
+#endif /* !_Integer_h */
diff --git a/gnu/lib/libg++/g++-include/LogNorm.cc b/gnu/lib/libg++/g++-include/LogNorm.cc
new file mode 100644
index 00000000000..8adc86cbdbd
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/LogNorm.cc
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Normal.h>
+
+#include <LogNorm.h>
+
+//
+// See Simulation, Modelling & Analysis by Law & Kelton, pp260
+//
+//
+
+double LogNormal::operator()()
+{
+ return( pow(M_E, this->Normal::operator()() ) );
+}
+
+
diff --git a/gnu/lib/libg++/g++-include/LogNorm.h b/gnu/lib/libg++/g++-include/LogNorm.h
new file mode 100644
index 00000000000..2e9454cadc2
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/LogNorm.h
@@ -0,0 +1,81 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: LogNorm.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#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++/g++-include/MLCG.cc b/gnu/lib/libg++/g++-include/MLCG.cc
new file mode 100644
index 00000000000..74836c65afb
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/MLCG.cc
@@ -0,0 +1,103 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <MLCG.h>
+//
+// SEED_TABLE_SIZE must be a power of 2
+//
+
+
+#define SEED_TABLE_SIZE 32
+
+static long seedTable[SEED_TABLE_SIZE] = {
+0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
+0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
+0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
+0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
+0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
+0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
+0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
+0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf
+};
+
+MLCG::MLCG(long seed1, long seed2)
+{
+ initialSeedOne = seed1;
+ initialSeedTwo = seed2;
+ reset();
+}
+
+void
+MLCG::reset()
+{
+ long seed1 = initialSeedOne;
+ long seed2 = initialSeedTwo;
+
+ //
+ // Most people pick stupid seed numbers that do not have enough
+ // bits. In this case, if they pick a small seed number, we
+ // map that to a specific seed.
+ //
+ if (seed1 < 0) {
+ seed1 = (seed1 + 2147483561);
+ seed1 = (seed1 < 0) ? -seed1 : seed1;
+ }
+
+ if (seed2 < 0) {
+ seed2 = (seed2 + 2147483561);
+ seed2 = (seed2 < 0) ? -seed2 : seed2;
+ }
+
+ if (seed1 > -1 && seed1 < SEED_TABLE_SIZE) {
+ seedOne = seedTable[seed1];
+ } else {
+ seedOne = seed1 ^ seedTable[seed1 & (SEED_TABLE_SIZE-1)];
+ }
+
+ if (seed2 > -1 && seed2 < SEED_TABLE_SIZE) {
+ seedTwo = seedTable[seed2];
+ } else {
+ seedTwo = seed2 ^ seedTable[ seed2 & (SEED_TABLE_SIZE-1) ];
+ }
+ seedOne = (seedOne % 2147483561) + 1;
+ seedTwo = (seedTwo % 2147483397) + 1;
+}
+
+unsigned long MLCG::asLong()
+{
+ long 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;
+ }
+
+ long z = seedOne - seedTwo;
+ if (z < 1) {
+ z += 2147483562;
+ }
+ return( (unsigned long) z);
+}
+
diff --git a/gnu/lib/libg++/g++-include/MLCG.h b/gnu/lib/libg++/g++-include/MLCG.h
new file mode 100644
index 00000000000..b0a3f6fcb42
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/MLCG.h
@@ -0,0 +1,90 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: MLCG.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#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 {
+ long initialSeedOne;
+ long initialSeedTwo;
+ long seedOne;
+ long seedTwo;
+
+protected:
+
+public:
+ MLCG(long seed1 = 0, long seed2 = 1);
+ //
+ // Return a long-words word of random bits
+ //
+ virtual unsigned long asLong();
+ virtual void reset();
+ long seed1();
+ void seed1(long);
+ long seed2();
+ void seed2(long);
+ void reseed(long, long);
+};
+
+inline long
+MLCG::seed1()
+{
+ return(seedOne);
+}
+
+inline void
+MLCG::seed1(long s)
+{
+ initialSeedOne = s;
+ reset();
+}
+
+inline long
+MLCG::seed2()
+{
+ return(seedTwo);
+}
+
+inline void
+MLCG::seed2(long s)
+{
+ initialSeedTwo = s;
+ reset();
+}
+
+inline void
+MLCG::reseed(long s1, long s2)
+{
+ initialSeedOne = s1;
+ initialSeedTwo = s2;
+ reset();
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Makefile b/gnu/lib/libg++/g++-include/Makefile
new file mode 100644
index 00000000000..f9b55ce74b5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Makefile
@@ -0,0 +1,31 @@
+# $Id: Makefile,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+
+LIB= g++
+
+SRCS= AllocRing.cc Obstack.cc builtin.cc \
+ regex.cc Regex.cc String.cc Integer.cc Rational.cc Complex.cc Random.cc \
+ BitSet.cc BitString.cc LogNorm.cc SmplHist.cc SmplStat.cc \
+ Normal.cc NegExp.cc Weibull.cc Erlang.cc DiscUnif.cc \
+ Uniform.cc Poisson.cc HypGeom.cc Geom.cc Binomial.cc \
+ RNG.cc ACG.cc MLCG.cc RndInt.cc \
+ Fix.cc Fix16.cc Fix24.cc CursesW.cc GetOpt.cc $(EH_FILES) \
+ new.cc chr.cc dtoa.cc error.cc gcd.cc hash.cc \
+ lg.cc fmtq.cc ioob.cc pow.cc sqrt.cc str.cc timer.cc \
+ math.cc compare.cc SLList.cc DLList.cc \
+ streambuf.C stdstrbufs.C iostream.C stdstreams.C \
+ strstream.C indstream.C PlotFile.C SFile.C fstream.C \
+ parsestream.C stream.C makebuf.C editbuf.C filebuf.C \
+ sgetline.C igetline.C igetsb.C procbuf.C sbufvform.C \
+ sbufvscan.C stdiostream.C floatconv.C outfloat.C iomanip.C
+
+CXXFLAGS+= -nostdinc++ -I$(.CURDIR)/../g++-include \
+ -I$(.CURDIR)/../iostream
+CFLAGS+= -I$(.CURDIR)
+LDADD= ${DESTDIR}/usr/lib/c++rt0.o -lcurses
+DPADD= ${DESTDIR}/usr/lib/c++rt0.o ${LIBCURSES}
+NOMAN= noman
+.PATH: $(.CURDIR)/../iostream
+LIBCURSES!= printf "xxx:\n\techo \$${LIBCURSES}\n.include <bsd.prog.mk>" |\
+ $(MAKE) -r -s -f - xxx
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libg++/g++-include/NegExp.cc b/gnu/lib/libg++/g++-include/NegExp.cc
new file mode 100644
index 00000000000..8bd6d0514d7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/NegExp.cc
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <NegExp.h>
+
+double NegativeExpntl::operator()()
+{
+ return(-pMean * log(pGenerator -> asDouble()));
+}
+
diff --git a/gnu/lib/libg++/g++-include/NegExp.h b/gnu/lib/libg++/g++-include/NegExp.h
new file mode 100644
index 00000000000..f5574a17aee
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/NegExp.h
@@ -0,0 +1,58 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: NegExp.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#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++/g++-include/Normal.cc b/gnu/lib/libg++/g++-include/Normal.cc
new file mode 100644
index 00000000000..bae43e10553
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Normal.cc
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Normal.h>
+//
+// See Simulation, Modelling & Analysis by Law & Kelton, pp259
+//
+// This is the ``polar'' method.
+//
+
+double Normal::operator()()
+{
+
+ if (haveCachedNormal == 1) {
+ haveCachedNormal = 0;
+ return(cachedNormal * pStdDev + pMean );
+ } else {
+
+ for(;;) {
+ double u1 = pGenerator -> asDouble();
+ double u2 = pGenerator -> asDouble();
+ double v1 = 2 * u1 - 1;
+ double v2 = 2 * u2 - 1;
+ double w = (v1 * v1) + (v2 * v2);
+
+//
+// We actually generate two IID normal distribution variables.
+// We cache the one & return the other.
+//
+ if (w <= 1) {
+ double y = sqrt( (-2 * log(w)) / w);
+ double x1 = v1 * y;
+ double x2 = v2 * y;
+
+ haveCachedNormal = 1;
+ cachedNormal = x2;
+ return(x1 * pStdDev + pMean);
+ }
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/g++-include/Normal.h b/gnu/lib/libg++/g++-include/Normal.h
new file mode 100644
index 00000000000..499ecc38cdb
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Normal.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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Normal.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#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++/g++-include/Obstack.cc b/gnu/lib/libg++/g++-include/Obstack.cc
new file mode 100644
index 00000000000..f748eb4df83
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Obstack.cc
@@ -0,0 +1,112 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <values.h>
+#include <builtin.h>
+#include <Obstack.h>
+
+Obstack::Obstack(int size, int alignment)
+{
+ alignmentmask = alignment - 1;
+ chunksize = size;
+ chunk = 0;
+ nextfree = objectbase = 0;
+ chunklimit = 0;
+}
+
+void Obstack::_free(void* obj)
+{
+ _obstack_chunk* lp;
+ _obstack_chunk* plp;
+
+ lp = chunk;
+ while (lp != 0 && ((void*)lp > obj || (void*)(lp)->limit < obj))
+ {
+ plp = lp -> prev;
+ delete [] (char*)lp;
+ lp = plp;
+ }
+ if (lp)
+ {
+ objectbase = nextfree = (char *)(obj);
+ chunklimit = lp->limit;
+ chunk = lp;
+ }
+ else if (obj != 0)
+ (*lib_error_handler)("Obstack", "deletion of nonexistent obj");
+}
+
+void Obstack::newchunk(int size)
+{
+ _obstack_chunk* old_chunk = chunk;
+ _obstack_chunk* new_chunk;
+ long new_size;
+ int obj_size = nextfree - objectbase;
+
+ new_size = (obj_size + size) << 1;
+ if (new_size < chunksize)
+ new_size = chunksize;
+
+ new_chunk = chunk = (_obstack_chunk*)(new char[new_size]);
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = chunklimit = (char *) new_chunk + new_size;
+
+ memcpy((void*)new_chunk->contents, (void*)objectbase, obj_size);
+ objectbase = new_chunk->contents;
+ nextfree = objectbase + obj_size;
+}
+
+void* Obstack::finish()
+{
+ void* value = (void*) objectbase;
+ nextfree = (char*)((int)(nextfree + alignmentmask) & ~(alignmentmask));
+ if (nextfree - (char*)chunk > chunklimit - (char*)chunk)
+ nextfree = chunklimit;
+ objectbase = nextfree;
+ return value;
+}
+
+int Obstack::contains(void* obj) // true if obj somewhere in Obstack
+{
+ for (_obstack_chunk* ch = chunk;
+ ch != 0 && (obj < (void*)ch || obj >= (void*)(ch->limit));
+ ch = ch->prev);
+
+ return ch != 0;
+}
+
+int Obstack::OK()
+{
+ int v = chunksize > 0; // valid size
+ v &= alignmentmask != 0; // and alignment
+ v &= chunk != 0;
+ v &= objectbase >= chunk->contents;
+ v &= nextfree >= objectbase;
+ v &= nextfree <= chunklimit;
+ v &= chunklimit == chunk->limit;
+ _obstack_chunk* p = chunk;
+ // allow lots of chances to find bottom!
+ long x = MAXLONG;
+ 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++/g++-include/Obstack.h b/gnu/lib/libg++/g++-include/Obstack.h
new file mode 100644
index 00000000000..2467a8ad862
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Obstack.h
@@ -0,0 +1,217 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Obstack.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#ifndef _Obstack_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Obstack_h 1
+
+#include <std.h>
+
+class Obstack
+{
+ struct _obstack_chunk
+ {
+ char* limit;
+ _obstack_chunk* prev;
+ char contents[4];
+ };
+
+protected:
+ long chunksize;
+ _obstack_chunk* chunk;
+ char* objectbase;
+ char* nextfree;
+ char* chunklimit;
+ int alignmentmask;
+
+ void _free(void* obj);
+ void newchunk(int size);
+
+public:
+ Obstack(int size = 4080, int alignment = 4); // 4080=4096-mallocslop
+
+ ~Obstack();
+
+ void* base();
+ void* next_free();
+ int alignment_mask();
+ int chunk_size();
+ int size();
+ int room();
+ int contains(void* p); // does Obstack hold pointer p?
+
+ void grow(const void* data, int size);
+ void grow(const void* data, int size, char terminator);
+ void grow(const char* s);
+ void grow(char c);
+ void grow_fast(char c);
+ void blank(int size);
+ void blank_fast(int size);
+
+ void* finish();
+ void* finish(char terminator);
+
+ void* copy(const void* data, int size);
+ void* copy(const void* data, int size, char terminator);
+ void* copy(const char* s);
+ void* copy(char c);
+ void* alloc(int size);
+
+ void free(void* obj);
+ void shrink(int size = 1); // suggested by ken@cs.rochester.edu
+
+ int OK(); // rep invariant
+};
+
+
+inline Obstack::~Obstack()
+{
+ _free(0);
+}
+
+inline void* Obstack::base()
+{
+ return objectbase;
+}
+
+inline void* Obstack::next_free()
+{
+ return nextfree;
+}
+
+inline int Obstack::alignment_mask()
+{
+ return alignmentmask;
+}
+
+inline int Obstack::chunk_size()
+{
+ return chunksize;
+}
+
+inline int Obstack::size()
+{
+ return nextfree - objectbase;
+}
+
+inline int Obstack::room()
+{
+ return chunklimit - nextfree;
+}
+
+inline void Obstack:: grow(const void* data, int size)
+{
+ if (nextfree+size > chunklimit)
+ newchunk(size);
+ memcpy(nextfree, data, size);
+ nextfree += size;
+}
+
+inline void Obstack:: grow(const void* data, int size, char terminator)
+{
+ if (nextfree+size+1 > chunklimit)
+ newchunk(size+1);
+ memcpy(nextfree, data, size);
+ nextfree += size;
+ *(nextfree)++ = terminator;
+}
+
+inline void Obstack:: grow(const char* s)
+{
+ grow((const void*)s, strlen(s), 0);
+}
+
+inline void Obstack:: grow(char c)
+{
+ if (nextfree+1 > chunklimit)
+ newchunk(1);
+ *(nextfree)++ = c;
+}
+
+inline void Obstack:: blank(int size)
+{
+ if (nextfree+size > chunklimit)
+ newchunk(size);
+ nextfree += size;
+}
+
+inline void* Obstack::finish(char terminator)
+{
+ grow(terminator);
+ return finish();
+}
+
+inline void* Obstack::copy(const void* data, int size)
+{
+ grow (data, size);
+ return finish();
+}
+
+inline void* Obstack::copy(const void* data, int size, char terminator)
+{
+ grow(data, size, terminator);
+ return finish();
+}
+
+inline void* Obstack::copy(const char* s)
+{
+ grow((const void*)s, strlen(s), 0);
+ return finish();
+}
+
+inline void* Obstack::copy(char c)
+{
+ grow(c);
+ return finish();
+}
+
+inline void* Obstack::alloc(int size)
+{
+ blank(size);
+ return finish();
+}
+
+inline void Obstack:: free(void* obj)
+{
+ if (obj >= (void*)chunk && obj<(void*)chunklimit)
+ nextfree = objectbase = (char *) obj;
+ else
+ _free(obj);
+}
+
+inline void Obstack:: grow_fast(char c)
+{
+ *(nextfree)++ = c;
+}
+
+inline void Obstack:: blank_fast(int size)
+{
+ nextfree += size;
+}
+
+inline void Obstack:: shrink(int size) // from ken@cs.rochester.edu
+{
+ if (nextfree >= objectbase + size)
+ nextfree -= size;
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Pix.h b/gnu/lib/libg++/g++-include/Pix.h
new file mode 100644
index 00000000000..c4a5289ddd5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Pix.h
@@ -0,0 +1,6 @@
+/* $Id: Pix.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $ */
+
+#ifndef _Pix_h
+#define _Pix_h 1
+typedef void* Pix;
+#endif
diff --git a/gnu/lib/libg++/g++-include/Poisson.cc b/gnu/lib/libg++/g++-include/Poisson.cc
new file mode 100644
index 00000000000..8d70f1751b9
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Poisson.cc
@@ -0,0 +1,36 @@
+
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Poisson.h>
+
+double Poisson::operator()()
+{
+ double bound = exp(-1.0 * pMean);
+ int count = 0;
+
+ for (double product = 1.0;
+ product >= bound;
+ product *= pGenerator -> asDouble()) {
+ count++;
+ }
+ return(count - 1);
+}
diff --git a/gnu/lib/libg++/g++-include/Poisson.h b/gnu/lib/libg++/g++-include/Poisson.h
new file mode 100644
index 00000000000..190518faa48
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Poisson.h
@@ -0,0 +1,54 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Poisson.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#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++/g++-include/RNG.cc b/gnu/lib/libg++/g++-include/RNG.cc
new file mode 100644
index 00000000000..568b721898a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/RNG.cc
@@ -0,0 +1,132 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1989 Free Software Foundation
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <values.h>
+#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(unsigned long));
+
+ //
+ // 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++/g++-include/RNG.h b/gnu/lib/libg++/g++-include/RNG.h
new file mode 100644
index 00000000000..3105b3eb5c0
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/RNG.h
@@ -0,0 +1,60 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: RNG.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#ifndef _RNG_h
+#define _RNG_h 1
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <assert.h>
+#include <math.h>
+
+union PrivateRNGSingleType { // used to access floats as unsigneds
+ float s;
+ unsigned long u;
+};
+
+union PrivateRNGDoubleType { // used to access doubles as unsigneds
+ double d;
+ unsigned long u[2];
+};
+
+//
+// Base class for Random Number Generators. See ACG and MLCG for instances.
+//
+class RNG {
+ static PrivateRNGSingleType singleMantissa; // mantissa bit vector
+ static PrivateRNGDoubleType doubleMantissa; // mantissa bit vector
+public:
+ RNG();
+ //
+ // Return a long-words word of random bits
+ //
+ virtual unsigned long asLong() = 0;
+ virtual void reset() = 0;
+ //
+ // Return random bits converted to either a float or a double
+ //
+ float asFloat();
+ double asDouble();
+};
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Random.cc b/gnu/lib/libg++/g++-include/Random.cc
new file mode 100644
index 00000000000..572a602cf7a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Random.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <Random.h>
diff --git a/gnu/lib/libg++/g++-include/Random.h b/gnu/lib/libg++/g++-include/Random.h
new file mode 100644
index 00000000000..a92bef88fc0
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Random.h
@@ -0,0 +1,57 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Random.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#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++/g++-include/Rational.cc b/gnu/lib/libg++/g++-include/Rational.cc
new file mode 100644
index 00000000000..cef31be4b08
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Rational.cc
@@ -0,0 +1,415 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <math.h>
+#include <values.h>
+#include <builtin.h>
+#include <float.h>
+#include <Rational.h>
+
+void Rational::error(const char* msg) const
+{
+ (*lib_error_handler)("Rational", msg);
+}
+
+static const Integer _Int_One(1);
+
+void Rational::normalize()
+{
+ int s = sign(den);
+ if (s == 0)
+ error("Zero denominator.");
+ else if (s < 0)
+ {
+ den.negate();
+ num.negate();
+ }
+
+ Integer g = gcd(num, den);
+ if (ucompare(g, _Int_One) != 0)
+ {
+ num /= g;
+ den /= g;
+ }
+}
+
+void add(const Rational& x, const Rational& y, Rational& r)
+{
+ if (&r != &x && &r != &y)
+ {
+ mul(x.num, y.den, r.num);
+ mul(x.den, y.num, r.den);
+ add(r.num, r.den, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ else
+ {
+ Integer tmp;
+ mul(x.den, y.num, tmp);
+ mul(x.num, y.den, r.num);
+ add(r.num, tmp, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ r.normalize();
+}
+
+void sub(const Rational& x, const Rational& y, Rational& r)
+{
+ if (&r != &x && &r != &y)
+ {
+ mul(x.num, y.den, r.num);
+ mul(x.den, y.num, r.den);
+ sub(r.num, r.den, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ else
+ {
+ Integer tmp;
+ mul(x.den, y.num, tmp);
+ mul(x.num, y.den, r.num);
+ sub(r.num, tmp, r.num);
+ mul(x.den, y.den, r.den);
+ }
+ r.normalize();
+}
+
+void mul(const Rational& x, const Rational& y, Rational& r)
+{
+ mul(x.num, y.num, r.num);
+ mul(x.den, y.den, r.den);
+ r.normalize();
+}
+
+void div(const Rational& x, const Rational& y, Rational& r)
+{
+ if (&r != &x && &r != &y)
+ {
+ mul(x.num, y.den, r.num);
+ mul(x.den, y.num, r.den);
+ }
+ else
+ {
+ Integer tmp;
+ mul(x.num, y.den, tmp);
+ mul(y.num, x.den, r.den);
+ r.num = tmp;
+ }
+ r.normalize();
+}
+
+
+
+
+void Rational::invert()
+{
+ Integer tmp = num;
+ num = den;
+ den = tmp;
+ int s = sign(den);
+ if (s == 0)
+ error("Zero denominator.");
+ else if (s < 0)
+ {
+ den.negate();
+ num.negate();
+ }
+}
+
+int compare(const Rational& x, const Rational& y)
+{
+ int xsgn = sign(x.num);
+ int ysgn = sign(y.num);
+ int d = xsgn - ysgn;
+ if (d == 0 && xsgn != 0) d = compare(x.num * y.den, x.den * y.num);
+ return d;
+}
+
+Rational::Rational(double x)
+{
+ num = 0;
+ den = 1;
+ if (x != 0.0)
+ {
+ int neg = x < 0;
+ if (neg)
+ x = -x;
+
+ const long shift = 15; // a safe shift per step
+ const double width = 32768.0; // = 2^shift
+ const int maxiter = 20; // ought not be necessary, but just in case,
+ // max 300 bits of precision
+ int expt;
+ double mantissa = frexp(x, &expt);
+ long exponent = expt;
+ double intpart;
+ int k = 0;
+ while (mantissa != 0.0 && k++ < maxiter)
+ {
+ mantissa *= width;
+ mantissa = modf(mantissa, &intpart);
+ num <<= shift;
+ num += (long)intpart;
+ exponent -= shift;
+ }
+ if (exponent > 0)
+ num <<= exponent;
+ else if (exponent < 0)
+ den <<= -exponent;
+ if (neg)
+ num.negate();
+ }
+ normalize();
+}
+
+
+Integer trunc(const Rational& x)
+{
+ return x.num / x.den ;
+}
+
+
+Rational pow(const Rational& x, const Integer& y)
+{
+ long yy = y.as_long();
+ return pow(x, yy);
+}
+
+#if defined(__GNUG__) && !defined(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++/g++-include/Rational.h b/gnu/lib/libg++/g++-include/Rational.h
new file mode 100644
index 00000000000..45abc7f61ff
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Rational.h
@@ -0,0 +1,284 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Rational.h,v 1.1 1995/10/18 08:38:17 deraadt Exp $
+*/
+
+#ifndef _Rational_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Rational_h 1
+
+#include <Integer.h>
+#include <math.h>
+
+class Rational
+{
+protected:
+ Integer num;
+ Integer den;
+
+ void normalize();
+
+public:
+ Rational();
+ Rational(double);
+ Rational(int n);
+ Rational(long n);
+ Rational(int n, int d);
+ Rational(long n, long d);
+ Rational(long n, unsigned long d);
+ Rational(unsigned long n, long d);
+ Rational(unsigned long n, unsigned long d);
+ Rational(const Integer& n);
+ Rational(const Integer& n, const Integer& d);
+ Rational(const Rational&);
+
+ ~Rational();
+
+ void 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);
+
+ void operator += (const Rational& y);
+ void operator -= (const Rational& y);
+ void operator *= (const Rational& y);
+ void operator /= (const Rational& y);
+
+#ifdef __GNUG__
+ 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 void Rational::operator = (const Rational& y)
+{
+ num = y.num; den = y.den;
+}
+
+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 void Rational::operator += (const Rational& y)
+{
+ add(*this, y, *this);
+}
+
+inline void Rational::operator -= (const Rational& y)
+{
+ sub(*this, y, *this);
+}
+
+inline void Rational::operator *= (const Rational& y)
+{
+ mul(*this, y, *this);
+}
+
+inline void Rational::operator /= (const Rational& y)
+{
+ div(*this, y, *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); }
+
+#ifdef __GNUG__
+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(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++/g++-include/Regex.cc b/gnu/lib/libg++/g++-include/Regex.cc
new file mode 100644
index 00000000000..d10eaec940a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Regex.cc
@@ -0,0 +1,136 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ Regex class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <std.h>
+#include <ctype.h>
+#include <values.h>
+#include <new.h>
+#include <builtin.h>
+
+extern "C" {
+#include <regex.h>
+}
+
+#include <Regex.h>
+
+Regex::~Regex()
+{
+ if (buf->buffer) free(buf->buffer);
+ if (buf->fastmap) free(buf->fastmap);
+ delete(buf);
+ delete(reg);
+}
+
+Regex::Regex(const char* t, int fast, int bufsize,
+ const char* transtable)
+{
+ int tlen = (t == 0)? 0 : strlen(t);
+ buf = new re_pattern_buffer;
+ reg = new re_registers;
+ if (fast)
+ buf->fastmap = (char*)malloc(256);
+ else
+ buf->fastmap = 0;
+ buf->translate = (char*)transtable;
+ if (tlen > bufsize)
+ bufsize = tlen;
+ buf->allocated = bufsize;
+ buf->buffer = (char *)malloc(buf->allocated);
+ char* msg = re_compile_pattern((const char*)t, tlen, buf);
+ if (msg != 0)
+ (*lib_error_handler)("Regex", msg);
+ else if (fast)
+ re_compile_fastmap(buf);
+}
+
+int Regex::match_info(int& start, int& length, int nth) const
+{
+ if ((unsigned)(nth) >= RE_NREGS)
+ return 0;
+ else
+ {
+ start = reg->start[nth];
+ length = reg->end[nth] - start;
+ return start >= 0 && length >= 0;
+ }
+}
+
+int Regex::search(const char* s, int len, int& matchlen, int startpos) const
+{
+ int matchpos, pos, range;
+ if (startpos >= 0)
+ {
+ pos = startpos;
+ range = len - startpos;
+ }
+ else
+ {
+ pos = len + startpos;
+ range = -pos;
+ }
+ matchpos = re_search_2(buf, 0, 0, (char*)s, len, pos, range, reg, len);
+ if (matchpos >= 0)
+ matchlen = reg->end[0] - reg->start[0];
+ else
+ matchlen = 0;
+ return matchpos;
+}
+
+int Regex::match(const char*s, int len, int p) const
+{
+ if (p < 0)
+ {
+ p += len;
+ if (p > len)
+ return -1;
+ return re_match_2(buf, 0, 0, (char*)s, p, 0, reg, p);
+ }
+ else if (p > len)
+ return -1;
+ else
+ return re_match_2(buf, 0, 0, (char*)s, len, p, reg, len);
+}
+
+int Regex::OK() const
+{
+// can't verify much, since we've lost the original string
+ int v = buf != 0; // have a regex buf
+ v &= buf->buffer != 0; // with a pat
+ if (!v) (*lib_error_handler)("Regex", "invariant failure");
+ return v;
+}
+
+/*
+ some built-in Regular expressions
+*/
+
+const Regex RXwhite("[ \n\t\r\v\f]+", 1);
+const Regex RXint("-?[0-9]+", 1);
+const Regex RXdouble("-?\\(\\([0-9]+\\.[0-9]*\\)\\|\\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)\\([eE][---+]?[0-9]+\\)?", 1, 200);
+const Regex RXalpha("[A-Za-z]+", 1);
+const Regex RXlowercase("[a-z]+", 1);
+const Regex RXuppercase("[A-Z]+", 1);
+const Regex RXalphanum("[0-9A-Za-z]+", 1);
+const Regex RXidentifier("[A-Za-z_][A-Za-z0-9_]*", 1);
+
diff --git a/gnu/lib/libg++/g++-include/Regex.h b/gnu/lib/libg++/g++-include/Regex.h
new file mode 100644
index 00000000000..e7ca449345e
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Regex.h
@@ -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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Regex.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+#ifndef _Regex_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _Regex_h 1
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define re_compile_pattern recmppat
+#define re_pattern_buffer repatbuf
+#define re_registers reregs
+#endif
+
+struct re_pattern_buffer; // defined elsewhere
+struct re_registers;
+
+class Regex
+{
+private:
+
+ Regex(const Regex&) {} // no X(X&)
+ void operator = (const Regex&) {} // no assignment
+
+protected:
+ re_pattern_buffer* buf;
+ re_registers* reg;
+
+public:
+ Regex(const char* t,
+ int fast = 0,
+ int bufsize = 40,
+ const char* transtable = 0);
+
+ ~Regex();
+
+ int match(const char* s, int len, int pos = 0) const;
+ int search(const char* s, int len,
+ int& matchlen, int startpos = 0) const;
+ int match_info(int& start, int& length, int nth = 0) const;
+
+ int OK() const; // representation invariant
+};
+
+// some built in regular expressions
+
+extern const Regex RXwhite; // = "[ \n\t\r\v\f]+"
+extern const Regex RXint; // = "-?[0-9]+"
+extern const Regex RXdouble; // = "-?\\(\\([0-9]+\\.[0-9]*\\)\\|
+ // \\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)
+ // \\([eE][---+]?[0-9]+\\)?"
+extern const Regex RXalpha; // = "[A-Za-z]+"
+extern const Regex RXlowercase; // = "[a-z]+"
+extern const Regex RXuppercase; // = "[A-Z]+"
+extern const Regex RXalphanum; // = "[0-9A-Za-z]+"
+extern const Regex RXidentifier; // = "[A-Za-z_][A-Za-z0-9_]*"
+
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/RndInt.cc b/gnu/lib/libg++/g++-include/RndInt.cc
new file mode 100644
index 00000000000..c09f1e504d3
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/RndInt.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <RndInt.h>
diff --git a/gnu/lib/libg++/g++-include/RndInt.h b/gnu/lib/libg++/g++-include/RndInt.h
new file mode 100644
index 00000000000..40165a5b8e4
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/RndInt.h
@@ -0,0 +1,177 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1990 Free Software Foundation
+ adapted from a submission from John Reidl <riedl@cs.purdue.edu>
+
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU CC General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU CC, but only under the conditions described in the
+GNU CC General Public License. A copy of this license is
+supposed to have been given to you along with GNU CC so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: RndInt.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+#ifndef _RandomInteger_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _RandomInteger_h 1
+
+// RandomInteger uses a random number generator to generate an integer
+// in a specified range. By default the range is 0..1. Since in my
+// experience random numbers are often needed for a wide variety of
+// ranges in the same program, this generator accepts a new low or high value
+// as an argument to the asLong and operator() methods to temporarily
+// override stored values
+
+#include <math.h>
+#include <RNG.h>
+
+class RandomInteger
+{
+ protected:
+ RNG *pGenerator;
+ long pLow;
+ long pHigh;
+
+ long _asLong(long, long);
+
+ public:
+
+ RandomInteger(long low, long high, RNG *gen);
+ RandomInteger(long high, RNG *gen);
+ RandomInteger(RNG *gen);
+
+// read params
+
+ long low() const;
+ long high() const;
+ RNG* generator() const;
+
+// change params
+
+ long low(long x);
+ long high(long x);
+ RNG* generator(RNG *gen);
+
+// get a random number
+
+ long asLong();
+ long operator()(); // synonym for asLong
+ int asInt(); // (possibly) truncate as int
+
+// override params for one shot
+
+ long asLong(long high);
+ long asLong(long low, long high);
+
+ long operator () (long high); // synonyms
+ long operator () (long low, long high);
+
+};
+
+
+inline RandomInteger::RandomInteger(long low, long high, RNG *gen)
+ : pLow((low < high) ? low : high),
+ pHigh((low < high) ? high : low),
+ pGenerator(gen)
+{}
+
+inline RandomInteger::RandomInteger(long high, RNG *gen)
+ : pLow((0 < high) ? 0 : high),
+ pHigh((0 < high) ? high : 0),
+ pGenerator(gen)
+{}
+
+
+inline RandomInteger::RandomInteger(RNG *gen)
+ : pLow(0),
+ pHigh(1),
+ pGenerator(gen)
+{}
+
+inline RNG* RandomInteger::generator() const { return pGenerator;}
+inline long RandomInteger::low() const { return pLow; }
+inline long RandomInteger::high() const { return pHigh; }
+
+inline RNG* RandomInteger::generator(RNG *gen)
+{
+ RNG *tmp = pGenerator; pGenerator = gen; return tmp;
+}
+
+inline long RandomInteger::low(long x)
+{
+ long tmp = pLow; pLow = x; return tmp;
+}
+
+inline long RandomInteger:: high(long x)
+{
+ long tmp = pHigh; pHigh = x; return tmp;
+}
+
+inline long RandomInteger:: _asLong(long low, long high)
+{
+ return (pGenerator->asLong() % (high-low+1)) + low;
+}
+
+
+inline long RandomInteger:: asLong()
+{
+ return _asLong(pLow, pHigh);
+}
+
+inline long RandomInteger:: asLong(long high)
+{
+ return _asLong(pLow, high);
+}
+
+inline long RandomInteger:: asLong(long low, long high)
+{
+ return _asLong(low, high);
+}
+
+inline long RandomInteger:: operator () ()
+{
+ return _asLong(pLow, pHigh);
+}
+
+inline long RandomInteger:: operator () (long high)
+{
+ return _asLong(pLow, high);
+}
+
+inline long RandomInteger:: operator () (long low, long high)
+{
+ return _asLong(low, high);
+}
+
+
+
+
+inline int RandomInteger:: asInt()
+{
+ return int(asLong());
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/SLList.cc b/gnu/lib/libg++/g++-include/SLList.cc
new file mode 100644
index 00000000000..725488cab4f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/SLList.cc
@@ -0,0 +1,247 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _G_NO_TEMPLATES
+#ifdef __GNUG__
+//#pragma implementation
+#endif
+#include <values.h>
+#include <stream.h>
+#include <builtin.h>
+#include "SLList.h"
+
+void BaseSLList::error(const char* msg)
+{
+ (*lib_error_handler)("SLList", msg);
+}
+
+int BaseSLList::length()
+{
+ 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(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(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, void *datum)
+{
+ BaseSLNode* u = (BaseSLNode*)p;
+ BaseSLNode* t = copy_node(datum);
+ if (last == 0)
+ t->tl = last = t;
+ else if (u == 0) // ins_after 0 means prepend
+ {
+ t->tl = last->tl;
+ last->tl = t;
+ }
+ else
+ {
+ t->tl = u->tl;
+ u->tl = t;
+ if (u == last)
+ last = t;
+ }
+ return Pix(t);
+}
+
+void BaseSLList::del_after(Pix p)
+{
+ BaseSLNode* u = (BaseSLNode*)p;
+ if (last == 0 || u == last) error("cannot del_after last");
+ if (u == 0) u = last; // del_after 0 means delete first
+ BaseSLNode* t = u->tl;
+ if (u == t)
+ last = 0;
+ else
+ {
+ u->tl = t->tl;
+ if (last == t)
+ last = u;
+ }
+ delete_node(t);
+}
+
+int BaseSLList::owns(Pix p)
+{
+ BaseSLNode* t = last;
+ if (t != 0 && p != 0)
+ {
+ do
+ {
+ if (Pix(t) == p) return 1;
+ t = t->tl;
+ } while (t != last);
+ }
+ return 0;
+}
+
+int BaseSLList::remove_front(void *dst, int signal_error)
+{
+ if (last)
+ {
+ BaseSLNode* t = last->tl;
+ copy_item(dst, t->item());
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete_node(t);
+ return 1;
+ }
+ if (signal_error)
+ error("remove_front of empty list");
+ return 0;
+}
+
+void BaseSLList::del_front()
+{
+ if (last == 0) error("del_front of empty list");
+ BaseSLNode* t = last->tl;
+ if (t == last)
+ last = 0;
+ else
+ last->tl = t->tl;
+ delete_node(t);
+}
+
+int BaseSLList::OK()
+{
+ int v = 1;
+ if (last != 0)
+ {
+ BaseSLNode* t = last;
+ long count = MAXLONG; // 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++/g++-include/SLList.h b/gnu/lib/libg++/g++-include/SLList.h
new file mode 100644
index 00000000000..499968caf5d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/SLList.h
@@ -0,0 +1,117 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: SLList.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+#ifndef _SLList_h
+#ifdef __GNUG__
+//#pragma interface
+#endif
+#define _SLList_h 1
+
+#include <Pix.h>
+
+struct BaseSLNode
+{
+ BaseSLNode *tl;
+ void *item() {return (void*)(this+1);} // Return ((SLNode<T>*)this)->hd
+};
+
+template<class T>
+class SLNode : public BaseSLNode
+{
+ public:
+ T hd; // Data part of node
+ SLNode() { }
+ SLNode(const T& h, SLNode* t = 0)
+ : hd(h) { tl = t; }
+ ~SLNode() { }
+};
+
+extern int __SLListLength(BaseSLNode *ptr);
+
+class BaseSLList {
+ protected:
+ BaseSLNode *last;
+ virtual void delete_node(BaseSLNode*node) = 0;
+ virtual BaseSLNode* copy_node(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, void *datum);
+ Pix prepend(void *datum);
+ Pix append(void *datum);
+ int remove_front(void *dst, int signal_error = 0);
+ void join(BaseSLList&);
+ public:
+ int length();
+ void clear();
+ Pix prepend(BaseSLNode*);
+ Pix append(BaseSLNode*);
+ int OK();
+ void error(const char* msg);
+ void del_after(Pix p);
+ int owns(Pix p);
+ void del_front();
+};
+
+template <class T>
+class SLList : public BaseSLList
+{
+ private:
+ virtual void delete_node(BaseSLNode *node) { delete (SLNode<T>*)node; }
+ virtual BaseSLNode* copy_node(void *datum)
+ { return new SLNode<T>(*(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(); }
+
+ int empty() { return last == 0; }
+
+ Pix prepend(T& item) {return BaseSLList::prepend(&item);}
+ Pix append(T& item) {return BaseSLList::append(&item);}
+ Pix prepend(SLNode<T>* node) {return BaseSLList::prepend(node);}
+ Pix append(SLNode<T>* node) {return BaseSLList::append(node);}
+
+ T& operator () (Pix p) {
+ if (p == 0) error("null Pix");
+ return ((SLNode<T>*)(p))->hd; }
+ inline Pix first() { return (last == 0)? 0 : Pix(last->tl); }
+ void next(Pix& p)
+ { p = (p == 0 || p == last)? 0 : Pix(((SLNode<T>*)(p))->tl); }
+ Pix ins_after(Pix p, T& item) { return BaseSLList::ins_after(p, &item); }
+ void join(SLList<T>& a) { BaseSLList::join(a); }
+
+ T& front() {
+ if (last == 0) error("front: empty list");
+ return ((SLNode<T>*)last->tl)->hd; }
+ T& rear() {
+ if (last == 0) error("rear: empty list");
+ return ((SLNode<T>*)last)->hd; }
+ int remove_front(T& x) { return BaseSLList::remove_front(&x); }
+ T remove_front() { T dst; BaseSLList::remove_front(&dst, 1); return dst; }
+};
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/SmplHist.cc b/gnu/lib/libg++/g++-include/SmplHist.cc
new file mode 100644
index 00000000000..a1fcd155a87
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/SmplHist.cc
@@ -0,0 +1,112 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <SmplHist.h>
+#include <math.h>
+
+#ifndef HUGE_VAL
+#ifdef HUGE
+#define HUGE_VAL HUGE
+#else
+#include <float.h>
+#define HUGE_VAL DBL_MAX
+#endif
+#endif
+
+const int SampleHistogramMinimum = -2;
+const int SampleHistogramMaximum = -1;
+
+SampleHistogram::SampleHistogram(double low, double high, double width)
+{
+ if (high < low) {
+ double t = high;
+ high = low;
+ low = t;
+ }
+
+ if (width == -1) {
+ width = (high - low) / 10;
+ }
+
+ howManyBuckets = int((high - low) / width) + 2;
+ bucketCount = new int[howManyBuckets];
+ bucketLimit = new double[howManyBuckets];
+ double lim = low;
+ for (int i = 0; i < howManyBuckets; i++) {
+ bucketCount[i] = 0;
+ bucketLimit[i] = lim;
+ lim += width;
+ }
+ bucketLimit[howManyBuckets-1] = HUGE_VAL; /* from math.h */
+}
+
+SampleHistogram::~SampleHistogram()
+{
+ if (howManyBuckets > 0) {
+ delete bucketCount;
+ delete bucketLimit;
+ }
+}
+
+void
+SampleHistogram::operator+=(double value)
+{
+ int i;
+ for (i = 0; i < howManyBuckets; i++) {
+ if (value < bucketLimit[i]) break;
+ }
+ bucketCount[i]++;
+ this->SampleStatistic::operator+=(value);
+}
+
+int
+SampleHistogram::similarSamples(double d)
+{
+ int i;
+ for (i = 0; i < howManyBuckets; i++) {
+ if (d < bucketLimit[i]) return(bucketCount[i]);
+ }
+ return(0);
+}
+
+void
+SampleHistogram::printBuckets(ostream& s)
+{
+ for(int i = 0; i < howManyBuckets; i++) {
+ if (bucketLimit[i] >= HUGE_VAL) {
+ s << "< max : " << bucketCount[i] << "\n";
+ } else {
+ s << "< " << bucketLimit[i] << " : " << bucketCount[i] << "\n";
+ }
+ }
+}
+
+void
+SampleHistogram::reset()
+{
+ this->SampleStatistic::reset();
+ if (howManyBuckets > 0) {
+ for (register int i = 0; i < howManyBuckets; i++) {
+ bucketCount[i] = 0;
+ }
+ }
+}
+
diff --git a/gnu/lib/libg++/g++-include/SmplHist.h b/gnu/lib/libg++/g++-include/SmplHist.h
new file mode 100644
index 00000000000..d8efe119d78
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/SmplHist.h
@@ -0,0 +1,74 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: SmplHist.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+#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++/g++-include/SmplStat.cc b/gnu/lib/libg++/g++-include/SmplStat.cc
new file mode 100644
index 00000000000..461bea43aff
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/SmplStat.cc
@@ -0,0 +1,160 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <stream.h>
+#include <SmplStat.h>
+#include <math.h>
+
+#ifndef HUGE_VAL
+#ifdef HUGE
+#define HUGE_VAL HUGE
+#else
+#include <float.h>
+#define HUGE_VAL DBL_MAX
+#endif
+#endif
+
+// error handling
+
+void default_SampleStatistic_error_handler(const char* msg)
+{
+ cerr << "Fatal SampleStatistic error. " << msg << "\n";
+ exit(1);
+}
+
+one_arg_error_handler_t SampleStatistic_error_handler = default_SampleStatistic_error_handler;
+
+one_arg_error_handler_t set_SampleStatistic_error_handler(one_arg_error_handler_t f)
+{
+ one_arg_error_handler_t old = SampleStatistic_error_handler;
+ SampleStatistic_error_handler = f;
+ return old;
+}
+
+void SampleStatistic::error(const char* msg)
+{
+ (*SampleStatistic_error_handler)(msg);
+}
+
+// t-distribution: given p-value and degrees of freedom, return t-value
+// adapted from Peizer & Pratt JASA, vol63, p1416
+
+double tval(double p, int df)
+{
+ double t;
+ int positive = p >= 0.5;
+ p = (positive)? 1.0 - p : p;
+ if (p <= 0.0 || df <= 0)
+ t = HUGE_VAL;
+ else if (p == 0.5)
+ t = 0.0;
+ else if (df == 1)
+ t = 1.0 / tan((p + p) * 1.57079633);
+ else if (df == 2)
+ t = sqrt(1.0 / ((p + p) * (1.0 - p)) - 2.0);
+ else
+ {
+ double ddf = df;
+ double a = sqrt(log(1.0 / (p * p)));
+ double aa = a * a;
+ a = a - ((2.515517 + (0.802853 * a) + (0.010328 * aa)) /
+ (1.0 + (1.432788 * a) + (0.189269 * aa) +
+ (0.001308 * aa * a)));
+ t = ddf - 0.666666667 + 1.0 / (10.0 * ddf);
+ t = sqrt(ddf * (exp(a * a * (ddf - 0.833333333) / (t * t)) - 1.0));
+ }
+ return (positive)? t : -t;
+}
+
+void
+SampleStatistic::reset()
+{
+ n = 0; x = x2 = 0.0;
+ maxValue = -HUGE_VAL;
+ minValue = HUGE_VAL;
+}
+
+void
+SampleStatistic::operator+=(double value)
+{
+ n += 1;
+ x += value;
+ x2 += (value * value);
+ if ( minValue > value) minValue = value;
+ if ( maxValue < value) maxValue = value;
+}
+
+double
+SampleStatistic::mean()
+{
+ if ( n > 0) {
+ return (x / n);
+ }
+ else {
+ return ( 0.0 );
+ }
+}
+
+double
+SampleStatistic::var()
+{
+ if ( n > 1) {
+ return(( x2 - ((x * x) / n)) / ( n - 1));
+ }
+ else {
+ return ( 0.0 );
+ }
+}
+
+double
+SampleStatistic::stdDev()
+{
+ if ( n <= 0 || this -> var() <= 0) {
+ return(0);
+ } else {
+ return( (double) sqrt( var() ) );
+ }
+}
+
+double
+SampleStatistic::confidence(int interval)
+{
+ int df = n - 1;
+ if (df <= 0) return HUGE_VAL;
+ double t = tval(double(100 + interval) * 0.005, df);
+ if (t == HUGE_VAL)
+ return t;
+ else
+ return (t * stdDev()) / sqrt(double(n));
+}
+
+double
+SampleStatistic::confidence(double p_value)
+{
+ int df = n - 1;
+ if (df <= 0) return HUGE_VAL;
+ double t = tval((1.0 + p_value) * 0.5, df);
+ if (t == HUGE_VAL)
+ return t;
+ else
+ return (t * stdDev()) / sqrt(double(n));
+}
+
+
diff --git a/gnu/lib/libg++/g++-include/SmplStat.h b/gnu/lib/libg++/g++-include/SmplStat.h
new file mode 100644
index 00000000000..6b0a8b04e7d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: SmplStat.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+#ifndef SampleStatistic_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define SampleStatistic_h 1
+
+#include <builtin.h>
+
+class SampleStatistic {
+protected:
+ int n;
+ double x;
+ double x2;
+ double minValue, maxValue;
+
+ public :
+
+ SampleStatistic();
+ virtual ~SampleStatistic();
+ virtual void reset();
+
+ virtual void operator+=(double);
+ int samples();
+ double mean();
+ double stdDev();
+ double var();
+ double min();
+ double max();
+ double confidence(int p_percentage);
+ double confidence(double p_value);
+
+ void error(const char* msg);
+};
+
+// error handlers
+
+extern void default_SampleStatistic_error_handler(const char*);
+extern one_arg_error_handler_t SampleStatistic_error_handler;
+
+extern one_arg_error_handler_t
+ set_SampleStatistic_error_handler(one_arg_error_handler_t f);
+
+inline SampleStatistic:: SampleStatistic(){ reset();}
+inline int SampleStatistic:: samples() {return(n);}
+inline double SampleStatistic:: min() {return(minValue);}
+inline double SampleStatistic:: max() {return(maxValue);}
+inline SampleStatistic::~SampleStatistic() {}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/String.cc b/gnu/lib/libg++/g++-include/String.cc
new file mode 100644
index 00000000000..6e7a9f87e6c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/String.cc
@@ -0,0 +1,1311 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ String class implementation
+ */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <String.h>
+#include <std.h>
+#include <ctype.h>
+#include <limits.h>
+#include <new.h>
+#include <builtin.h>
+
+// extern "C" {
+#include <regex.h>
+// }
+
+void String::error(const char* msg) const
+{
+ (*lib_error_handler)("String", msg);
+}
+
+String::operator const char*() const
+{
+ return (const char*)chars();
+}
+
+// globals
+
+StrRep _nilStrRep = { 0, 1, { 0 } }; // nil strings point here
+String _nilString; // nil SubStrings point here
+
+
+
+
+/*
+ the following inline fcts are specially designed to work
+ in support of String classes, and are not meant as generic replacements
+ for libc "str" functions.
+
+ inline copy fcts - I like left-to-right from->to arguments.
+ all versions assume that `to' argument is non-null
+
+ These are worth doing inline, rather than through calls because,
+ via procedural integration, adjacent copy calls can be smushed
+ together by the optimizer.
+*/
+
+// copy n bytes
+inline static void ncopy(const char* from, char* to, int n)
+{
+ if (from != to) while (--n >= 0) *to++ = *from++;
+}
+
+// copy n bytes, null-terminate
+inline static void ncopy0(const char* from, char* to, int n)
+{
+ if (from != to)
+ {
+ while (--n >= 0) *to++ = *from++;
+ *to = 0;
+ }
+ else
+ to[n] = 0;
+}
+
+// copy until null
+inline static void scopy(const char* from, char* to)
+{
+ if (from != 0) while((*to++ = *from++) != 0);
+}
+
+// copy right-to-left
+inline static void revcopy(const char* from, char* to, short n)
+{
+ if (from != 0) while (--n >= 0) *to-- = *from--;
+}
+
+
+inline static int slen(const char* t) // inline strlen
+{
+ if (t == 0)
+ return 0;
+ else
+ {
+ const char* a = t;
+ while (*a++ != 0);
+ return a - 1 - t;
+ }
+}
+
+// minimum & maximum representable rep size
+
+#define MAXStrRep_SIZE ((1 << (sizeof(short) * CHAR_BIT - 1)) - 1)
+#define MINStrRep_SIZE 16
+
+#ifndef MALLOC_MIN_OVERHEAD
+#define MALLOC_MIN_OVERHEAD 4
+#endif
+
+// The basic allocation primitive:
+// Always round request to something close to a power of two.
+// This ensures a bit of padding, which often means that
+// concatenations don't have to realloc. Plus it tends to
+// be faster when lots of Strings are created and discarded,
+// since just about any version of malloc (op new()) will
+// be faster when it can reuse identically-sized chunks
+
+inline static StrRep* Snew(int newsiz)
+{
+ unsigned int siz = sizeof(StrRep) + newsiz + MALLOC_MIN_OVERHEAD;
+ unsigned int allocsiz = MINStrRep_SIZE;
+ while (allocsiz < siz) allocsiz <<= 1;
+ allocsiz -= MALLOC_MIN_OVERHEAD;
+ if (allocsiz >= MAXStrRep_SIZE)
+ (*lib_error_handler)("String", "Requested length out of range");
+
+ StrRep* rep = (StrRep *) new char[allocsiz];
+ rep->sz = allocsiz - sizeof(StrRep);
+ return rep;
+}
+
+// Do-something-while-allocating routines.
+
+// We live with two ways to signify empty Sreps: either the
+// null pointer (0) or a pointer to the nilStrRep.
+
+// We always signify unknown source lengths (usually when fed a char*)
+// via len == -1, in which case it is computed.
+
+// allocate, copying src if nonull
+
+StrRep* Salloc(StrRep* old, const char* src, int srclen, int newlen)
+{
+ if (old == &_nilStrRep) old = 0;
+ if (srclen < 0) srclen = slen(src);
+ if (newlen < srclen) newlen = srclen;
+ StrRep* rep;
+ if (old == 0 || newlen > old->sz)
+ rep = Snew(newlen);
+ else
+ rep = old;
+
+ rep->len = newlen;
+ ncopy0(src, rep->s, srclen);
+
+ if (old != rep && old != 0) delete old;
+
+ return rep;
+}
+
+// reallocate: Given the initial allocation scheme, it will
+// generally be faster in the long run to get new space & copy
+// than to call realloc
+
+StrRep* Sresize(StrRep* old, int newlen)
+{
+ if (old == &_nilStrRep) old = 0;
+ StrRep* rep;
+ if (old == 0)
+ rep = Snew(newlen);
+ else if (newlen > old->sz)
+ {
+ rep = Snew(newlen);
+ ncopy0(old->s, rep->s, old->len);
+ delete old;
+ }
+ else
+ rep = old;
+
+ rep->len = newlen;
+
+ return rep;
+}
+
+// like allocate, but we know that src is a StrRep
+
+StrRep* Scopy(StrRep* old, 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(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(NO_NRV)
+
+String join(String src[], int n, const String& separator) return x;
+{
+ String sep = separator;
+ int xlen = 0;
+ for (int i = 0; i < n; ++i)
+ xlen += src[i].length();
+ xlen += (n - 1) * sep.length();
+
+ x.alloc(xlen);
+
+ int j = 0;
+
+ for (i = 0; i < n - 1; ++i)
+ {
+ ncopy(src[i].chars(), &(x.rep->s[j]), src[i].length());
+ j += src[i].length();
+ ncopy(sep.chars(), &(x.rep->s[j]), sep.length());
+ j += sep.length();
+ }
+ ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
+}
+
+#else
+
+String join(String src[], int n, const String& separator)
+{
+ String x;
+ String sep = separator;
+ int xlen = 0;
+ for (int i = 0; i < n; ++i)
+ xlen += src[i].length();
+ xlen += (n - 1) * sep.length();
+
+ x.alloc(xlen);
+
+ int j = 0;
+
+ for (i = 0; i < n - 1; ++i)
+ {
+ ncopy(src[i].chars(), &(x.rep->s[j]), src[i].length());
+ j += src[i].length();
+ ncopy(sep.chars(), &(x.rep->s[j]), sep.length());
+ j += sep.length();
+ }
+ ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
+ return x;
+}
+
+#endif
+
+/*
+ misc
+*/
+
+
+StrRep* Sreverse(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(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(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(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);
+ else if (!islower(*p) && !isdigit(*p))
+ break;
+ }
+ }
+ }
+ return dest;
+}
+
+#if defined(__GNUG__) && !defined(NO_NRV)
+
+String replicate(char c, int n) return w;
+{
+ w.rep = Sresize(w.rep, n);
+ char* p = w.rep->s;
+ while (n-- > 0) *p++ = c;
+ *p = 0;
+}
+
+String replicate(const String& y, int n) return w
+{
+ int len = y.length();
+ w.rep = Sresize(w.rep, n * len);
+ char* p = w.rep->s;
+ while (n-- > 0)
+ {
+ ncopy(y.chars(), p, len);
+ p += len;
+ }
+ *p = 0;
+}
+
+String common_prefix(const String& x, const String& y, int startpos) return r;
+{
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[startpos]);
+ const char* ss = xs;
+ const char* topx = &(xchars[x.length()]);
+ const char* ys = &(ychars[startpos]);
+ const char* topy = &(ychars[y.length()]);
+ for (int l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
+ r.rep = Salloc(r.rep, ss, l, l);
+}
+
+String common_suffix(const String& x, const String& y, int startpos) return r;
+{
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[x.length() + startpos]);
+ const char* botx = xchars;
+ const char* ys = &(ychars[y.length() + startpos]);
+ const char* boty = ychars;
+ for (int l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
+ r.rep = Salloc(r.rep, ++xs, l, l);
+}
+
+#else
+
+String replicate(char c, int n)
+{
+ String w;
+ w.rep = Sresize(w.rep, n);
+ char* p = w.rep->s;
+ while (n-- > 0) *p++ = c;
+ *p = 0;
+ return w;
+}
+
+String replicate(const String& y, int n)
+{
+ String w;
+ int len = y.length();
+ w.rep = Sresize(w.rep, n * len);
+ char* p = w.rep->s;
+ while (n-- > 0)
+ {
+ ncopy(y.chars(), p, len);
+ p += len;
+ }
+ *p = 0;
+ return w;
+}
+
+String common_prefix(const String& x, const String& y, int startpos)
+{
+ String r;
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[startpos]);
+ const char* ss = xs;
+ const char* topx = &(xchars[x.length()]);
+ const char* ys = &(ychars[startpos]);
+ const char* topy = &(ychars[y.length()]);
+ for (int l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
+ r.rep = Salloc(r.rep, ss, l, l);
+ return r;
+}
+
+String common_suffix(const String& x, const String& y, int startpos)
+{
+ String r;
+ const char* xchars = x.chars();
+ const char* ychars = y.chars();
+ const char* xs = &(xchars[x.length() + startpos]);
+ const char* botx = xchars;
+ const char* ys = &(ychars[y.length() + startpos]);
+ const char* boty = ychars;
+ for (int l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
+ r.rep = Salloc(r.rep, ++xs, l, l);
+ return r;
+}
+
+#endif
+
+// IO
+
+istream& operator>>(istream& s, String& x)
+{
+ if (!s.ipfx(0) || (!(s.flags() & ios::skipws) && !ws(s)))
+ {
+ s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.
+ return s;
+ }
+ int ch;
+ int i = 0;
+ x.rep = Sresize(x.rep, 20);
+ register streambuf *sb = s.rdbuf();
+ while ((ch = sb->sbumpc()) != EOF)
+ {
+ if (isspace(ch))
+ break;
+ if (i >= x.rep->sz - 1)
+ x.rep = Sresize(x.rep, i+1);
+ x.rep->s[i++] = ch;
+ }
+ x.rep->s[i] = 0;
+ x.rep->len = i;
+ int new_state = s.rdstate();
+ if (i == 0) new_state |= ios::failbit;
+ if (ch == EOF) new_state |= ios::eofbit;
+ s.clear(new_state);
+ return s;
+}
+
+int readline(istream& s, String& x, char terminator, int discard)
+{
+ if (!s.ipfx(0))
+ return 0;
+ int ch;
+ int i = 0;
+ x.rep = Sresize(x.rep, 80);
+ register streambuf *sb = s.rdbuf();
+ while ((ch = sb->sbumpc()) != EOF)
+ {
+ if (ch != terminator || !discard)
+ {
+ if (i >= x.rep->sz - 1)
+ x.rep = Sresize(x.rep, i+1);
+ x.rep->s[i++] = ch;
+ }
+ if (ch == terminator)
+ break;
+ }
+ x.rep->s[i] = 0;
+ x.rep->len = i;
+ if (ch == EOF) s.clear(ios::eofbit|s.rdstate());
+ return i;
+}
+
+
+ostream& operator<<(ostream& s, const SubString& x)
+{
+ const char* a = x.chars();
+ const char* lasta = &(a[x.length()]);
+ while (a < lasta)
+ s.put(*a++);
+ return(s);
+}
+
+// from John.Willis@FAS.RI.CMU.EDU
+
+int String::freq(const SubString& y) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,y.chars(), y.length())>= 0) found++;
+ return(found);
+}
+
+int String::freq(const String& y) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,y.chars(),y.length()) >= 0) found++;
+ return(found);
+}
+
+int String::freq(const char* t) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,t) >= 0) found++;
+ return(found);
+}
+
+int String::freq(char c) const
+{
+ int found = 0;
+ for (unsigned int i = 0; i < length(); i++)
+ if (match(i,length(),0,&c,1) >= 0) found++;
+ return(found);
+}
+
+
+int String::OK() const
+{
+ if (rep == 0 // don't have a rep
+ || rep->len > rep->sz // string oustide bounds
+ || rep->s[rep->len] != 0) // not null-terminated
+ error("invariant failure");
+ return 1;
+}
+
+int SubString::OK() const
+{
+ int v = S != (const char*)0; // have a String;
+ v &= S.OK(); // that is legal
+ v &= pos + len >= S.rep->len;// pos and len within bounds
+ if (!v) S.error("SubString invariant failure");
+ return v;
+}
+
diff --git a/gnu/lib/libg++/g++-include/String.h b/gnu/lib/libg++/g++-include/String.h
new file mode 100644
index 00000000000..0a6ad822039
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/String.h
@@ -0,0 +1,1318 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: String.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+
+#ifndef _String_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _String_h 1
+
+#include <iostream.h>
+#include <Regex.h>
+
+struct StrRep // internal String representations
+{
+ unsigned short len; // string length
+ unsigned short sz; // allocated space
+ char s[1]; // the string starts here
+ // (at least 1 char for trailing null)
+ // allocated & expanded via non-public fcts
+};
+
+// primitive ops on StrReps -- nearly all String fns go through these.
+
+StrRep* Salloc(StrRep*, const char*, int, int);
+StrRep* Scopy(StrRep*, StrRep*);
+StrRep* Sresize(StrRep*, int);
+StrRep* Scat(StrRep*, const char*, int, const char*, int);
+StrRep* Scat(StrRep*, const char*, int,const char*,int, const char*,int);
+StrRep* Sprepend(StrRep*, const char*, int);
+StrRep* Sreverse(StrRep*, StrRep*);
+StrRep* Supcase(StrRep*, StrRep*);
+StrRep* Sdowncase(StrRep*, StrRep*);
+StrRep* Scapitalize(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(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();
+
+ void operator = (const String& y);
+ void operator = (const SubString& y);
+ void operator = (const char* t);
+ void 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();
+
+ void operator = (const String& y);
+ void operator = (const char* y);
+ void operator = (char c);
+ void operator = (const SubString& y);
+
+// concatenation
+
+ void operator += (const String& y);
+ void operator += (const SubString& y);
+ void operator += (const char* t);
+ void operator += (char c);
+
+ void prepend(const String& y);
+ void prepend(const SubString& y);
+ void prepend(const char* t);
+ void prepend(char c);
+
+
+// procedural versions:
+// concatenate first 2 args, store result in last arg
+
+ friend void cat(const String&, const String&, String&);
+ friend void cat(const String&, const SubString&, String&);
+ friend void cat(const String&, const char*, String&);
+ friend void cat(const String&, char, String&);
+
+ friend void cat(const SubString&, const String&, String&);
+ friend void cat(const SubString&, const SubString&, String&);
+ friend void cat(const SubString&, const char*, String&);
+ friend void cat(const SubString&, char, String&);
+
+ friend void cat(const char*, const String&, String&);
+ friend void cat(const char*, const SubString&, String&);
+ friend void cat(const char*, const char*, String&);
+ friend void cat(const char*, char, String&);
+
+// double concatenation, by request. (yes, there are too many versions,
+// but if one is supported, then the others should be too...)
+// Concatenate first 3 args, store in last arg
+
+ friend void cat(const String&,const String&, const String&,String&);
+ friend void cat(const String&,const String&,const SubString&,String&);
+ friend void cat(const String&,const String&, const char*, String&);
+ friend void cat(const String&,const String&, char, String&);
+ friend void cat(const String&,const SubString&,const String&,String&);
+ friend void cat(const String&,const SubString&,const SubString&,String&);
+ friend void cat(const String&,const SubString&, const char*, String&);
+ friend void cat(const String&,const SubString&, char, String&);
+ friend void cat(const String&,const char*, const String&, String&);
+ friend void cat(const String&,const char*, const SubString&, String&);
+ friend void cat(const String&,const char*, const char*, String&);
+ friend void cat(const String&,const char*, char, String&);
+
+ friend void cat(const char*, const String&, const String&,String&);
+ friend void cat(const char*,const String&,const SubString&,String&);
+ friend void cat(const char*,const String&, const char*, String&);
+ friend void cat(const char*,const String&, char, String&);
+ friend void cat(const char*,const SubString&,const String&,String&);
+ friend void cat(const char*,const SubString&,const SubString&,String&);
+ friend void cat(const char*,const SubString&, const char*, String&);
+ friend void cat(const char*,const SubString&, char, String&);
+ friend void cat(const char*,const char*, const String&, String&);
+ friend void cat(const char*,const char*, const SubString&, String&);
+ friend void cat(const char*,const char*, const char*, String&);
+ friend void cat(const char*,const char*, char, String&);
+
+
+// searching & matching
+
+// return position of target in string or -1 for failure
+
+ int index(char c, int startpos = 0) const;
+ int index(const String& y, int startpos = 0) const;
+ int index(const SubString& y, int startpos = 0) const;
+ int index(const char* t, int startpos = 0) const;
+ int index(const Regex& r, int startpos = 0) const;
+
+// return 1 if target appears anyhere in String; else 0
+
+ int contains(char c) const;
+ int contains(const String& y) const;
+ int contains(const SubString& y) const;
+ int contains(const char* t) const;
+ int contains(const Regex& r) const;
+
+// return 1 if target appears anywhere after position pos
+// (or before, if pos is negative) in String; else 0
+
+ int contains(char c, int pos) const;
+ int contains(const String& y, int pos) const;
+ int contains(const SubString& y, int pos) const;
+ int contains(const char* t, int pos) const;
+ int contains(const Regex& r, int pos) const;
+
+// return 1 if target appears at position pos in String; else 0
+
+ int matches(char c, int pos = 0) const;
+ int matches(const String& y, int pos = 0) const;
+ int matches(const SubString& y, int pos = 0) const;
+ int matches(const char* t, int pos = 0) const;
+ int matches(const Regex& r, int pos = 0) const;
+
+// return number of occurences of target in String
+
+ int freq(char c) const;
+ int freq(const String& y) const;
+ int freq(const SubString& y) const;
+ int freq(const char* t) const;
+
+// SubString extraction
+
+// Note that you can't take a substring of a const String, since
+// this leaves open the possiblility of indirectly modifying the
+// String through the SubString
+
+ SubString at(int pos, int len);
+ SubString operator () (int pos, int len); // synonym for at
+
+ SubString at(const String& x, int startpos = 0);
+ SubString at(const SubString& x, int startpos = 0);
+ SubString at(const char* t, int startpos = 0);
+ SubString at(char c, int startpos = 0);
+ SubString at(const Regex& r, int startpos = 0);
+
+ SubString before(int pos);
+ SubString before(const String& x, int startpos = 0);
+ SubString before(const SubString& x, int startpos = 0);
+ SubString before(const char* t, int startpos = 0);
+ SubString before(char c, int startpos = 0);
+ SubString before(const Regex& r, int startpos = 0);
+
+ SubString through(int pos);
+ SubString through(const String& x, int startpos = 0);
+ SubString through(const SubString& x, int startpos = 0);
+ SubString through(const char* t, int startpos = 0);
+ SubString through(char c, int startpos = 0);
+ SubString through(const Regex& r, int startpos = 0);
+
+ SubString from(int pos);
+ SubString from(const String& x, int startpos = 0);
+ SubString from(const SubString& x, int startpos = 0);
+ SubString from(const char* t, int startpos = 0);
+ SubString from(char c, int startpos = 0);
+ SubString from(const Regex& r, int startpos = 0);
+
+ SubString after(int pos);
+ SubString after(const String& x, int startpos = 0);
+ SubString after(const SubString& x, int startpos = 0);
+ SubString after(const char* t, int startpos = 0);
+ SubString after(char c, int startpos = 0);
+ SubString after(const Regex& r, int startpos = 0);
+
+
+// deletion
+
+// delete len chars starting at pos
+ void del(int pos, int len);
+
+// delete the first occurrence of target after startpos
+
+ void del(const String& y, int startpos = 0);
+ void del(const SubString& y, int startpos = 0);
+ void del(const char* t, int startpos = 0);
+ void del(char c, int startpos = 0);
+ void del(const Regex& r, int startpos = 0);
+
+// global substitution: substitute all occurrences of pat with repl
+
+ int gsub(const String& pat, const String& repl);
+ int gsub(const SubString& pat, const String& repl);
+ int gsub(const char* pat, const String& repl);
+ int gsub(const char* pat, const char* repl);
+ int gsub(const Regex& pat, const String& repl);
+
+// friends & utilities
+
+// split string into array res at separators; return number of elements
+
+ friend int split(const String& x, String res[], int maxn,
+ const String& sep);
+ friend int split(const String& x, String res[], int maxn,
+ const Regex& sep);
+
+ friend String common_prefix(const String& x, const String& y,
+ int startpos = 0);
+ friend String common_suffix(const String& x, const String& y,
+ int startpos = -1);
+ friend String replicate(char c, int n);
+ friend String replicate(const String& y, int n);
+ friend String join(String src[], int n, const String& sep);
+
+// simple builtin transformations
+
+ friend String reverse(const String& x);
+ friend String upcase(const String& x);
+ friend String downcase(const String& x);
+ friend String capitalize(const String& x);
+
+// in-place versions of above
+
+ void reverse();
+ void upcase();
+ void downcase();
+ void capitalize();
+
+// element extraction
+
+ char& operator [] (int i);
+ char elem(int i) const;
+ char firstchar() const;
+ char lastchar() const;
+
+// conversion
+
+ operator const char*() const;
+ const char* chars() const;
+
+
+// IO
+
+ friend ostream& operator<<(ostream& s, const String& x);
+ friend ostream& operator<<(ostream& s, const SubString& x);
+ friend istream& operator>>(istream& s, String& x);
+
+ friend int readline(istream& s, String& x,
+ char terminator = '\n',
+ int discard_terminator = 1);
+
+// status
+
+ unsigned int length() const;
+ int empty() const;
+
+// preallocate some space for String
+ void alloc(int newsize);
+
+// report current allocation (not length!)
+
+ int allocation() const;
+
+
+ void error(const char* msg) const;
+
+ int OK() const;
+};
+
+typedef String StrTmp; // for backward compatibility
+
+// other externs
+
+int compare(const String& x, const String& y);
+int compare(const String& x, const SubString& y);
+int compare(const String& x, const char* y);
+int compare(const SubString& x, const String& y);
+int compare(const SubString& x, const SubString& y);
+int compare(const SubString& x, const char* y);
+int fcompare(const String& x, const String& y); // ignore case
+
+extern StrRep _nilStrRep;
+extern String _nilString;
+
+// other inlines
+
+String operator + (const String& x, const String& y);
+String operator + (const String& x, const SubString& y);
+String operator + (const String& x, const char* y);
+String operator + (const String& x, char y);
+String operator + (const SubString& x, const String& y);
+String operator + (const SubString& x, const SubString& y);
+String operator + (const SubString& x, const char* y);
+String operator + (const SubString& x, char y);
+String operator + (const char* x, const String& y);
+String operator + (const char* x, const SubString& y);
+
+int operator==(const String& x, const String& y);
+int operator!=(const String& x, const String& y);
+int operator> (const String& x, const String& y);
+int operator>=(const String& x, const String& y);
+int operator< (const String& x, const String& y);
+int operator<=(const String& x, const String& y);
+int operator==(const String& x, const SubString& y);
+int operator!=(const String& x, const SubString& y);
+int operator> (const String& x, const SubString& y);
+int operator>=(const String& x, const SubString& y);
+int operator< (const String& x, const SubString& y);
+int operator<=(const String& x, const SubString& y);
+int operator==(const String& x, const char* t);
+int operator!=(const String& x, const char* t);
+int operator> (const String& x, const char* t);
+int operator>=(const String& x, const char* t);
+int operator< (const String& x, const char* t);
+int operator<=(const String& x, const char* t);
+int operator==(const SubString& x, const String& y);
+int operator!=(const SubString& x, const String& y);
+int operator> (const SubString& x, const String& y);
+int operator>=(const SubString& x, const String& y);
+int operator< (const SubString& x, const String& y);
+int operator<=(const SubString& x, const String& y);
+int operator==(const SubString& x, const SubString& y);
+int operator!=(const SubString& x, const SubString& y);
+int operator> (const SubString& x, const SubString& y);
+int operator>=(const SubString& x, const SubString& y);
+int operator< (const SubString& x, const SubString& y);
+int operator<=(const SubString& x, const SubString& y);
+int operator==(const SubString& x, const char* t);
+int operator!=(const SubString& x, const char* t);
+int operator> (const SubString& x, const char* t);
+int operator>=(const SubString& x, const char* t);
+int operator< (const SubString& x, const char* t);
+int operator<=(const SubString& x, const char* t);
+
+
+// status reports, needed before defining other things
+
+inline unsigned int String::length() const { return rep->len; }
+inline int String::empty() const { return rep->len == 0; }
+inline const char* String::chars() const { return &(rep->s[0]); }
+inline int String::allocation() const { return rep->sz; }
+inline void String::alloc(int newsize) { rep = Sresize(rep, newsize); }
+
+inline unsigned int SubString::length() const { return len; }
+inline int SubString::empty() const { return len == 0; }
+inline const char* SubString::chars() const { return &(S.rep->s[pos]); }
+
+
+// constructors
+
+inline String::String()
+ : rep(&_nilStrRep) {}
+inline String::String(const String& x)
+ : rep(Scopy(0, x.rep)) {}
+inline String::String(const char* t)
+ : rep(Salloc(0, t, -1, -1)) {}
+inline String::String(const char* t, int tlen)
+ : rep(Salloc(0, t, tlen, tlen)) {}
+inline String::String(const SubString& y)
+ : rep(Salloc(0, y.chars(), y.length(), y.length())) {}
+inline String::String(char c)
+ : rep(Salloc(0, &c, 1, 1)) {}
+
+inline String::~String() { if (rep != &_nilStrRep) delete rep; }
+
+inline SubString::SubString(const SubString& x)
+ :S(x.S), pos(x.pos), len(x.len) {}
+inline SubString::SubString(String& x, int first, int l)
+ :S(x), pos(first), len(l) {}
+
+inline SubString::~SubString() {}
+
+// assignment
+
+inline void String::operator = (const String& y)
+{
+ rep = Scopy(rep, y.rep);
+}
+
+inline void String::operator=(const char* t)
+{
+ rep = Salloc(rep, t, -1, -1);
+}
+
+inline void String::operator=(const SubString& y)
+{
+ rep = Salloc(rep, y.chars(), y.length(), y.length());
+}
+
+inline void String::operator=(char c)
+{
+ rep = Salloc(rep, &c, 1, 1);
+}
+
+
+inline void SubString::operator = (const char* ys)
+{
+ assign(0, ys);
+}
+
+inline void SubString::operator = (char ch)
+{
+ assign(0, &ch, 1);
+}
+
+inline void SubString::operator = (const String& y)
+{
+ assign(y.rep, y.chars(), y.length());
+}
+
+inline void SubString::operator = (const SubString& y)
+{
+ assign(y.S.rep, y.chars(), y.length());
+}
+
+// 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 void String::operator +=(const String& y)
+{
+ cat(*this, y, *this);
+}
+
+inline void String::operator +=(const SubString& y)
+{
+ cat(*this, y, *this);
+}
+
+inline void String::operator += (const char* y)
+{
+ cat(*this, y, *this);
+}
+
+inline void String:: operator +=(char y)
+{
+ cat(*this, y, *this);
+}
+
+// constructive concatenation
+
+#if defined(__GNUG__) && !defined(NO_NRV)
+
+inline String operator + (const String& x, const String& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const String& x, const SubString& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const String& x, const char* y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const String& x, char y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, const String& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, const SubString& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, const char* y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const SubString& x, char y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const char* x, const String& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String operator + (const char* x, const SubString& y) return r;
+{
+ cat(x, y, r);
+}
+
+inline String reverse(const String& x) return r;
+{
+ r.rep = Sreverse(x.rep, r.rep);
+}
+
+inline String upcase(const String& x) return r;
+{
+ r.rep = Supcase(x.rep, r.rep);
+}
+
+inline String downcase(const String& x) return r;
+{
+ r.rep = Sdowncase(x.rep, r.rep);
+}
+
+inline String capitalize(const String& x) return r;
+{
+ r.rep = Scapitalize(x.rep, r.rep);
+}
+
+#else /* NO_NRV */
+
+inline String operator + (const String& x, const String& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const String& x, const SubString& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const String& x, const char* y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const String& x, char y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, const String& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, const SubString& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, const char* y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const SubString& x, char y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const char* x, const String& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String operator + (const char* x, const SubString& y)
+{
+ String r; cat(x, y, r); return r;
+}
+
+inline String reverse(const String& x)
+{
+ String r; r.rep = Sreverse(x.rep, r.rep); return r;
+}
+
+inline String upcase(const String& x)
+{
+ String r; r.rep = Supcase(x.rep, r.rep); return r;
+}
+
+inline String downcase(const String& x)
+{
+ String r; r.rep = Sdowncase(x.rep, r.rep); return r;
+}
+
+inline String capitalize(const String& x)
+{
+ String r; r.rep = Scapitalize(x.rep, r.rep); return r;
+}
+
+#endif
+
+// prepend
+
+inline void String::prepend(const String& y)
+{
+ rep = Sprepend(rep, y.chars(), y.length());
+}
+
+inline void String::prepend(const char* y)
+{
+ rep = Sprepend(rep, y, -1);
+}
+
+inline void String::prepend(char y)
+{
+ rep = Sprepend(rep, &y, 1);
+}
+
+inline void String::prepend(const SubString& y)
+{
+ rep = Sprepend(rep, y.chars(), y.length());
+}
+
+// misc transformations
+
+
+inline void String::reverse()
+{
+ rep = Sreverse(rep, rep);
+}
+
+
+inline void String::upcase()
+{
+ rep = Supcase(rep, rep);
+}
+
+
+inline void String::downcase()
+{
+ rep = Sdowncase(rep, rep);
+}
+
+
+inline void String::capitalize()
+{
+ rep = Scapitalize(rep, rep);
+}
+
+// element extraction
+
+inline char& String::operator [] (int i)
+{
+ if (((unsigned)i) >= length()) error("invalid index");
+ return rep->s[i];
+}
+
+inline char String::elem (int i) const
+{
+ if (((unsigned)i) >= length()) error("invalid index");
+ return rep->s[i];
+}
+
+inline char String::firstchar() const
+{
+ return elem(0);
+}
+
+inline char String::lastchar() const
+{
+ return elem(length() - 1);
+}
+
+// searching
+
+inline int String::index(char c, int startpos) const
+{
+ return search(startpos, length(), c);
+}
+
+inline int String::index(const char* t, int startpos) const
+{
+ return search(startpos, length(), t);
+}
+
+inline int String::index(const String& y, int startpos) const
+{
+ return search(startpos, length(), y.chars(), y.length());
+}
+
+inline int String::index(const SubString& y, int startpos) const
+{
+ return search(startpos, length(), y.chars(), y.length());
+}
+
+inline int String::index(const Regex& r, int startpos) const
+{
+ int unused; return r.search(chars(), length(), unused, startpos);
+}
+
+inline int String::contains(char c) const
+{
+ return search(0, length(), c) >= 0;
+}
+
+inline int String::contains(const char* t) const
+{
+ return search(0, length(), t) >= 0;
+}
+
+inline int String::contains(const String& y) const
+{
+ return search(0, length(), y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(const SubString& y) const
+{
+ return search(0, length(), y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(char c, int p) const
+{
+ return match(p, length(), 0, &c, 1) >= 0;
+}
+
+inline int String::contains(const char* t, int p) const
+{
+ return match(p, length(), 0, t) >= 0;
+}
+
+inline int String::contains(const String& y, int p) const
+{
+ return match(p, length(), 0, y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(const SubString& y, int p) const
+{
+ return match(p, length(), 0, y.chars(), y.length()) >= 0;
+}
+
+inline int String::contains(const Regex& r) const
+{
+ int unused; return r.search(chars(), length(), unused, 0) >= 0;
+}
+
+inline int String::contains(const Regex& r, int p) const
+{
+ return r.match(chars(), length(), p) >= 0;
+}
+
+
+inline int String::matches(const SubString& y, int p) const
+{
+ return match(p, length(), 1, y.chars(), y.length()) >= 0;
+}
+
+inline int String::matches(const String& y, int p) const
+{
+ return match(p, length(), 1, y.chars(), y.length()) >= 0;
+}
+
+inline int String::matches(const char* t, int p) const
+{
+ return match(p, length(), 1, t) >= 0;
+}
+
+inline int String::matches(char c, int p) const
+{
+ return match(p, length(), 1, &c, 1) >= 0;
+}
+
+inline int String::matches(const Regex& r, int p) const
+{
+ int l = (p < 0)? -p : length() - p;
+ return r.match(chars(), length(), p) == l;
+}
+
+
+inline int SubString::contains(const char* t) const
+{
+ return S.search(pos, pos+len, t) >= 0;
+}
+
+inline int SubString::contains(const String& y) const
+{
+ return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
+}
+
+inline int SubString::contains(const SubString& y) const
+{
+ return S.search(pos, pos+len, y.chars(), y.length()) >= 0;
+}
+
+inline int SubString::contains(char c) const
+{
+ return S.search(pos, pos+len, c) >= 0;
+}
+
+inline int SubString::contains(const Regex& r) const
+{
+ int unused; return r.search(chars(), len, unused, 0) >= 0;
+}
+
+inline int SubString::matches(const Regex& r) const
+{
+ return r.match(chars(), len, 0) == len;
+}
+
+
+inline int String::gsub(const String& pat, const String& r)
+{
+ return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
+}
+
+inline int String::gsub(const SubString& pat, const String& r)
+{
+ return _gsub(pat.chars(), pat.length(), r.chars(), r.length());
+}
+
+inline int String::gsub(const Regex& pat, const String& r)
+{
+ return _gsub(pat, r.chars(), r.length());
+}
+
+inline int String::gsub(const char* pat, const String& r)
+{
+ return _gsub(pat, -1, r.chars(), r.length());
+}
+
+inline int String::gsub(const char* pat, const char* r)
+{
+ return _gsub(pat, -1, r, -1);
+}
+
+
+
+inline ostream& operator<<(ostream& s, const String& x)
+{
+ s << x.chars(); return s;
+}
+
+// a zillion comparison operators
+
+inline int operator==(const String& x, const String& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator!=(const String& x, const String& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator>(const String& x, const String& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator>=(const String& x, const String& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator<(const String& x, const String& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator<=(const String& x, const String& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator==(const String& x, const SubString& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator!=(const String& x, const SubString& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator>(const String& x, const SubString& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator>=(const String& x, const SubString& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator<(const String& x, const SubString& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator<=(const String& x, const SubString& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator==(const String& x, const char* t)
+{
+ return compare(x, t) == 0;
+}
+
+inline int operator!=(const String& x, const char* t)
+{
+ return compare(x, t) != 0;
+}
+
+inline int operator>(const String& x, const char* t)
+{
+ return compare(x, t) > 0;
+}
+
+inline int operator>=(const String& x, const char* t)
+{
+ return compare(x, t) >= 0;
+}
+
+inline int operator<(const String& x, const char* t)
+{
+ return compare(x, t) < 0;
+}
+
+inline int operator<=(const String& x, const char* t)
+{
+ return compare(x, t) <= 0;
+}
+
+inline int operator==(const SubString& x, const String& y)
+{
+ return compare(y, x) == 0;
+}
+
+inline int operator!=(const SubString& x, const String& y)
+{
+ return compare(y, x) != 0;
+}
+
+inline int operator>(const SubString& x, const String& y)
+{
+ return compare(y, x) < 0;
+}
+
+inline int operator>=(const SubString& x, const String& y)
+{
+ return compare(y, x) <= 0;
+}
+
+inline int operator<(const SubString& x, const String& y)
+{
+ return compare(y, x) > 0;
+}
+
+inline int operator<=(const SubString& x, const String& y)
+{
+ return compare(y, x) >= 0;
+}
+
+inline int operator==(const SubString& x, const SubString& y)
+{
+ return compare(x, y) == 0;
+}
+
+inline int operator!=(const SubString& x, const SubString& y)
+{
+ return compare(x, y) != 0;
+}
+
+inline int operator>(const SubString& x, const SubString& y)
+{
+ return compare(x, y) > 0;
+}
+
+inline int operator>=(const SubString& x, const SubString& y)
+{
+ return compare(x, y) >= 0;
+}
+
+inline int operator<(const SubString& x, const SubString& y)
+{
+ return compare(x, y) < 0;
+}
+
+inline int operator<=(const SubString& x, const SubString& y)
+{
+ return compare(x, y) <= 0;
+}
+
+inline int operator==(const SubString& x, const char* t)
+{
+ return compare(x, t) == 0;
+}
+
+inline int operator!=(const SubString& x, const char* t)
+{
+ return compare(x, t) != 0;
+}
+
+inline int operator>(const SubString& x, const char* t)
+{
+ return compare(x, t) > 0;
+}
+
+inline int operator>=(const SubString& x, const char* t)
+{
+ return compare(x, t) >= 0;
+}
+
+inline int operator<(const SubString& x, const char* t)
+{
+ return compare(x, t) < 0;
+}
+
+inline int operator<=(const SubString& x, const char* t)
+{
+ return compare(x, t) <= 0;
+}
+
+
+// a helper needed by at, before, etc.
+
+inline SubString String::_substr(int first, int l)
+{
+ if (first < 0 || (unsigned)(first + l) > length() )
+ return SubString(_nilString, 0, 0) ;
+ else
+ return SubString(*this, first, l);
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/Uniform.cc b/gnu/lib/libg++/g++-include/Uniform.cc
new file mode 100644
index 00000000000..2bf7259bdca
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Uniform.cc
@@ -0,0 +1,27 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Uniform.h>
+
+double Uniform::operator()()
+{
+ return( pLow + delta * pGenerator -> asDouble() );
+}
diff --git a/gnu/lib/libg++/g++-include/Uniform.h b/gnu/lib/libg++/g++-include/Uniform.h
new file mode 100644
index 00000000000..1f3318303d9
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Uniform.h
@@ -0,0 +1,74 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Uniform.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+#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++/g++-include/Weibull.cc b/gnu/lib/libg++/g++-include/Weibull.cc
new file mode 100644
index 00000000000..02670b933d2
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Weibull.cc
@@ -0,0 +1,33 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <Random.h>
+#include <Weibull.h>
+
+//
+// See Simulation, Modelling & Analysis by Law & Kelton, pp259
+//
+// This is the ``polar'' method.
+//
+
+double Weibull::operator()()
+{
+ return( pow(pBeta * ( - log(1 - pGenerator -> asDouble()) ), pInvAlpha) );
+}
diff --git a/gnu/lib/libg++/g++-include/Weibull.h b/gnu/lib/libg++/g++-include/Weibull.h
new file mode 100644
index 00000000000..9e09ee00f8f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/Weibull.h
@@ -0,0 +1,76 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Dirk Grunwald (grunwald@cs.uiuc.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: Weibull.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+#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++/g++-include/_G_config.h b/gnu/lib/libg++/g++-include/_G_config.h
new file mode 100644
index 00000000000..109a3d622a5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/_G_config.h
@@ -0,0 +1,52 @@
+/* $Id: _G_config.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $ */
+
+/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
+#ifndef _G_config_h
+#define _G_config_h
+#define _G_LIB_VERSION "2.4"
+#define _G_NAMES_HAVE_UNDERSCORE 1
+#define _G_DOLLAR_IN_LABEL 1
+#define _G_HAVE_ST_BLKSIZE 1
+typedef unsigned long _G_clock_t;
+typedef short _G_dev_t;
+typedef long _G_fpos_t;
+typedef unsigned short _G_gid_t;
+typedef unsigned long _G_ino_t;
+typedef unsigned short _G_mode_t;
+typedef unsigned short _G_nlink_t;
+typedef long _G_off_t;
+typedef short _G_pid_t;
+typedef int _G_ptrdiff_t;
+typedef unsigned int _G_sigset_t;
+typedef unsigned int _G_size_t;
+typedef long _G_time_t;
+typedef unsigned short _G_uid_t;
+typedef unsigned short _G_wchar_t;
+typedef int /* default */ _G_int32_t;
+typedef unsigned int /* default */ _G_uint32_t;
+typedef int /* default */ _G_ssize_t;
+typedef char* /* default */ _G_va_list;
+#define _G_signal_return_type void
+#define _G_sprintf_return_type int
+#define _G_BUFSIZ 1024
+#define _G_FOPEN_MAX 20
+#define _G_FILENAME_MAX 1024
+#define _G_NULL 0 /* default */
+#define _G_USE_PROTOS
+#ifdef _G_USE_PROTOS
+#define _G_ARGS(ARGLIST) ARGLIST
+#else
+#define _G_ARGS(ARGLIST) (...)
+#endif
+/* #define _G_SYSV */
+#define _G_HAVE_SYS_RESOURCE 1
+#define _G_HAVE_SYS_SOCKET 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_HAVE_UNISTD 1
+#define _G_HAVE_DIRENT 1
+#define _G_HAVE_CURSES 1
+#define _G_CURSES_FORMAT_ARG const char *fmt,
+#define _G_MATH_H_INLINES 0
+/* #define _G_BROKEN_SIGNED_CHAR */
+/* #define _G_FRIEND_BUG */
+#endif /* !_G_config_h */
diff --git a/gnu/lib/libg++/g++-include/builtin.cc b/gnu/lib/libg++/g++-include/builtin.cc
new file mode 100644
index 00000000000..6b9abe5380c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/builtin.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
diff --git a/gnu/lib/libg++/g++-include/builtin.h b/gnu/lib/libg++/g++-include/builtin.h
new file mode 100644
index 00000000000..0c52258eaee
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/builtin.h
@@ -0,0 +1,160 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: builtin.h,v 1.1 1995/10/18 08:38:18 deraadt Exp $
+*/
+
+/*
+ arithmetic, etc. functions on built in types
+*/
+
+
+#ifndef _builtin_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _builtin_h 1
+
+#include <stddef.h>
+#include <std.h>
+#include <math.h>
+
+#ifdef __GNUG__
+#define _VOLATILE_VOID volatile void
+#else
+#define _VOLATILE_VOID void
+#endif
+
+typedef void (*one_arg_error_handler_t)(const char*);
+typedef void (*two_arg_error_handler_t)(const char*, const char*);
+
+long gcd(long, long);
+long lg(unsigned long);
+double pow(double, long);
+long pow(long, long);
+
+double start_timer();
+double return_elapsed_time(double last_time = 0.0);
+
+char* dtoa(double x, char cvt = 'g', int width = 0, int prec = 6);
+
+unsigned int hashpjw(const char*);
+unsigned int multiplicativehash(int);
+unsigned int foldhash(double);
+
+extern _VOLATILE_VOID default_one_arg_error_handler(const char*);
+extern _VOLATILE_VOID default_two_arg_error_handler(const char*, const char*);
+
+extern two_arg_error_handler_t lib_error_handler;
+
+extern two_arg_error_handler_t
+ set_lib_error_handler(two_arg_error_handler_t f);
+
+
+double abs(double arg);
+float abs(float arg);
+short abs(short arg);
+long abs(long arg);
+int sign(long arg);
+int sign(double arg);
+long sqr(long arg);
+double sqr(double arg);
+int even(long arg);
+int odd(long arg);
+long lcm(long x, long y);
+void (setbit)(long& x, long b);
+void clearbit(long& x, long b);
+int testbit(long x, long b);
+
+#if !defined(IV)
+
+#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
+inline double abs(double arg)
+{
+ return (arg < 0.0)? -arg : arg;
+}
+#endif
+
+inline float abs(float arg)
+{
+ return (arg < 0.0)? -arg : arg;
+}
+
+inline short abs(short arg)
+{
+ return (arg < 0)? -arg : arg;
+}
+
+inline long abs(long arg)
+{
+ return (arg < 0)? -arg : arg;
+}
+
+inline int sign(long arg)
+{
+ return (arg == 0) ? 0 : ( (arg > 0) ? 1 : -1 );
+}
+
+inline int sign(double arg)
+{
+ return (arg == 0.0) ? 0 : ( (arg > 0.0) ? 1 : -1 );
+}
+
+inline long sqr(long arg)
+{
+ return arg * arg;
+}
+
+#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
+inline double sqr(double arg)
+{
+ return arg * arg;
+}
+#endif
+
+inline int even(long arg)
+{
+ return !(arg & 1);
+}
+
+inline int odd(long arg)
+{
+ return (arg & 1);
+}
+
+inline long lcm(long x, long y)
+{
+ return x / gcd(x, y) * y;
+}
+
+inline void (setbit)(long& x, long b)
+{
+ x |= (1 << b);
+}
+
+inline void clearbit(long& x, long b)
+{
+ x &= ~(1 << b);
+}
+
+inline int testbit(long x, long b)
+{
+ return ((x & (1 << b)) != 0);
+}
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/chr.cc b/gnu/lib/libg++/g++-include/chr.cc
new file mode 100644
index 00000000000..d580a629f5a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/chr.cc
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <AllocRing.h>
+
+extern AllocRing _libgxx_fmtq;
+
+char* chr(char ch, int width)
+{
+ int len = 1;
+ int wrksiz = len + width + 1;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ char* fmt = fmtbase;
+ for (int blanks = width - len; blanks > 0; --blanks)
+ *fmt++ = ' ';
+ *fmt++ = ch;
+ *fmt = 0;
+ return fmtbase;
+}
diff --git a/gnu/lib/libg++/g++-include/compare.cc b/gnu/lib/libg++/g++-include/compare.cc
new file mode 100644
index 00000000000..aae8409a2aa
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/compare.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <compare.h>
diff --git a/gnu/lib/libg++/g++-include/compare.h b/gnu/lib/libg++/g++-include/compare.h
new file mode 100644
index 00000000000..a4730244881
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/compare.h
@@ -0,0 +1,92 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: compare.h,v 1.1 1995/10/18 08:38:19 deraadt Exp $
+*/
+
+#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++/g++-include/dtoa.cc b/gnu/lib/libg++/g++-include/dtoa.cc
new file mode 100644
index 00000000000..81d7551daae
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/dtoa.cc
@@ -0,0 +1,335 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <math.h>
+#include <values.h>
+#include <AllocRing.h>
+
+extern AllocRing _libgxx_fmtq;
+
+#ifdef __GNUC__ /* cfront cannot compile this routine */
+// OBSOLETE ROUTINE!
+
+char* dtoa(double fpnum, char cvt, int width, int prec)
+{
+ // set up workspace
+
+ // max possible digits <= those need to show all of prec + exp
+ // <= ceil(log10(HUGE)) plus space for null, etc.
+
+ const int worksiz = int((M_LN2 / M_LN10) * DMAXEXP) + 8;
+
+ // for fractional part
+ char fwork[worksiz];
+ char* fw = fwork;
+
+ // for integer part
+ char iwork[worksiz];
+ char* iworkend = &iwork[sizeof(iwork) - 1];
+ char* iw = iworkend;
+ *iw = 0;
+
+ // for exponent part
+
+ const int eworksiz = int(M_LN2 * _DEXPLEN) + 8;
+ char ework[eworksiz];
+ char* eworkend = &ework[sizeof(ework) - 1];
+ char* ew = eworkend;
+ *ew = 0;
+
+#if (_IEEE != 0)
+ if (isinf(fpnum))
+ {
+ char* inffmt = (char *) _libgxx_fmtq.alloc(5);
+ char* inffmtp = inffmt;
+ if (fpnum < 0)
+ *inffmtp++ = '-';
+ strcpy(inffmtp, "Inf");
+ return inffmt;
+ }
+
+ if (isnan(fpnum))
+ {
+ char* nanfmt = (char *) _libgxx_fmtq.alloc(4);
+ strcpy(nanfmt, "NaN");
+ return nanfmt;
+ }
+#endif
+
+ // grab sign & make non-negative
+ int is_neg = fpnum < 0;
+ if (is_neg) fpnum = -fpnum;
+
+ // precision matters
+
+ if (prec > worksiz - 2) // can't have more prec than supported
+ prec = worksiz - 2;
+
+ double powprec;
+ if (prec == 6)
+ powprec = 1.0e6;
+ else
+ powprec = pow(10.0, (long) prec);
+
+ double rounder = 0.5 / powprec;
+
+ int f_fmt = cvt == 'f' ||
+ ((cvt == 'g') && (fpnum == 0.0 || (fpnum >= 1e-4 && fpnum < powprec)));
+
+ int iwidth = 0;
+ int fwidth = 0;
+ int ewidth = 0;
+
+ if (f_fmt) // fixed format
+ {
+ double ipart;
+ double fpart = modf(fpnum, &ipart);
+
+ // convert fractional part
+
+ if (fpart >= rounder || cvt != 'g')
+ {
+ fpart += rounder;
+ if (fpart >= 1.0)
+ {
+ ipart += 1.0;
+ fpart -= 1.0;
+ }
+ double ffpart = fpart;
+ double ifpart;
+ for (int i = 0; i < prec; ++i)
+ {
+ ffpart = modf(ffpart * 10.0, &ifpart);
+ *fw++ = '0' + int(ifpart);
+ ++fwidth;
+ }
+ if (cvt == 'g') // inhibit trailing zeroes if g-fmt
+ {
+ for (char* p = fw - 1; p >= fwork && *p == '0'; --p)
+ {
+ *p = 0;
+ --fwidth;
+ }
+ }
+ }
+
+ // convert integer part
+ if (ipart == 0.0)
+ {
+ if (cvt != 'g' || fwidth < prec || fwidth < width)
+ {
+ *--iw = '0'; ++iwidth;
+ }
+ }
+ else if (ipart <= double(MAXLONG)) // a useful speedup
+ {
+ long li = long(ipart);
+ while (li != 0)
+ {
+ *--iw = '0' + (li % 10);
+ li = li / 10;
+ ++iwidth;
+ }
+ }
+ else // the slow way
+ {
+ while (ipart > 0.5)
+ {
+ double ff = modf(ipart / 10.0, &ipart);
+ ff = (ff + 0.05) * 10.0;
+ *--iw = '0' + int(ff);
+ ++iwidth;
+ }
+ }
+
+ // g-fmt: kill part of frac if prec/width exceeded
+ if (cvt == 'g')
+ {
+ int m = prec;
+ if (m < width)
+ m = width;
+ int adj = iwidth + fwidth - m;
+ if (adj > fwidth)
+ adj = fwidth;
+ if (adj > 0)
+ {
+ for (char* f = &fwork[fwidth-1]; f >= fwork && adj > 0; --adj, --f)
+ {
+ --fwidth;
+ char ch = *f;
+ *f = 0;
+ if (ch > '5') // properly round: unavoidable propagation
+ {
+ int carry = 1;
+ for (char* p = f - 1; p >= fwork && carry; --p)
+ {
+ ++*p;
+ if (*p > '9')
+ *p = '0';
+ else
+ carry = 0;
+ }
+ if (carry)
+ {
+ for (p = iworkend - 1; p >= iw && carry; --p)
+ {
+ ++*p;
+ if (*p > '9')
+ *p = '0';
+ else
+ carry = 0;
+ }
+ if (carry)
+ {
+ *--iw = '1';
+ ++iwidth;
+ --adj;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+ else // e-fmt
+ {
+
+ // normalize
+ int exp = 0;
+ while (fpnum >= 10.0)
+ {
+ fpnum *= 0.1;
+ ++exp;
+ }
+ double almost_one = 1.0 - rounder;
+ while (fpnum > 0.0 && fpnum < almost_one)
+ {
+ fpnum *= 10.0;
+ --exp;
+ }
+
+ double ipart;
+ double fpart = modf(fpnum, &ipart);
+
+
+ if (cvt == 'g') // used up one digit for int part...
+ {
+ --prec;
+ powprec /= 10.0;
+ rounder = 0.5 / powprec;
+ }
+
+ // convert fractional part -- almost same as above
+ if (fpart >= rounder || cvt != 'g')
+ {
+ fpart += rounder;
+ if (fpart >= 1.0)
+ {
+ fpart -= 1.0;
+ ipart += 1.0;
+ if (ipart >= 10.0)
+ {
+ ++exp;
+ ipart /= 10.0;
+ fpart /= 10.0;
+ }
+ }
+ double ffpart = fpart;
+ double ifpart;
+ for (int i = 0; i < prec; ++i)
+ {
+ ffpart = modf(ffpart * 10.0, &ifpart);
+ *fw++ = '0' + int(ifpart);
+ ++fwidth;
+ }
+ if (cvt == 'g') // inhibit trailing zeroes if g-fmt
+ {
+ for (char* p = fw - 1; p >= fwork && *p == '0'; --p)
+ {
+ *p = 0;
+ --fwidth;
+ }
+ }
+ }
+
+
+ // convert exponent
+
+ char eneg = exp < 0;
+ if (eneg) exp = - exp;
+
+ while (exp > 0)
+ {
+ *--ew = '0' + (exp % 10);
+ exp /= 10;
+ ++ewidth;
+ }
+
+ while (ewidth < 2) // ensure at least 2 zeroes
+ {
+ *--ew = '0';
+ ++ewidth;
+ }
+
+ *--ew = eneg ? '-' : '+';
+ *--ew = 'e';
+
+ ewidth += 2;
+
+ // convert the one-digit integer part
+ *--iw = '0' + int(ipart);
+ ++iwidth;
+
+ }
+
+ // arrange everything in returned string
+
+ int showdot = cvt != 'g' || fwidth > 0;
+
+ int fmtwidth = is_neg + iwidth + showdot + fwidth + ewidth;
+
+ int pad = width - fmtwidth;
+ if (pad < 0) pad = 0;
+
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(fmtwidth + pad + 1);
+ char* fmt = fmtbase;
+
+ for (int i = 0; i < pad; ++i) *fmt++ = ' ';
+
+ if (is_neg) *fmt++ = '-';
+
+ for (i = 0; i < iwidth; ++i) *fmt++ = *iw++;
+
+ if (showdot)
+ {
+ *fmt++ = '.';
+ fw = fwork;
+ for (i = 0; i < fwidth; ++i) *fmt++ = *fw++;
+ }
+
+ for (i = 0; i < ewidth; ++i) *fmt++ = *ew++;
+
+ *fmt = 0;
+
+ return fmtbase;
+}
+#endif
diff --git a/gnu/lib/libg++/g++-include/error.cc b/gnu/lib/libg++/g++-include/error.cc
new file mode 100644
index 00000000000..fc14959c4da
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/error.cc
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+extern "C" _VOLATILE_VOID abort();
+
+_VOLATILE_VOID default_one_arg_error_handler(const char* msg)
+{
+ fputs("Error: ", stderr);
+ fputs(msg, stderr);
+ fputs("\n", stderr);
+ abort();
+}
+
+
+_VOLATILE_VOID default_two_arg_error_handler(const char* kind, const char* msg)
+{
+ fputs(kind, stderr);
+ fputs(" Error: ", stderr);
+ fputs(msg, stderr);
+ fputs("\n", stderr);
+ abort();
+}
+
+two_arg_error_handler_t lib_error_handler = default_two_arg_error_handler;
+
+two_arg_error_handler_t set_lib_error_handler(two_arg_error_handler_t f)
+{
+ two_arg_error_handler_t old = lib_error_handler;
+ lib_error_handler = f;
+ return old;
+}
+
diff --git a/gnu/lib/libg++/g++-include/fmtq.cc b/gnu/lib/libg++/g++-include/fmtq.cc
new file mode 100644
index 00000000000..7a9dd7b4f3c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/fmtq.cc
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <AllocRing.h>
+
+// AllocRings are used for output operations
+// We guaranteee that the last _libgxx_maxfmt formats
+// will be intact
+
+static const int _libgxx_maxfmt = 20;
+AllocRing _libgxx_fmtq(_libgxx_maxfmt);
diff --git a/gnu/lib/libg++/g++-include/gcd.cc b/gnu/lib/libg++/g++-include/gcd.cc
new file mode 100644
index 00000000000..76ff0ef1b8e
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gcd.cc
@@ -0,0 +1,52 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+
+/*
+ common functions on built-in types
+*/
+
+long gcd(long x, long y) // euclid's algorithm
+{
+ long a = abs(x);
+ long b = abs(y);
+
+ long tmp;
+
+ if (b > a)
+ {
+ tmp = a; a = b; b = tmp;
+ }
+ for(;;)
+ {
+ if (b == 0)
+ return a;
+ else if (b == 1)
+ return b;
+ else
+ {
+ tmp = b;
+ b = a % b;
+ a = tmp;
+ }
+ }
+}
diff --git a/gnu/lib/libg++/g++-include/gen/AVLMap.ccP b/gnu/lib/libg++/g++-include/gen/AVLMap.ccP
new file mode 100644
index 00000000000..12b52f5e92a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/AVLMap.ccP
@@ -0,0 +1,608 @@
+// 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 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 <stream.h>
+#include <assert.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++/g++-include/gen/AVLMap.hP b/gnu/lib/libg++/g++-include/gen/AVLMap.hP
new file mode 100644
index 00000000000..cbf0ffbe7bc
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/AVLMap.hP
@@ -0,0 +1,157 @@
+// 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 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.
+*/
+
+
+#ifndef _<T><C>AVLMap_h
+#ifdef __GNUG__
+#pragma once
+#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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>AVLNode::<T><C>AVLNode(<T&> h, <C&> c,
+ <T><C>AVLNode* l, <T><C>AVLNode* r)
+ :item(h), cont(c), lt(l), rt(r), stat(0) {}
+
+inline <T><C>AVLNode::~<T><C>AVLNode() {}
+
+#endif
+
+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);
+ ~<T><C>AVLMap();
+
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>AVLMap::~<T><C>AVLMap()
+{
+ _kill(root);
+}
+
+inline <T><C>AVLMap::<T><C>AVLMap(<C&> dflt) :(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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/AVLSet.ccP b/gnu/lib/libg++/g++-include/gen/AVLSet.ccP
new file mode 100644
index 00000000000..ee433257c09
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/AVLSet.ccP
@@ -0,0 +1,885 @@
+// 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 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 <stream.h>
+#include <assert.h>
+#include "<T>.AVLSet.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++/g++-include/gen/AVLSet.hP b/gnu/lib/libg++/g++-include/gen/AVLSet.hP
new file mode 100644
index 00000000000..b9adfb4e748
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/AVLSet.hP
@@ -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)
+
+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.
+*/
+
+
+#ifndef _<T>AVL_h
+#ifdef __GNUG__
+#pragma once
+#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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>AVLNode::<T>AVLNode(<T&> h, <T>AVLNode* l, <T>AVLNode* r)
+:item(h), lt(l), rt(r), stat(0) {}
+
+inline <T>AVLNode::~<T>AVLNode() {}
+
+#endif
+
+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);
+ ~<T>AVLSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/AVec.ccP b/gnu/lib/libg++/g++-include/gen/AVec.ccP
new file mode 100644
index 00000000000..e2f40345582
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/AVec.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 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 <stream.h>
+#include "<T>.AVec.h"
+
+/*
+ The following brought to you by the department of redundancy department
+*/
+
+<T>AVec& <T>AVec::operator = (<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 > 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++/g++-include/gen/AVec.hP b/gnu/lib/libg++/g++-include/gen/AVec.hP
new file mode 100644
index 00000000000..9c57d204f7d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/AVec.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 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.
+*/
+
+
+#ifndef _<T>AVec_h
+#ifdef __GNUG__
+#pragma once
+#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();
+ <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 = (<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);
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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) :(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 void <T>AVec::check_len(int l)
+{
+ if (l != len)
+ error("nonconformant vectors.");
+}
+
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/BSTSet.ccP b/gnu/lib/libg++/g++-include/gen/BSTSet.ccP
new file mode 100644
index 00000000000..5edb1d62eb4
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/BSTSet.ccP
@@ -0,0 +1,383 @@
+// 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 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 <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;
+ int comp;
+ for (;;)
+ {
+ 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;
+ comp = <T>CMP(t->item, item);
+ if (comp == 0)
+ return Pix(t);
+ else if (comp > 0)
+ t = t->lt;
+ else
+ t = t->rt;
+ }
+}
+
+
+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++/g++-include/gen/BSTSet.hP b/gnu/lib/libg++/g++-include/gen/BSTSet.hP
new file mode 100644
index 00000000000..4ac9f4099dc
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/BSTSet.hP
@@ -0,0 +1,166 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>BSTSet_h
+#ifdef __GNUG__
+#pragma once
+#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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>BSTNode::<T>BSTNode(<T&> h, <T>BSTNode* l, <T>BSTNode* r,
+ <T>BSTNode* p)
+:item(h), lt(l), rt(r), par(p) {}
+
+inline <T>BSTNode::~<T>BSTNode() {}
+
+#endif
+
+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);
+ ~<T>BSTSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Bag.ccP b/gnu/lib/libg++/g++-include/gen/Bag.ccP
new file mode 100644
index 00000000000..694c9b7c074
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Bag.ccP
@@ -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 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 <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++/g++-include/gen/Bag.hP b/gnu/lib/libg++/g++-include/gen/Bag.hP
new file mode 100644
index 00000000000..af87a8ba534
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Bag.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 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.
+*/
+
+
+#ifndef _<T>Bag_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>Bag_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T>Bag
+{
+protected:
+ int count;
+
+public:
+ 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
+ virtual void remove(<T&> item); // delete all occurrences
+ virtual void clear(); // delete all items
+
+ 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
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/CHBag.ccP b/gnu/lib/libg++/g++-include/gen/CHBag.ccP
new file mode 100644
index 00000000000..b7f97ec938c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/CHBag.ccP
@@ -0,0 +1,214 @@
+// 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 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 "<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)
+ {
+ for (<T>CHNode* 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++/g++-include/gen/CHBag.hP b/gnu/lib/libg++/g++-include/gen/CHBag.hP
new file mode 100644
index 00000000000..5254f8ff962
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/CHBag.hP
@@ -0,0 +1,110 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>CHBag_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>CHBag_h 1
+
+#include "<T>.Bag.h"
+
+
+#ifndef _<T>CHNode_h
+#define _<T>CHNode_h 1
+
+struct <T>CHNode
+{
+ <T>CHNode* tl;
+ <T> hd;
+ <T>CHNode();
+ <T>CHNode(<T&> h, <T>CHNode* t = 0);
+ ~<T>CHNode();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>CHNode::<T>CHNode() {}
+
+inline <T>CHNode::<T>CHNode(<T&> h, <T>CHNode* t) :hd(h), tl(t) {}
+
+inline <T>CHNode::~<T>CHNode() {}
+
+#endif
+
+typedef <T>CHNode* <T>CHNodePtr;
+
+#endif
+
+
+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);
+ ~<T>CHBag();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/CHMap.ccP b/gnu/lib/libg++/g++-include/gen/CHMap.ccP
new file mode 100644
index 00000000000..edb942f2963
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/CHMap.ccP
@@ -0,0 +1,171 @@
+// 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 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 "<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;
+
+ for (<T><C>CHNode* 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)
+ {
+ for (<T><C>CHNode* 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++/g++-include/gen/CHMap.hP b/gnu/lib/libg++/g++-include/gen/CHMap.hP
new file mode 100644
index 00000000000..03479718be3
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/CHMap.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 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.
+*/
+
+
+#ifndef _<T><C>CHMap_h
+#ifdef __GNUG__
+#pragma once
+#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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>CHNode::<T><C>CHNode() {}
+
+inline <T><C>CHNode::<T><C>CHNode(<T&> h, <C&> c, <T><C>CHNode* t)
+ : hd(h), cont(c), tl(t) {}
+
+inline <T><C>CHNode::~<T><C>CHNode() {}
+
+
+#endif
+
+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);
+ ~<T><C>CHMap();
+
+ <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();
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/CHSet.ccP b/gnu/lib/libg++/g++-include/gen/CHSet.ccP
new file mode 100644
index 00000000000..07c57d34620
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/CHSet.ccP
@@ -0,0 +1,276 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of 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 "<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;
+
+ for (<T>CHNode* 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 (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)
+ {
+ for (<T>CHNode* 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++/g++-include/gen/CHSet.hP b/gnu/lib/libg++/g++-include/gen/CHSet.hP
new file mode 100644
index 00000000000..51cad80a95c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/CHSet.hP
@@ -0,0 +1,121 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>CHSet_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>CHSet_h 1
+
+#include "<T>.Set.h"
+
+
+#ifndef _<T>CHNode_h
+#define _<T>CHNode_h 1
+
+struct <T>CHNode
+{
+ <T>CHNode* tl;
+ <T> hd;
+ <T>CHNode();
+ <T>CHNode(<T&> h, <T>CHNode* t = 0);
+ ~<T>CHNode();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>CHNode::<T>CHNode() {}
+
+inline <T>CHNode::<T>CHNode(<T&> h, <T>CHNode* t) : hd(h), tl(t) {}
+
+inline <T>CHNode::~<T>CHNode() {}
+
+#endif
+
+typedef <T>CHNode* <T>CHNodePtr;
+
+#endif
+
+
+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);
+ ~<T>CHSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/DLDeque.ccP b/gnu/lib/libg++/g++-include/gen/DLDeque.ccP
new file mode 100644
index 00000000000..d5a0db7f910
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/DLDeque.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.DLDeque.h"
diff --git a/gnu/lib/libg++/g++-include/gen/DLDeque.hP b/gnu/lib/libg++/g++-include/gen/DLDeque.hP
new file mode 100644
index 00000000000..5ef7c4cdfc7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/DLDeque.hP
@@ -0,0 +1,138 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>DLDeque_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>DLDeque();
+
+ void operator = (const <T>DLDeque&);
+
+ void push(<T&> item); // insert at front
+ void enq(<T&> item); // insert at rear
+
+ <T>& front();
+ <T>& rear();
+
+ <T> deq();
+ void del_front();
+ void del_rear();
+
+ void clear();
+ int empty();
+ int full();
+ int length();
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/DLList.ccP b/gnu/lib/libg++/g++-include/gen/DLList.ccP
new file mode 100644
index 00000000000..c9965a66179
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/DLList.ccP
@@ -0,0 +1,317 @@
+// 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 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 <values.h>
+#include <stream.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(<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 = (<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;
+}
+
+<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 = MAXLONG; // 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++/g++-include/gen/DLList.hP b/gnu/lib/libg++/g++-include/gen/DLList.hP
new file mode 100644
index 00000000000..511c7b55235
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/DLList.hP
@@ -0,0 +1,170 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>DLList_h
+#ifdef __GNUG__
+#pragma once
+#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(<T&> h,
+ <T>DLListNode* p = 0,
+ <T>DLListNode* n = 0);
+ ~<T>DLListNode();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>DLListNode::<T>DLListNode() {}
+
+inline <T>DLListNode::<T>DLListNode(<T&> h, <T>DLListNode* p,
+ <T>DLListNode* n)
+ :hd(h), bk(p), fd(n) {}
+
+inline <T>DLListNode::~<T>DLListNode() {}
+
+#endif
+
+typedef <T>DLListNode* <T>DLListNodePtr;
+
+#endif
+
+class <T>DLList
+{
+ friend class <T>DLListTrav;
+
+ <T>DLListNode* h;
+
+public:
+ <T>DLList();
+ <T>DLList(<T>DLList& a);
+ ~<T>DLList();
+
+ <T>DLList& operator = (<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 error(const char* msg);
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Deque.ccP b/gnu/lib/libg++/g++-include/gen/Deque.ccP
new file mode 100644
index 00000000000..79a9b72c875
--- /dev/null
+++ b/gnu/lib/libg++/g++-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++/g++-include/gen/Deque.hP b/gnu/lib/libg++/g++-include/gen/Deque.hP
new file mode 100644
index 00000000000..a82607bec89
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Deque.hP
@@ -0,0 +1,67 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>Deque_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>Deque_h
+
+#include <builtin.h>
+
+#include "<T>.defs.h"
+
+class <T>Deque
+{
+public:
+ <T>Deque();
+ ~<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*);
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+inline <T>Deque::<T>Deque() {}
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/FPQueue.ccP b/gnu/lib/libg++/g++-include/gen/FPQueue.ccP
new file mode 100644
index 00000000000..a358cacb60e
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/FPQueue.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.FPQueue.h"
diff --git a/gnu/lib/libg++/g++-include/gen/FPQueue.hP b/gnu/lib/libg++/g++-include/gen/FPQueue.hP
new file mode 100644
index 00000000000..9fcb81b58a3
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/FPQueue.hP
@@ -0,0 +1,121 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>FPQueue_h
+#ifdef __GNUG__
+#pragma once
+#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_<T>PLEX_CHUNK_SIZE);
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/FPStack.ccP b/gnu/lib/libg++/g++-include/gen/FPStack.ccP
new file mode 100644
index 00000000000..954991193b7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/FPStack.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.FPStack.h"
diff --git a/gnu/lib/libg++/g++-include/gen/FPStack.hP b/gnu/lib/libg++/g++-include/gen/FPStack.hP
new file mode 100644
index 00000000000..1ec4673e484
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/FPStack.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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+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.
+*/
+
+
+#ifndef _<T>FPStack_h
+#ifdef __GNUG__
+#pragma once
+#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_<T>PLEX_CHUNK_SIZE);
+ <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();
+
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/FPlex.ccP b/gnu/lib/libg++/g++-include/gen/FPlex.ccP
new file mode 100644
index 00000000000..235d2908756
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/FPlex.ccP
@@ -0,0 +1,182 @@
+// 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 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 "<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::append (const <T>FPlex& a)
+{
+ for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
+}
+
+void <T>FPlex::prepend (const <T>FPlex& a)
+{
+ for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(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++/g++-include/gen/FPlex.hP b/gnu/lib/libg++/g++-include/gen/FPlex.hP
new file mode 100644
index 00000000000..2fda48d6226
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/FPlex.hP
@@ -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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+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.
+*/
+
+#ifndef _<T>FPlex_h
+#ifdef __GNUG__
+#pragma once
+#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&)
+
+ ~<T>FPlex();
+
+ void operator= (const <T>FPlex&);
+
+// virtuals
+
+ <T>& high_element ();
+ <T>& low_element ();
+
+ const <T>& high_element () const;
+ const <T>& low_element () const;
+
+ Pix first() const;
+ Pix last() const;
+ void prev(Pix& ptr) const;
+ void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ <T>& operator () (Pix p);
+ const <T>& operator () (Pix p) const;
+
+ int low() const;
+ int high() const;
+ int valid(int idx) const;
+ void prev(int& idx) const;
+ void next(int& x) const;
+ <T>& operator [] (int index);
+ const <T>& operator [] (int index) const;
+
+ int Pix_to_index(Pix p) const;
+ Pix index_to_Pix(int idx) const;
+
+ int can_add_high() const;
+ int can_add_low() const;
+ 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();
+ void append(const <T>FPlex& a);
+ void prepend(const <T>FPlex& a);
+
+ int OK () const;
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/List.ccP b/gnu/lib/libg++/g++-include/gen/List.ccP
new file mode 100644
index 00000000000..75c09a92f44
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/List.ccP
@@ -0,0 +1,959 @@
+// 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 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 <builtin.h>
+#include "<T>.List.h"
+
+<T>ListNode Nil<T>ListNode;
+
+class init_Nil<T>ListNode
+{
+public:
+ inline 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 = (<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)
+{
+ for (<T>ListNode* 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)
+{
+ for (<T>ListNode* p = P; n-- > 0; p = p->tl);
+ return (p->hd);
+}
+
+int operator == (<T>List& x, <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 (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 (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 (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 (p->hd == targ)
+ return 1;
+ else
+ p = p->tl;
+ }
+}
+
+<T>List <T>List::find(<T&> targ)
+{
+ for (<T>ListNode* p = P; p != &Nil<T>ListNode && !(p->hd == targ); p=p->tl);
+ reference(p);
+ return <T>List(p);
+}
+
+Pix <T>List::seek(<T&> targ)
+{
+ <T>ListNode* p = P;
+ for (;;)
+ {
+ if (p == &Nil<T>ListNode)
+ return 0;
+ else if (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 (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 || !(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 (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 || !(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;
+
+ for (;;)
+ {
+ if (h == &Nil<T>ListNode)
+ {
+ P = h;
+ return;
+ }
+ else if (h->hd == targ)
+ {
+ <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 (p->hd == targ)
+ {
+ <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::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(<T>List& x)
+{
+ <T>ListNode* a = x.P;
+ if (a == &Nil<T>ListNode)
+ return <T>List(a);
+ 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 (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 (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 (!(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 (!(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++/g++-include/gen/List.hP b/gnu/lib/libg++/g++-include/gen/List.hP
new file mode 100644
index 00000000000..cade890d04b
--- /dev/null
+++ b/gnu/lib/libg++/g++-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 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.
+*/
+
+
+#ifndef _<T>List_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>List_h 1
+
+#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
+
+#include <Pix.h>
+
+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, <T>List& tl);
+ <T>List(<T>List& a);
+ <T>List(Pix p);
+ ~<T>List();
+
+ <T>List& operator = (<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(<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);
+ 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 == (<T>List& a, <T>List& b);
+ friend int operator != (<T>List& a, <T>List& b);
+
+ Pix first();
+ void next(Pix& p);
+ Pix seek(<T&> item);
+ <T>& operator () (Pix p);
+ int owns(Pix p);
+
+ void error(const char*);
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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(<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, <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 != (<T>List& x, <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 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/MPlex.ccP b/gnu/lib/libg++/g++-include/gen/MPlex.ccP
new file mode 100644
index 00000000000..2008d8555a5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/MPlex.ccP
@@ -0,0 +1,850 @@
+// 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 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 "<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]);
+ bzero((void*)map, 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;
+ bzero((void*)map, ((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;
+ bzero((void*)map, ((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] == ~0L) ++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);
+
+ for(<T>MChunk* 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();
+
+ for(<T>MChunk* 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;
+
+ for(<T>MChunk* 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++/g++-include/gen/MPlex.hP b/gnu/lib/libg++/g++-include/gen/MPlex.hP
new file mode 100644
index 00000000000..83e28637435
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/MPlex.hP
@@ -0,0 +1,422 @@
+// 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 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.
+*/
+
+#ifndef _<T>MPlex_h
+#ifdef __GNUG__
+#pragma once
+#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
+
+ void mark(int); // bitmap operations
+ void free(int);
+ 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);
+
+ ~<T>MChunk();
+
+// virtuals
+
+ int first_index() const;
+ int last_index() const;
+ int succ(int idx) const;
+ int pred(int idx) const;
+ <T>* first_pointer() const;
+ <T>* last_pointer() const;
+ <T>* succ(<T>*) const;
+ <T>* pred(<T>*) const;
+ int empty() const;
+ int full() const;
+ int valid_index(int i) const;
+ int valid_pointer(const <T>* p) const;
+ <T>* grow_high ();
+ <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
+
+ <T>& high_element ();
+ <T>& low_element ();
+ const <T>& high_element () const;
+ const <T>& low_element () const;
+
+ Pix first() const;
+ Pix last() const ;
+ void prev(Pix& ptr) const;
+ void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ <T>& operator () (Pix p);
+ const <T>& operator () (Pix p) const;
+
+ int low() const;
+ int high() const;
+ int valid(int idx) const;
+ void prev(int& idx) const;
+ void next(int& x) const;
+ <T>& operator [] (int index);
+ const <T>& operator [] (int index) const;
+
+ int Pix_to_index(Pix p) const;
+ Pix index_to_Pix(int idx) const;
+
+ int can_add_high() const;
+ int can_add_low() const;
+ 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
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Map.ccP b/gnu/lib/libg++/g++-include/gen/Map.ccP
new file mode 100644
index 00000000000..4bf254160f0
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Map.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 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 <builtin.h>
+#include "<T>.<C>.Map.h"
+
+
+Pix <T><C>Map::seek(<T&> item)
+{
+ for (Pix 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++/g++-include/gen/Map.hP b/gnu/lib/libg++/g++-include/gen/Map.hP
new file mode 100644
index 00000000000..301a4ab8094
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Map.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 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.
+*/
+
+
+#ifndef _<T><C>Map_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ virtual ~<T><C>Map();
+
+ int length(); // current number of items
+ int empty();
+
+ 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
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>Map::~<T><C>Map() {}
+
+inline int <T><C>Map::length()
+{
+ return count;
+}
+
+inline int <T><C>Map::empty()
+{
+ 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/OSLBag.ccP b/gnu/lib/libg++/g++-include/gen/OSLBag.ccP
new file mode 100644
index 00000000000..79c95cbe515
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OSLBag.ccP
@@ -0,0 +1,201 @@
+// 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 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 "<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++/g++-include/gen/OSLBag.hP b/gnu/lib/libg++/g++-include/gen/OSLBag.hP
new file mode 100644
index 00000000000..36d74bcb9ee
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OSLBag.hP
@@ -0,0 +1,100 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>OSLBag_h
+#ifdef __GNUG__
+#pragma once
+#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);
+
+ int contains(<T&> item);
+ int nof(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/OSLSet.ccP b/gnu/lib/libg++/g++-include/gen/OSLSet.ccP
new file mode 100644
index 00000000000..2ab19445a6a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OSLSet.ccP
@@ -0,0 +1,326 @@
+// 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 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 "<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++/g++-include/gen/OSLSet.hP b/gnu/lib/libg++/g++-include/gen/OSLSet.hP
new file mode 100644
index 00000000000..1e94c09efc8
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OSLSet.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 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.
+*/
+
+
+#ifndef _<T>OSLSet_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ 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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/OXPBag.ccP b/gnu/lib/libg++/g++-include/gen/OXPBag.ccP
new file mode 100644
index 00000000000..2a396441c01
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OXPBag.ccP
@@ -0,0 +1,226 @@
+// 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 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 "<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++/g++-include/gen/OXPBag.hP b/gnu/lib/libg++/g++-include/gen/OXPBag.hP
new file mode 100644
index 00000000000..5542a273dc3
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OXPBag.hP
@@ -0,0 +1,76 @@
+#ifndef _<T>OXPBag_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/OXPSet.ccP b/gnu/lib/libg++/g++-include/gen/OXPSet.ccP
new file mode 100644
index 00000000000..f7a99f8a86f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OXPSet.ccP
@@ -0,0 +1,285 @@
+// 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 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 "<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++/g++-include/gen/OXPSet.hP b/gnu/lib/libg++/g++-include/gen/OXPSet.hP
new file mode 100644
index 00000000000..fb1cb3c4fa2
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/OXPSet.hP
@@ -0,0 +1,110 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>OXPSet_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ 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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/PHPQ.ccP b/gnu/lib/libg++/g++-include/gen/PHPQ.ccP
new file mode 100644
index 00000000000..cc688732c35
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/PHPQ.ccP
@@ -0,0 +1,342 @@
+// 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 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 <values.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 [size] storage;
+ storage = newstor;
+ for (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 = check_sibling_list(root, 0);
+ v &= n == count;
+ int ct = MAXLONG;
+ 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, int cnt)
+{
+ if (t != 0)
+ {
+ int s = t;
+ long ct = MAXLONG; // Lots of chances to find self!
+ do
+ {
+ if (storage[s].valid) cnt++;
+ cnt += check_sibling_list(storage[s].children, cnt);
+ s = storage[s].sibling;
+ } while (ct-- > 0 && s != t && s != 0);
+ if (ct <= 0) return -1;
+ }
+ return cnt;
+}
+
+
diff --git a/gnu/lib/libg++/g++-include/gen/PHPQ.hP b/gnu/lib/libg++/g++-include/gen/PHPQ.hP
new file mode 100644
index 00000000000..acc6ebb2987
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/PHPQ.hP
@@ -0,0 +1,118 @@
+// 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 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.
+*/
+
+#ifndef <T>PHPQ_h
+#ifdef __GNUG__
+#pragma once
+#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, int);
+
+public:
+
+ <T>PHPQ(int sz = DEFAULT_INITIAL_CAPACITY);
+ <T>PHPQ(<T>PHPQ&);
+ ~<T>PHPQ();
+
+ Pix enq(<T&> item);
+ <T> deq();
+
+ <T>& front();
+ void del_front();
+
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ void del(Pix i);
+ Pix seek(<T&> item);
+
+ int OK(); // rep invariant
+};
+
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>PHPQ::~<T>PHPQ()
+{
+ delete [size] 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/PQ.ccP b/gnu/lib/libg++/g++-include/gen/PQ.ccP
new file mode 100644
index 00000000000..7aeddcbd2e9
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/PQ.ccP
@@ -0,0 +1,67 @@
+// 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 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 <builtin.h>
+#include "<T>.PQ.h"
+
+
+
+<T> <T>PQ::deq()
+{
+ <T> x = front();
+ del_front();
+ return x;
+}
+
+Pix <T>PQ::seek(<T&> item)
+{
+ for (Pix 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++/g++-include/gen/PQ.hP b/gnu/lib/libg++/g++-include/gen/PQ.hP
new file mode 100644
index 00000000000..eb7b22cdf70
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/PQ.hP
@@ -0,0 +1,80 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>PQ_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>PQ_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T>PQ
+{
+protected:
+
+ int count;
+
+public:
+ 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
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline int <T>PQ::length()
+{
+ return count;
+}
+
+inline int <T>PQ::empty()
+{
+ return count == 0;
+}
+
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Plex.ccP b/gnu/lib/libg++/g++-include/gen/Plex.ccP
new file mode 100644
index 00000000000..9d475612de1
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Plex.ccP
@@ -0,0 +1,227 @@
+// 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 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 <stream.h>
+#include "<T>.Plex.h"
+
+// IChunk support
+
+volatile void <T>IChunk::error(const char* msg) const
+{
+ (*lib_error_handler)("<T>IChunk", msg);
+}
+
+volatile void <T>IChunk::index_error() const
+{
+ error("attempt to use invalid index");
+}
+
+volatile void <T>IChunk::empty_error() const
+{
+ error("invalid use of empty chunk");
+}
+
+volatile 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
+
+
+volatile void <T>Plex::error(const char* msg) const
+{
+ (*lib_error_handler)("Plex", msg);
+}
+
+volatile void <T>Plex::index_error() const
+{
+ error("attempt to access invalid index");
+}
+
+volatile void <T>Plex::empty_error() const
+{
+ error("attempted operation on empty plex");
+}
+
+volatile 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();
+ int sz = x->size();
+ <T>* data = (<T>*)(x->invalidate());
+ delete [sz] 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++/g++-include/gen/Plex.hP b/gnu/lib/libg++/g++-include/gen/Plex.hP
new file mode 100644
index 00000000000..38a1ef66673
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Plex.hP
@@ -0,0 +1,503 @@
+// 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 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.
+*/
+
+#ifndef _<T>Plex_h
+#ifdef __GNUG__
+#pragma once
+#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
+
+ virtual int empty() const ;
+ 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;
+ virtual int first_index() const; // lowest valid index or fence if none
+ 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
+ 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;
+ 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
+
+ virtual int succ(int idx) const; // next valid index or fence if none
+ virtual int pred(int idx) const; // previous index or low - 1 if none
+
+ virtual <T>* first_pointer() const; // pointer to first valid pos or 0
+ virtual <T>* last_pointer() const; // pointer to first valid pos or 0
+ virtual <T>* succ(<T>* p) const; // next pointer or 0
+ virtual <T>* pred(<T>* p) const; // previous pointer or 0
+
+// modification
+
+ virtual <T>* grow_high (); // return spot to add an element
+ virtual <T>* grow_low ();
+
+ virtual void shrink_high (); // logically delete top index
+ 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
+
+ volatile void error(const char*) const;
+ volatile void empty_error() const;
+ volatile void full_error() const;
+ volatile 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
+
+ volatile void error(const char* msg) const;
+ volatile void index_error() const;
+ volatile void empty_error() const;
+ volatile void full_error() const;
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+// <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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Queue.ccP b/gnu/lib/libg++/g++-include/gen/Queue.ccP
new file mode 100644
index 00000000000..fb48d952ff7
--- /dev/null
+++ b/gnu/lib/libg++/g++-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++/g++-include/gen/Queue.hP b/gnu/lib/libg++/g++-include/gen/Queue.hP
new file mode 100644
index 00000000000..3ff62c865cc
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Queue.hP
@@ -0,0 +1,62 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>Queue_h
+#ifdef __GNUG__
+#pragma once
+#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;
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>Queue::<T>Queue() {}
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP b/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP
new file mode 100644
index 00000000000..815342330a5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/RAVLMap.ccP
@@ -0,0 +1,684 @@
+// 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 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 <stream.h>
+#include <assert.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++/g++-include/gen/RAVLMap.hP b/gnu/lib/libg++/g++-include/gen/RAVLMap.hP
new file mode 100644
index 00000000000..cf216e5ba02
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/RAVLMap.hP
@@ -0,0 +1,162 @@
+// 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 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.
+*/
+
+
+#ifndef _<T><C>RAVLMap_h
+#ifdef __GNUG__
+#pragma once
+#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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>RAVLNode::<T><C>RAVLNode(<T&> h, <C&> c,
+ <T><C>RAVLNode* l, <T><C>RAVLNode* r, int k)
+ :item(h), cont(c), lt(l), rt(r), rank(k), stat(0) {}
+
+inline <T><C>RAVLNode::~<T><C>RAVLNode() {}
+
+#endif
+
+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);
+ ~<T><C>RAVLMap();
+
+ <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);
+
+ Pix ranktoPix(int i);
+ int rankof(<T&> key);
+
+ void clear();
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>RAVLMap::~<T><C>RAVLMap()
+{
+ _kill(root);
+}
+
+inline <T><C>RAVLMap::<T><C>RAVLMap(<C&> dflt) :(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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/RPlex.ccP b/gnu/lib/libg++/g++-include/gen/RPlex.ccP
new file mode 100644
index 00000000000..a91bbeb80ec
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/RPlex.ccP
@@ -0,0 +1,492 @@
+// 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 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 "<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];
+ bcopy(chunks, newch, 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];
+ bcopy(chunks, &(newch[lch]), 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::append(const <T>RPlex& a)
+{
+ for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
+}
+
+void <T>RPlex::prepend (const <T>RPlex& a)
+{
+ for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]);
+}
+
+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++/g++-include/gen/RPlex.hP b/gnu/lib/libg++/g++-include/gen/RPlex.hP
new file mode 100644
index 00000000000..7a21f5bb649
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/RPlex.hP
@@ -0,0 +1,268 @@
+// 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 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.
+*/
+
+#ifndef _<T>RPlex_h
+#ifdef __GNUG__
+#pragma once
+#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;
+
+ 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&);
+
+ ~<T>RPlex();
+
+ void operator= (const <T>RPlex&);
+
+// virtuals
+
+ <T>& high_element ();
+ <T>& low_element ();
+
+ const <T>& high_element () const;
+ const <T>& low_element () const;
+
+ Pix first() const;
+ Pix last() const;
+ void prev(Pix& ptr) const;
+ void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ <T>& operator () (Pix p);
+ const <T>& operator () (Pix p) const;
+
+ int low() const;
+ int high() const;
+ int valid(int idx) const;
+ void prev(int& idx) const;
+ void next(int& x) const;
+ <T>& operator [] (int index);
+ const <T>& operator [] (int index) const;
+
+ int Pix_to_index(Pix p) const;
+ Pix index_to_Pix(int idx) const;
+
+ int can_add_high() const;
+ int can_add_low() const;
+ 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();
+ void append(const <T>RPlex& a);
+ void prepend(const <T>RPlex& a);
+
+ int reset_low(int newlow);
+
+ int OK () const;
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SLBag.ccP b/gnu/lib/libg++/g++-include/gen/SLBag.ccP
new file mode 100644
index 00000000000..172a652da31
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLBag.ccP
@@ -0,0 +1,110 @@
+// 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 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 "<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++/g++-include/gen/SLBag.hP b/gnu/lib/libg++/g++-include/gen/SLBag.hP
new file mode 100644
index 00000000000..d039241668d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLBag.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 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.
+*/
+
+
+#ifndef _<T>SLBag_h
+#ifdef __GNUG__
+#pragma once
+#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&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int contains(<T&> item);
+ int nof(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SLList.ccP b/gnu/lib/libg++/g++-include/gen/SLList.ccP
new file mode 100644
index 00000000000..57920c3190f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLList.ccP
@@ -0,0 +1,296 @@
+// 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 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 <values.h>
+#include <stream.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(<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 = (<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 = MAXLONG; // 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++/g++-include/gen/SLList.hP b/gnu/lib/libg++/g++-include/gen/SLList.hP
new file mode 100644
index 00000000000..1886b68f1a1
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLList.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 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.
+*/
+
+
+#ifndef _<T>SLList_h
+#ifdef __GNUG__
+#pragma once
+#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(<T&> h, <T>SLListNode* t = 0);
+ ~<T>SLListNode();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>SLListNode::<T>SLListNode() {}
+
+inline <T>SLListNode::<T>SLListNode(<T&> h, <T>SLListNode* t) :hd(h), tl(t) {}
+
+inline <T>SLListNode::~<T>SLListNode() {}
+
+#endif
+
+typedef <T>SLListNode* <T>SLListNodePtr;
+
+#endif
+
+
+class <T>SLList
+{
+protected:
+ <T>SLListNode* last;
+
+public:
+ <T>SLList();
+ <T>SLList(<T>SLList& a);
+ ~<T>SLList();
+
+ <T>SLList& operator = (<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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SLQueue.ccP b/gnu/lib/libg++/g++-include/gen/SLQueue.ccP
new file mode 100644
index 00000000000..8a5935b7757
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLQueue.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SLQueue.h"
diff --git a/gnu/lib/libg++/g++-include/gen/SLQueue.hP b/gnu/lib/libg++/g++-include/gen/SLQueue.hP
new file mode 100644
index 00000000000..5e75031d3da
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLQueue.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 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.
+*/
+
+#ifndef _<T>SLQueue_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>SLQueue();
+
+ void operator = (const <T>SLQueue&);
+
+ void enq(<T&> item);
+ <T> deq();
+ <T>& front();
+ void del_front();
+
+ void clear();
+ int empty();
+ int full();
+ int length();
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SLSet.ccP b/gnu/lib/libg++/g++-include/gen/SLSet.ccP
new file mode 100644
index 00000000000..5854b2bbbfa
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLSet.ccP
@@ -0,0 +1,81 @@
+// 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 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 "<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)
+{
+ for (Pix 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++/g++-include/gen/SLSet.hP b/gnu/lib/libg++/g++-include/gen/SLSet.hP
new file mode 100644
index 00000000000..bc11a74c042
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLSet.hP
@@ -0,0 +1,97 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>SLSet_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SLStack.ccP b/gnu/lib/libg++/g++-include/gen/SLStack.ccP
new file mode 100644
index 00000000000..3996b41fac5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLStack.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.SLStack.h"
diff --git a/gnu/lib/libg++/g++-include/gen/SLStack.hP b/gnu/lib/libg++/g++-include/gen/SLStack.hP
new file mode 100644
index 00000000000..dced4672063
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SLStack.hP
@@ -0,0 +1,119 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>SLStack_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>SLStack();
+
+ void operator = (const <T>SLStack&);
+
+ void push(<T&> item);
+ <T> pop();
+ <T>& top();
+ void del_top();
+
+ int empty();
+ int full();
+ int length();
+
+ void clear();
+
+ int OK();
+
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Set.ccP b/gnu/lib/libg++/g++-include/gen/Set.ccP
new file mode 100644
index 00000000000..c47260227a7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Set.ccP
@@ -0,0 +1,121 @@
+// 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 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 <builtin.h>
+#include "<T>.Set.h"
+
+
+Pix <T>Set::seek(<T&> item)
+{
+ for (Pix 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++/g++-include/gen/Set.hP b/gnu/lib/libg++/g++-include/gen/Set.hP
new file mode 100644
index 00000000000..b2c08cea002
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Set.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)
+
+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.
+*/
+
+
+#ifndef _<T>Set_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>Set_h 1
+
+#include <Pix.h>
+#include "<T>.defs.h"
+
+class <T>Set
+{
+protected:
+
+ int count;
+
+public:
+ 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
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>Set::~<T>Set() {}
+
+inline int <T>Set::length()
+{
+ return count;
+}
+
+inline int <T>Set::empty()
+{
+ return count == 0;
+}
+
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SplayBag.ccP b/gnu/lib/libg++/g++-include/gen/SplayBag.ccP
new file mode 100644
index 00000000000..1e16a7e45d0
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplayBag.ccP
@@ -0,0 +1,451 @@
+// 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 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 <stream.h>
+#include <assert.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++/g++-include/gen/SplayBag.hP b/gnu/lib/libg++/g++-include/gen/SplayBag.hP
new file mode 100644
index 00000000000..5d3723ba9cf
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplayBag.hP
@@ -0,0 +1,160 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>SplayBag_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>SplayBag_h 1
+
+#include "<T>.Bag.h"
+
+#ifndef _<T>SplayNode
+#define _<T>SplayNode 1
+
+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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>SplayNode::<T>SplayNode(<T&> h, <T>SplayNode* l, <T>SplayNode* r)
+:item(h), lt(l), rt(r), par(0) {}
+
+inline <T>SplayNode::~<T>SplayNode() {}
+
+#endif
+
+typedef <T>SplayNode* <T>SplayNodePtr;
+
+#endif
+
+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);
+ ~<T>SplayBag();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ Pix last();
+ void prev(Pix& i);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SplayMap.ccP b/gnu/lib/libg++/g++-include/gen/SplayMap.ccP
new file mode 100644
index 00000000000..0d86c2dd4ab
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplayMap.ccP
@@ -0,0 +1,407 @@
+// 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 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 <stream.h>
+#include <assert.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++/g++-include/gen/SplayMap.hP b/gnu/lib/libg++/g++-include/gen/SplayMap.hP
new file mode 100644
index 00000000000..39cbe12be5f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplayMap.hP
@@ -0,0 +1,166 @@
+// 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 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.
+*/
+
+
+#ifndef _<T><C>SplayMap_h
+#ifdef __GNUG__
+#pragma once
+#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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>SplayNode::<T><C>SplayNode(<T&> h, <C&> c,
+ <T><C>SplayNode* l,
+ <T><C>SplayNode* r)
+ :item(h), cont(c), lt(l), rt(r), par(0) {}
+
+inline <T><C>SplayNode::~<T><C>SplayNode() {}
+
+#endif
+
+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);
+ ~<T><C>SplayMap();
+
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>SplayMap::~<T><C>SplayMap()
+{
+ _kill(root);
+}
+
+inline <T><C>SplayMap::<T><C>SplayMap(<C&> dflt) :(dflt)
+{
+ root = 0;
+}
+
+inline <T><C>SplayMap::<T><C>SplayMap(<T><C>SplayMap& b) :(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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP b/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP
new file mode 100644
index 00000000000..cfb8ab46c56
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplayPQ.ccP
@@ -0,0 +1,529 @@
+// 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 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 <stream.h>
+#include <assert.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++/g++-include/gen/SplayPQ.hP b/gnu/lib/libg++/g++-include/gen/SplayPQ.hP
new file mode 100644
index 00000000000..8c738256c4b
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplayPQ.hP
@@ -0,0 +1,157 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>SplayPQ_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>SplayPQ_h 1
+
+#include "<T>.PQ.h"
+
+#ifndef _<T>SplayNode
+#define _<T>SplayNode 1
+
+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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>SplayNode::<T>SplayNode(<T&> h, <T>SplayNode* l, <T>SplayNode* r)
+:item(h), lt(l), rt(r), par(0) {}
+
+inline <T>SplayNode::~<T>SplayNode() {}
+
+#endif
+
+typedef <T>SplayNode* <T>SplayNodePtr;
+
+#endif
+
+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);
+ ~<T>SplayPQ();
+
+ Pix enq(<T&> item);
+ <T> deq();
+
+ <T>& front();
+ void del_front();
+
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ Pix last();
+ void next(Pix& i);
+ void prev(Pix& i);
+ <T>& operator () (Pix i);
+ void del(Pix i);
+ Pix seek(<T&> item);
+
+ int OK(); // rep invariant
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/SplaySet.ccP b/gnu/lib/libg++/g++-include/gen/SplaySet.ccP
new file mode 100644
index 00000000000..fc037a0a0a7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplaySet.ccP
@@ -0,0 +1,505 @@
+// 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 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 <stream.h>
+#include <assert.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++/g++-include/gen/SplaySet.hP b/gnu/lib/libg++/g++-include/gen/SplaySet.hP
new file mode 100644
index 00000000000..b499fdc45ef
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/SplaySet.hP
@@ -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)
+
+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.
+*/
+
+
+#ifndef _<T>SplaySet_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>SplaySet_h 1
+
+#include "<T>.Set.h"
+
+#ifndef _<T>SplayNode
+#define _<T>SplayNode 1
+
+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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>SplayNode::<T>SplayNode(<T&> h, <T>SplayNode* l, <T>SplayNode* r)
+:item(h), lt(l), rt(r), par(0) {}
+
+inline <T>SplayNode::~<T>SplayNode() {}
+
+#endif
+
+typedef <T>SplayNode* <T>SplayNodePtr;
+
+#endif
+
+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);
+ ~<T>SplaySet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ Pix seek(<T&> item);
+
+ Pix last();
+ void prev(Pix& i);
+
+ 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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Stack.ccP b/gnu/lib/libg++/g++-include/gen/Stack.ccP
new file mode 100644
index 00000000000..efb6b8edbde
--- /dev/null
+++ b/gnu/lib/libg++/g++-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++/g++-include/gen/Stack.hP b/gnu/lib/libg++/g++-include/gen/Stack.hP
new file mode 100644
index 00000000000..46c4799f45b
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Stack.hP
@@ -0,0 +1,62 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>Stack_h
+#ifdef __GNUG__
+#pragma once
+#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;
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+inline <T>Stack::<T>Stack() {}
+#endif
+
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/VHBag.ccP b/gnu/lib/libg++/g++-include/gen/VHBag.ccP
new file mode 100644
index 00000000000..d56643df9f5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VHBag.ccP
@@ -0,0 +1,269 @@
+// 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 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 "<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 (size <= count + 1)
+ 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 (newsize <= count) 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 (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
+ delete [oldsize] 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++/g++-include/gen/VHBag.hP b/gnu/lib/libg++/g++-include/gen/VHBag.hP
new file mode 100644
index 00000000000..b88673c9f01
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VHBag.hP
@@ -0,0 +1,92 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>VHBag_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>VHBag();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int capacity();
+ void resize(unsigned int newsize = 0);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>VHBag::~<T>VHBag()
+{
+ delete [size] 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/VHMap.ccP b/gnu/lib/libg++/g++-include/gen/VHMap.ccP
new file mode 100644
index 00000000000..b6129446606
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VHMap.ccP
@@ -0,0 +1,215 @@
+// 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 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 "<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 (size <= count + 1)
+ 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 (newsize <= count) 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 (i = 0; i < oldsize; ++i)
+ if (oldstatus[i] == VALIDCELL)
+ (*this)[oldtab[i]] = oldcont[i];
+ delete [oldsize] oldtab;
+ delete [oldsize] 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++/g++-include/gen/VHMap.hP b/gnu/lib/libg++/g++-include/gen/VHMap.hP
new file mode 100644
index 00000000000..b0b1ecc08a8
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VHMap.hP
@@ -0,0 +1,94 @@
+// 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 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.
+*/
+
+
+#ifndef _<T><C>VHMap_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T><C>VHMap();
+
+ <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();
+ void resize(unsigned int newsize = 0);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T><C>VHMap::~<T><C>VHMap()
+{
+ delete [size] tab;
+ delete [size] cont;
+ delete [size] 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/VHSet.ccP b/gnu/lib/libg++/g++-include/gen/VHSet.ccP
new file mode 100644
index 00000000000..f93f1354cc4
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VHSet.ccP
@@ -0,0 +1,268 @@
+// 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 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 "<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 (size <= count + 1)
+ 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 (newsize <= count) 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 (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
+ delete [oldsize] 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 (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++/g++-include/gen/VHSet.hP b/gnu/lib/libg++/g++-include/gen/VHSet.hP
new file mode 100644
index 00000000000..3ec4d5253fb
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VHSet.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 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.
+*/
+
+
+#ifndef _<T>VHSet_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>VHSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <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();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>VHSet::~<T>VHSet()
+{
+ delete [size] 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/VOHSet.ccP b/gnu/lib/libg++/g++-include/gen/VOHSet.ccP
new file mode 100644
index 00000000000..382e1e96fc7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VOHSet.ccP
@@ -0,0 +1,313 @@
+// 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 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 <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]);
+ }
+ int cmp = <T>CMP(x, tab[h]);
+ if (cmp == 0)
+ return Pix(&tab[h]);
+
+ <T> item = x;
+ Pix mypix = 0;
+ unsigned inc = ((((hashval / size) << 1) + 1) & (size - 1));
+
+ for (;;)
+ {
+ if (cmp < 0)
+ {
+ <T> temp = tab[h];
+ tab[h] = item;
+ item = temp;
+ if (mypix == 0) mypix = Pix(&tab[h]);
+ inc = ((((<T>HASH(item) / size) << 1) + 1) & (size - 1));
+ h = ((h + inc) & (size - 1));
+ cmp = <T>CMP(item, tab[h]);
+ }
+ else
+ h = ((h + inc) & (size - 1));
+ if (status[h] != VALIDCELL)
+ {
+ if (status[h] == EMPTYCELL)
+ cnt++;
+ count++;
+ tab[h] = item;
+ status[h] = VALIDCELL;
+ return (mypix == 0)? Pix(&tab[h]) : mypix;
+ }
+ }
+}
+
+
+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 (i = 0; i < oldsize; ++i) if (oldstatus[i] == VALIDCELL) add(oldtab[i]);
+ delete [oldsize] 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 (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++/g++-include/gen/VOHSet.hP b/gnu/lib/libg++/g++-include/gen/VOHSet.hP
new file mode 100644
index 00000000000..6c71288044c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VOHSet.hP
@@ -0,0 +1,97 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>VOHSet_h
+#ifdef __GNUG__
+#pragma once
+#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&);
+ ~<T>VOHSet();
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <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();
+};
+
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>VOHSet::~<T>VOHSet()
+{
+ delete [size] tab;
+ delete status;
+}
+
+
+inline int <T>VOHSet::contains(int key)
+{
+ return seek(key) != 0;
+}
+
+
+inline <T>& <T>VOHSet::operator () (Pix p)
+{
+ if (p == 0) error("null Pix");
+ return *((<T>*)p);
+}
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/VQueue.ccP b/gnu/lib/libg++/g++-include/gen/VQueue.ccP
new file mode 100644
index 00000000000..7ffab10d9ba
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VQueue.ccP
@@ -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)
+
+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 <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 [size] 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 = j;
+ outp = 0;
+ delete [size] 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++/g++-include/gen/VQueue.hP b/gnu/lib/libg++/g++-include/gen/VQueue.hP
new file mode 100644
index 00000000000..66f58d84e02
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VQueue.hP
@@ -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 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.
+*/
+
+
+#ifndef _<T>VQueue_h
+#ifdef __GNUG__
+#pragma once
+#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&);
+ ~<T>VQueue();
+
+ void operator = (<T>VQueue&);
+
+ void enq(<T&> item);
+ <T> deq();
+ <T>& front();
+ void del_front();
+
+ int length();
+ int empty();
+ int full();
+
+ int capacity();
+ void resize(int sz);
+ void clear();
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>VQueue::<T>VQueue(int sz)
+{
+ s = new <T> [size = sz];
+ cnt = inp = outp = 0;
+}
+
+inline <T>VQueue::~<T>VQueue()
+{
+ delete [size] 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/VStack.ccP b/gnu/lib/libg++/g++-include/gen/VStack.ccP
new file mode 100644
index 00000000000..0404aa3b0c8
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VStack.ccP
@@ -0,0 +1,71 @@
+// 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 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 <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 [size] 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 [size] 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++/g++-include/gen/VStack.hP b/gnu/lib/libg++/g++-include/gen/VStack.hP
new file mode 100644
index 00000000000..c41bcba9214
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/VStack.hP
@@ -0,0 +1,128 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>VStack_h
+#ifdef __GNUG__
+#pragma once
+#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&);
+ ~<T>VStack();
+
+ void operator = (<T>VStack&);
+ void push(<T&> item);
+ <T> pop();
+ <T>& top();
+ void del_top();
+
+ int length();
+ int empty();
+ int full();
+ void clear();
+
+ void resize(int sz);
+ int capacity();
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+inline <T>VStack::<T>VStack(int sz)
+{
+ s = new <T> [size = sz];
+ ptr = 0;
+}
+
+inline <T>VStack::~<T>VStack()
+{
+ delete [size] 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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/Vec.ccP b/gnu/lib/libg++/g++-include/gen/Vec.ccP
new file mode 100644
index 00000000000..381b7d6a176
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Vec.ccP
@@ -0,0 +1,474 @@
+// 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 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 <stream.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(<T>Vec& v)
+{
+ s = new <T> [len = v.len];
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ <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 = (<T>Vec& v)
+{
+ if (this != &v)
+ {
+ delete[len] s;
+ s = new <T> [len = v.len];
+ <T>* top = &(s[len]);
+ <T>* t = s;
+ <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 [len] 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 (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++ != *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 > 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 > 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 og 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++/g++-include/gen/Vec.hP b/gnu/lib/libg++/g++-include/gen/Vec.hP
new file mode 100644
index 00000000000..8addfd6c19c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/Vec.hP
@@ -0,0 +1,142 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>Vec_h
+#ifdef __GNUG__
+#pragma once
+#pragma interface
+#endif
+#define _<T>Vec_h 1
+
+#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 (<T>Vec&);
+ ~<T>Vec ();
+
+ <T>Vec & operator = (<T>Vec & a);
+ <T>Vec at(int from = 0, int n = -1);
+
+ int capacity();
+ 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);
+
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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[len] s;
+}
+
+
+inline <T>& <T>Vec::operator [] (int n)
+{
+ if ((unsigned)n >= len)
+ range_error();
+ return s[n];
+}
+
+inline <T>& <T>Vec::elem(int n)
+{
+ return s[n];
+}
+
+
+inline int <T>Vec::capacity()
+{
+ return len;
+}
+
+
+
+inline int operator != (<T>Vec& a, <T>Vec& b)
+{
+ return !(a == b);
+}
+
+
+#endif
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPBag.ccP b/gnu/lib/libg++/g++-include/gen/XPBag.ccP
new file mode 100644
index 00000000000..59fa706b7a9
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPBag.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 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 "<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++/g++-include/gen/XPBag.hP b/gnu/lib/libg++/g++-include/gen/XPBag.hP
new file mode 100644
index 00000000000..4e8aad719fc
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPBag.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 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.
+*/
+
+
+#ifndef _<T>XPBag_h
+#ifdef __GNUG__
+#pragma once
+#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&);
+
+ Pix add(<T&> item);
+ void del(<T&> item);
+ void remove(<T&>item);
+ int nof(<T&> item);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item, Pix from = 0);
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPDeque.ccP b/gnu/lib/libg++/g++-include/gen/XPDeque.ccP
new file mode 100644
index 00000000000..6b363d9bdc4
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPDeque.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPDeque.h"
diff --git a/gnu/lib/libg++/g++-include/gen/XPDeque.hP b/gnu/lib/libg++/g++-include/gen/XPDeque.hP
new file mode 100644
index 00000000000..528766a8cef
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPDeque.hP
@@ -0,0 +1,142 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>XPDeque_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>XPDeque();
+
+ void operator = (const <T>XPDeque&);
+
+ void push(<T&> item); // insert at front
+ void enq(<T&> item); // insert at rear
+
+ <T>& front();
+ <T>& rear();
+
+ <T> deq();
+ void del_front();
+ void del_rear();
+
+ void clear();
+ int empty();
+ int full();
+ int length();
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPPQ.ccP b/gnu/lib/libg++/g++-include/gen/XPPQ.ccP
new file mode 100644
index 00000000000..f11731dad43
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPPQ.ccP
@@ -0,0 +1,148 @@
+// 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 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 "<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++/g++-include/gen/XPPQ.hP b/gnu/lib/libg++/g++-include/gen/XPPQ.hP
new file mode 100644
index 00000000000..46cdfdb6e8d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPPQ.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)
+
+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.
+*/
+
+
+#ifndef _<T>XPPQ_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ <T> deq();
+
+ <T>& front();
+ void del_front();
+
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ void del(Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item);
+
+ int OK(); // rep invariant
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPQueue.ccP b/gnu/lib/libg++/g++-include/gen/XPQueue.ccP
new file mode 100644
index 00000000000..77bfd1c7a95
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPQueue.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPQueue.h"
diff --git a/gnu/lib/libg++/g++-include/gen/XPQueue.hP b/gnu/lib/libg++/g++-include/gen/XPQueue.hP
new file mode 100644
index 00000000000..da070fd0458
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPQueue.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)
+ based on code by Marc Shapiro (shapiro@sor.inria.fr)
+
+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.
+*/
+
+
+#ifndef _<T>XPQueue_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>XPQueue();
+
+ void operator = (const <T>XPQueue&);
+
+ void enq(<T&> item);
+ <T> deq();
+ <T>& front();
+ void del_front();
+
+ void clear();
+ int empty();
+ int full();
+ int length();
+
+ int OK();
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPSet.ccP b/gnu/lib/libg++/g++-include/gen/XPSet.ccP
new file mode 100644
index 00000000000..97743735635
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPSet.ccP
@@ -0,0 +1,68 @@
+// 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 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 "<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++/g++-include/gen/XPSet.hP b/gnu/lib/libg++/g++-include/gen/XPSet.hP
new file mode 100644
index 00000000000..5e06b81d25d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPSet.hP
@@ -0,0 +1,99 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>XPSet_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ int contains(<T&> item);
+
+ void clear();
+
+ Pix first();
+ void next(Pix& i);
+ <T>& operator () (Pix i);
+ int owns(Pix i);
+ Pix seek(<T&> item);
+
+ int OK();
+};
+
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPStack.ccP b/gnu/lib/libg++/g++-include/gen/XPStack.ccP
new file mode 100644
index 00000000000..fe24f0f044a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPStack.ccP
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "<T>.XPStack.h"
diff --git a/gnu/lib/libg++/g++-include/gen/XPStack.hP b/gnu/lib/libg++/g++-include/gen/XPStack.hP
new file mode 100644
index 00000000000..f0c18491e09
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPStack.hP
@@ -0,0 +1,124 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>XPStack_h
+#ifdef __GNUG__
+#pragma once
+#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);
+ ~<T>XPStack();
+
+ void operator = (const <T>XPStack&);
+
+ void push(<T&> item);
+ <T> pop();
+ <T>& top();
+ void del_top();
+
+ int empty();
+ int full();
+ int length();
+
+ void clear();
+
+ int OK();
+
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/XPlex.ccP b/gnu/lib/libg++/g++-include/gen/XPlex.ccP
new file mode 100644
index 00000000000..2cef5293aa7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPlex.ccP
@@ -0,0 +1,412 @@
+// 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 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 "<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::append (const <T>XPlex& a)
+{
+ for (int i = a.low(); i < a.fence(); a.next(i)) add_high(a[i]);
+}
+
+void <T>XPlex::prepend (const <T>XPlex& a)
+{
+ for (int i = a.high(); i > a.ecnef(); a.prev(i)) add_low(a[i]);
+}
+
+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++/g++-include/gen/XPlex.hP b/gnu/lib/libg++/g++-include/gen/XPlex.hP
new file mode 100644
index 00000000000..41acef7fff7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/XPlex.hP
@@ -0,0 +1,248 @@
+// 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 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.
+*/
+
+#ifndef _<T>XPlex_h
+#ifdef __GNUG__
+#pragma once
+#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;
+
+ 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
+
+
+ <T>& high_element ();
+ <T>& low_element ();
+
+ const <T>& high_element () const;
+ const <T>& low_element () const;
+
+ Pix first() const;
+ Pix last() const;
+ void prev(Pix& ptr) const;
+ void next(Pix& ptr) const;
+ int owns(Pix p) const;
+ <T>& operator () (Pix p);
+ const <T>& operator () (Pix p) const;
+
+ int low() const;
+ int high() const;
+ int valid(int idx) const;
+ void prev(int& idx) const;
+ void next(int& x) const;
+ <T>& operator [] (int index);
+ const <T>& operator [] (int index) const;
+
+ int Pix_to_index(Pix p) const;
+ Pix index_to_Pix(int idx) const;
+
+ int can_add_high() const;
+ int can_add_low() const;
+ 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();
+ void append(const <T>XPlex& a);
+ void prepend(const <T>XPlex& a);
+
+ int OK () const;
+
+};
+
+#if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
+
+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
+#endif
diff --git a/gnu/lib/libg++/g++-include/gen/defs.hP b/gnu/lib/libg++/g++-include/gen/defs.hP
new file mode 100644
index 00000000000..4efc82d2632
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/gen/defs.hP
@@ -0,0 +1,60 @@
+// 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 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.
+*/
+
+
+#ifndef _<T>defs_h
+#ifdef __GNUG__
+#pragma once
+#endif
+#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
+
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/hash.cc b/gnu/lib/libg++/g++-include/hash.cc
new file mode 100644
index 00000000000..4f16f975989
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/hash.cc
@@ -0,0 +1,56 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+/*
+ some useful hash functions
+*/
+
+unsigned int hashpjw(const char* x) // From Dragon book, p436
+{
+ unsigned int h = 0;
+ unsigned int g;
+
+ while (*x != 0)
+ {
+ h = (h << 4) + *x++;
+ if ((g = h & 0xf0000000) != 0)
+ h = (h ^ (g >> 24)) ^ g;
+ }
+ return h;
+}
+
+unsigned int multiplicativehash(int x)
+{
+ // uses a const close to golden ratio * pow(2,32)
+ return ((unsigned)x) * 2654435767;
+}
+
+
+unsigned int foldhash(double x)
+{
+ union { unsigned int i[2]; double d; } u;
+ u.d = x;
+ unsigned int u0 = u.i[0];
+ unsigned int u1 = u.i[1];
+ return u0 ^ u1;
+}
+
diff --git a/gnu/lib/libg++/g++-include/ioob.cc b/gnu/lib/libg++/g++-include/ioob.cc
new file mode 100644
index 00000000000..08409a5d292
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/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++/g++-include/lg.cc b/gnu/lib/libg++/g++-include/lg.cc
new file mode 100644
index 00000000000..b5ea5fd0fb9
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/lg.cc
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+long lg(unsigned long x)
+{
+ long l = 0;
+ while (x > 1)
+ {
+ x = x >> 1;
+ ++l;
+ }
+ return l;
+}
diff --git a/gnu/lib/libg++/g++-include/math.cc b/gnu/lib/libg++/g++-include/math.cc
new file mode 100644
index 00000000000..f1a0e52aba5
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/math.cc
@@ -0,0 +1,4 @@
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <math.h>
diff --git a/gnu/lib/libg++/g++-include/new.cc b/gnu/lib/libg++/g++-include/new.cc
new file mode 100644
index 00000000000..7a707a6ee9d
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/new.cc
@@ -0,0 +1,31 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <new.h>
+
+#if 0 /* ndef NO_LIBGXX_MALLOC */
+
+void* operator new(size_t n)
+{
+ return malloc (n);
+}
+#endif
diff --git a/gnu/lib/libg++/g++-include/new.h b/gnu/lib/libg++/g++-include/new.h
new file mode 100644
index 00000000000..414923319fd
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/new.h
@@ -0,0 +1,35 @@
+/* $Id: new.h,v 1.1 1995/10/18 08:38:19 deraadt Exp $ */
+
+#ifndef _new_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _new_h 1
+
+#include <stddef.h>
+#include <std.h>
+
+#ifndef NO_LIBGXX_MALLOC
+#define MALLOC_ALIGN_MASK 7 /* ptrs aligned at 8 byte boundaries */
+#define MALLOC_MIN_OVERHEAD 8 /* 8 bytes of overhead per pointer */
+#endif
+
+typedef void (*new_handler_t)();
+extern new_handler_t __new_handler;
+extern "C" void default_new_handler();
+extern "C" new_handler_t set_new_handler(new_handler_t);
+
+#ifdef __GNUG__
+#define NEW(where) new { where }
+#endif
+
+// default placement version of operator new
+static inline void *operator new(size_t, void *place) { return place; }
+
+// provide a C++ interface to vector-resize via realloc
+inline void *operator new(size_t size, void *ptr, size_t new_len)
+{
+ return realloc(ptr, new_len * size);
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/osfcn.h b/gnu/lib/libg++/g++-include/osfcn.h
new file mode 100644
index 00000000000..3a12d99b56c
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/osfcn.h
@@ -0,0 +1,17 @@
+/* $Id: osfcn.h,v 1.1 1995/10/18 08:38:19 deraadt Exp $ */
+
+#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/resource.h>
+#endif
+
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/pow.cc b/gnu/lib/libg++/g++-include/pow.cc
new file mode 100644
index 00000000000..b56a8b7d779
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/pow.cc
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <math.h>
+
+double pow(double x, long p)
+{
+ if (p == 0)
+ return 1.0;
+ else if (x == 0.0)
+ return 0.0;
+ else
+ {
+ if (p < 0)
+ {
+ p = -p;
+ x = 1.0 / x;
+ }
+
+ double r = 1.0;
+ for(;;)
+ {
+ if (p & 1)
+ r *= x;
+ if ((p >>= 1) == 0)
+ return r;
+ else
+ x *= x;
+ }
+ }
+}
+
+long pow(long x, long p)
+{
+ if (p == 0)
+ return 1;
+ else if (p < 0 || x == 0)
+ return 0;
+ else
+ {
+ long r = 1;
+ for(;;)
+ {
+ if (p & 1)
+ r *= x;
+ if ((p >>= 1) == 0)
+ return r;
+ else
+ x *= x;
+ }
+ }
+}
diff --git a/gnu/lib/libg++/g++-include/regex.cc b/gnu/lib/libg++/g++-include/regex.cc
new file mode 100644
index 00000000000..199308d0da2
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/regex.cc
@@ -0,0 +1,2757 @@
+/* Extended regular expression matching and search library.
+ Copyright (C) 1985, 1989-90 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+// This is a translation into C++ of regex.c, the GNU regexp package.
+
+/* To test, compile with -Dtest. This Dtestable feature turns this into
+ a self-contained program which reads a pattern, describes how it
+ compiles, then reads a string and searches for it.
+
+ On the other hand, if you compile with both -Dtest and -Dcanned you
+ can run some tests we've already thought of. */
+
+/* AIX requires the alloca decl to be the first thing in the file. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#ifdef sparc
+#include <alloca.h>
+extern "C" void *__builtin_alloca(...);
+#else
+#ifdef _AIX
+#pragma alloca
+#else
+char *alloca ();
+#endif
+#endif
+#endif
+
+#ifdef emacs
+
+/* The `emacs' switch turns on certain special matching commands
+ that make sense only in emacs. */
+
+#include "config.h"
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+#else /* not emacs */
+
+#include <_G_config.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Define the syntax stuff, so we can do the \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+#ifndef Sword
+#define Sword 1
+#endif
+
+#define SYNTAX(c) re_syntax_table[c]
+
+
+#ifdef SYNTAX_TABLE
+
+char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+static char re_syntax_table[256];
+
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ memset (re_syntax_table, 0, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ done = 1;
+}
+
+#endif /* SYNTAX_TABLE */
+#endif /* emacs */
+
+/* We write fatal error messages on standard error. */
+#include <stdio.h>
+
+/* isalpha(3) etc. are used for the character classes. */
+#include <ctype.h>
+/* Sequents are missing isgraph. */
+#ifndef isgraph
+#define isgraph(c) (isprint((c)) && !isspace((c)))
+#endif
+
+/* Get the interface, including the syntax bits. */
+#include "regex.h"
+
+
+/* These are the command codes that appear in compiled regular
+ expressions, one per byte. Some command codes are followed by
+ argument bytes. A command code can specify any interpretation
+ whatsoever for its arguments. Zero-bytes may appear in the compiled
+ regular expression.
+
+ The value of `exactn' is needed in search.c (search_buffer) in emacs.
+ So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
+ `exactn' we use here must also be 1. */
+
+enum regexpcode
+ {
+ unused=0,
+ exactn=1, /* Followed by one byte giving n, then by n literal bytes. */
+ begline, /* Fail unless at beginning of line. */
+ endline, /* Fail unless at end of line. */
+ jump, /* Followed by two bytes giving relative address to jump to. */
+ on_failure_jump, /* Followed by two bytes giving relative address of
+ place to resume at in case of failure. */
+ finalize_jump, /* Throw away latest failure point and then jump to
+ address. */
+ maybe_finalize_jump, /* Like jump but finalize if safe to do so.
+ This is used to jump back to the beginning
+ of a repeat. If the command that follows
+ this jump is clearly incompatible with the
+ one at the beginning of the repeat, such that
+ we can be sure that there is no use backtracking
+ out of repetitions already completed,
+ then we finalize. */
+ dummy_failure_jump, /* Jump, and push a dummy failure point. This
+ failure point will be thrown away if an attempt
+ is made to use it for a failure. A + construct
+ makes this before the first repeat. Also
+ use it as an intermediary kind of jump when
+ compiling an or construct. */
+ succeed_n, /* Used like on_failure_jump except has to succeed n times;
+ then gets turned into an on_failure_jump. The relative
+ address following it is useless until then. The
+ address is followed by two bytes containing n. */
+ jump_n, /* Similar to jump, but jump n times only; also the relative
+ address following is in turn followed by yet two more bytes
+ containing n. */
+ set_number_at, /* Set the following relative location to the
+ subsequent number. */
+ anychar, /* Matches any (more or less) one character. */
+ charset, /* Matches any one char belonging to specified set.
+ First following byte is number of bitmap bytes.
+ Then come bytes for a bitmap saying which chars are in.
+ Bits in each byte are ordered low-bit-first.
+ A character is in the set if its bit is 1.
+ A character too large to have a bit in the map
+ is automatically not in the set. */
+ charset_not, /* Same parameters as charset, but match any character
+ that is not one of those specified. */
+ start_memory, /* Start remembering the text that is matched, for
+ storing in a memory register. Followed by one
+ byte containing the register number. Register numbers
+ must be in the range 0 through RE_NREGS. */
+ stop_memory, /* Stop remembering the text that is matched
+ and store it in a memory register. Followed by
+ one byte containing the register number. Register
+ numbers must be in the range 0 through RE_NREGS. */
+ duplicate, /* Match a duplicate of something remembered.
+ Followed by one byte containing the index of the memory
+ register. */
+#ifdef emacs
+ before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+#endif
+ begbuf, /* Succeeds if at beginning of buffer. */
+ endbuf, /* Succeeds if at end of buffer. */
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound,/* Succeeds if not at a word boundary. */
+#ifdef emacs
+ syntaxspec, /* Matches any character whose syntax is specified.
+ followed by a byte which contains a syntax code,
+ e.g., Sword. */
+ notsyntaxspec /* Matches any character whose syntax differs from
+ that specified. */
+#endif
+ };
+
+
+/* Number of failure points to allocate space for initially,
+ when matching. If this number is exceeded, more space is allocated,
+ so it is not a hard limit. */
+
+#ifndef NFAILURES
+#define NFAILURES 80
+#endif
+
+
+#ifndef SIGN_EXTEND_CHAR
+#ifdef __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char)(c))
+#else
+#define SIGN_EXTEND_CHAR(c) (((c)^128) - 128) /* As in Harbison and Steele. */
+#endif
+#endif /* not SIGN_EXTEND_CHAR */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+#define STORE_NUMBER(destination, number) \
+ { (destination)[0] = (char)((number) & 0377); \
+ (destination)[1] = (number) >> 8; }
+
+/* Same as STORE_NUMBER, except increment the destination pointer to
+ the byte after where the number is stored. Watch out that values for
+ DESTINATION such as p + 1 won't work, whereas p will. */
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ { STORE_NUMBER(destination, number); \
+ (destination) += 2; }
+
+
+/* Put into DESTINATION a number stored in two contingous bytes starting
+ at SOURCE. */
+#define EXTRACT_NUMBER(destination, source) \
+ { (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*(char *)((source) + 1)) << 8; }
+
+/* Same as EXTRACT_NUMBER, except increment the pointer for source to
+ point to second byte of SOURCE. Note that SOURCE has to be a value
+ such as p, not, e.g., p + 1. */
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ { EXTRACT_NUMBER (destination, source); \
+ (source) += 2; }
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit-mask comprised of the various bits
+ defined in regex.h. */
+
+int
+re_set_syntax (int syntax)
+{
+ int ret;
+
+ ret = obscure_syntax;
+ obscure_syntax = syntax;
+ return ret;
+}
+
+/* Set by re_set_syntax to the current regexp syntax to recognize. */
+int obscure_syntax = 0;
+
+
+
+/* Macros for re_compile_pattern, which is found below these definitions. */
+
+#define CHAR_CLASS_MAX_LENGTH 6
+
+/* Fetch the next character in the uncompiled pattern, translating it if
+ necessary. */
+#define PATFETCH(c) \
+ {if (p == pend) goto end_of_pattern; \
+ c = * (const unsigned char *) p++; \
+ if (translate) c = translate[c]; }
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ {if (p == pend) goto end_of_pattern; \
+ c = * (const unsigned char *) p++; }
+
+#define PATUNFETCH p--
+
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 28
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ { \
+ while (b - bufp->buffer + (n) >= bufp->allocated) \
+ EXTEND_BUFFER; \
+ }
+
+/* Make sure we have one more byte of buffer space and then add CH to it. */
+#define BUFPUSH(ch) \
+ { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (char) (ch); \
+ }
+
+/* Extend the buffer by twice its current size via reallociation and
+ reset the pointers that pointed into the old allocation to point to
+ the correct places in the new allocation. If extending the buffer
+ results in it being larger than 1 << 16, then flag memory exhausted. */
+#define EXTEND_BUFFER \
+ { char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == (1L<<16)) goto too_big; \
+ bufp->allocated *= 2; \
+ if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16); \
+ bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated); \
+ if (bufp->buffer == 0) \
+ goto memory_exhausted; \
+ b = (b - old_buffer) + bufp->buffer; \
+ if (fixup_jump) \
+ fixup_jump = (fixup_jump - old_buffer) + bufp->buffer; \
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ }
+
+/* Set the bit for character C in a character set list. */
+#define SET_LIST_BIT(c) (b[(c) / BYTEWIDTH] |= 1 << ((c) % BYTEWIDTH))
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (isdigit (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+/* Subroutines for re_compile_pattern. */
+static void store_jump (char *from, char opcode, char *to);
+static void insert_jump (char op, char *from, char *to, char *current_end);
+static void store_jump_n (char *from, char opcode, char *to, unsigned n);
+static void insert_jump_n (char, char *, char *, char *, unsigned);
+static void insert_op_2 (char, char *, char *_end, int, int);
+
+
+/* re_compile_pattern takes a regular-expression string
+ and converts it into a buffer full of byte commands for matching.
+
+ PATTERN is the address of the pattern string
+ SIZE is the length of it.
+ BUFP is a struct re_pattern_buffer * which points to the info
+ on where to store the byte commands.
+ This structure contains a char * which points to the
+ actual space, which should have been obtained with malloc.
+ re_compile_pattern may use realloc to grow the buffer space.
+
+ The number of bytes of commands can be found out by looking in
+ the `struct re_pattern_buffer' that bufp pointed to, after
+ re_compile_pattern returns. */
+
+char *
+re_compile_pattern (const char *pattern, int size, struct re_pattern_buffer *bufp)
+{
+ register char *b = bufp->buffer;
+ register const char *p = pattern;
+ const char *pend = pattern + size;
+ register unsigned c, c1;
+ const char *p1;
+ unsigned char *translate = (unsigned char *) bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell whether a new exact-match
+ character can be added to that command or requires a new `exactn'
+ command. */
+
+ char *pending_exact = 0;
+
+ /* Address of the place where a forward-jump should go to the end of
+ the containing expression. Each alternative of an `or', except the
+ last, ends with a forward-jump of this sort. */
+
+ char *fixup_jump = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells postfix * where to find the start of its operand. */
+
+ char *laststart = 0;
+
+ /* In processing a repeat, 1 means zero matches is allowed. */
+
+ char zero_times_ok;
+
+ /* In processing a repeat, 1 means many matches is allowed. */
+
+ char many_times_ok;
+
+ /* Address of beginning of regexp, or inside of last \(. */
+
+ char *begalt = b;
+
+ /* In processing an interval, at least this many matches must be made. */
+ int lower_bound;
+
+ /* In processing an interval, at most this many matches can be made. */
+ int upper_bound;
+
+ /* Place in pattern (i.e., the {) to which to go back if the interval
+ is invalid. */
+ const char *beg_interval = 0;
+
+ /* Stack of information saved by \( and restored by \).
+ Four stack elements are pushed by each \(:
+ First, the value of b.
+ Second, the value of fixup_jump.
+ Third, the value of regnum.
+ Fourth, the value of begalt. */
+
+ int stackb[40];
+ int *stackp = stackb;
+ int *stacke = stackb + 40;
+ int *stackt;
+
+ /* Counts \('s as they are encountered. Remembered for the matching \),
+ where it becomes the register number to put in the stop_memory
+ command. */
+
+ unsigned regnum = 1;
+
+ bufp->fastmap_accurate = 0;
+
+#ifndef emacs
+#ifndef SYNTAX_TABLE
+ /* Initialize the syntax table. */
+ init_syntax_once();
+#endif
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ bufp->allocated = INIT_BUF_SIZE;
+ if (bufp->buffer)
+ /* EXTEND_BUFFER loses when bufp->allocated is 0. */
+ bufp->buffer = (char *) realloc (bufp->buffer, INIT_BUF_SIZE);
+ else
+ /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = (char *) malloc (INIT_BUF_SIZE);
+ if (!bufp->buffer) goto memory_exhausted;
+ begalt = b = bufp->buffer;
+ }
+
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '$':
+ {
+ const char *p1 = p;
+ /* When testing what follows the $,
+ look past the \-constructs that don't consume anything. */
+ if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ while (p1 != pend)
+ {
+ if (*p1 == '\\' && p1 + 1 != pend
+ && (p1[1] == '<' || p1[1] == '>'
+ || p1[1] == '`' || p1[1] == '\''
+#ifdef emacs
+ || p1[1] == '='
+#endif
+ || p1[1] == 'b' || p1[1] == 'B'))
+ p1 += 2;
+ else
+ break;
+ }
+ if (obscure_syntax & RE_TIGHT_VBAR)
+ {
+ if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p1 != pend)
+ goto normal_char;
+ /* Make operand of last vbar end before this `$'. */
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+ fixup_jump = 0;
+ BUFPUSH (endline);
+ break;
+ }
+ /* $ means succeed if at end of line, but only in special contexts.
+ If validly in the middle of a pattern, it is a normal character. */
+
+ if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS) && p1 != pend)
+ goto invalid_pattern;
+ if (p1 == pend || *p1 == '\n'
+ || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
+ || (obscure_syntax & RE_NO_BK_PARENS
+ ? *p1 == ')'
+ : *p1 == '\\' && p1[1] == ')')
+ || (obscure_syntax & RE_NO_BK_VBAR
+ ? *p1 == '|'
+ : *p1 == '\\' && p1[1] == '|'))
+ {
+ BUFPUSH (endline);
+ break;
+ }
+ goto normal_char;
+ }
+ case '^':
+ /* ^ means succeed if at beg of line, but only if no preceding
+ pattern. */
+
+ if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS) && laststart)
+ goto invalid_pattern;
+ if (laststart && p - 2 >= pattern && p[-2] != '\n'
+ && !(obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ if (obscure_syntax & RE_TIGHT_VBAR)
+ {
+ if (p != pattern + 1
+ && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ BUFPUSH (begline);
+ begalt = b;
+ }
+ else
+ BUFPUSH (begline);
+ break;
+
+ case '+':
+ case '?':
+ if ((obscure_syntax & RE_BK_PLUS_QM)
+ || (obscure_syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern, char not special. */
+ if (!laststart)
+ {
+ if (obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
+ goto invalid_pattern;
+ else if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+ /* If there is a sequence of repetition chars,
+ collapse it down to just one. */
+ zero_times_ok = 0;
+ many_times_ok = 0;
+ while (1)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+ if (p == pend)
+ break;
+ PATFETCH (c);
+ if (c == '*')
+ ;
+ else if (!(obscure_syntax & RE_BK_PLUS_QM)
+ && (c == '+' || c == '?'))
+ ;
+ else if ((obscure_syntax & RE_BK_PLUS_QM)
+ && c == '\\')
+ {
+ int c1;
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ {
+ /* If more than one repetition is allowed, put in at the
+ end a backward relative jump from b to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump). */
+ GET_BUFFER_SPACE (3);
+ store_jump (b, maybe_finalize_jump, laststart - 3);
+ b += 3; /* Because store_jump put stuff here. */
+ }
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ insert_jump (on_failure_jump, laststart, b + 3, b);
+ pending_exact = 0;
+ b += 3;
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ dummy-failure before the initial on-failure-jump
+ instruction of the loop. This effects a skip over that
+ instruction the first time we hit that loop. */
+ GET_BUFFER_SPACE (6);
+ insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
+ b += 3;
+ }
+ break;
+
+ case '.':
+ laststart = b;
+ BUFPUSH (anychar);
+ break;
+
+ case '[':
+ if (p == pend)
+ goto invalid_pattern;
+ while (b - bufp->buffer
+ > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
+ EXTEND_BUFFER;
+
+ laststart = b;
+ if (*p == '^')
+ {
+ BUFPUSH (charset_not);
+ p++;
+ }
+ else
+ BUFPUSH (charset);
+ p1 = p;
+
+ BUFPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+ /* Clear the whole map */
+ memset (b, 0, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ if ((obscure_syntax & RE_HAT_NOT_NEWLINE) && b[-2] == charset_not)
+ SET_LIST_BIT ('\n');
+
+
+ /* Read in characters and ranges, setting map bits. */
+ while (1)
+ {
+ /* Don't translate while fetching, in case it's a range bound.
+ When we set the bit for the character, we translate it. */
+ PATFETCH_RAW (c);
+
+ /* If set, \ escapes characters when inside [...]. */
+ if ((obscure_syntax & RE_AWK_CLASS_HACK) && c == '\\')
+ {
+ PATFETCH(c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+ if (c == ']')
+ {
+ if (p == p1 + 1)
+ {
+ /* If this is an empty bracket expression. */
+ if ((obscure_syntax & RE_NO_EMPTY_BRACKETS)
+ && p == pend)
+ goto invalid_pattern;
+ }
+ else
+ /* Stop if this isn't merely a ] inside a bracket
+ expression, but rather the end of a bracket
+ expression. */
+ break;
+ }
+ /* Get a range. */
+ if (p[0] == '-' && p[1] != ']')
+ {
+ PATFETCH (c1);
+ /* Don't translate the range bounds while fetching them. */
+ PATFETCH_RAW (c1);
+
+ if ((obscure_syntax & RE_NO_EMPTY_RANGES) && c > c1)
+ goto invalid_pattern;
+
+ if ((obscure_syntax & RE_NO_HYPHEN_RANGE_END)
+ && c1 == '-' && *p != ']')
+ goto invalid_pattern;
+
+ while (c <= c1)
+ {
+ /* Translate each char that's in the range. */
+ if (translate)
+ SET_LIST_BIT (translate[c]);
+ else
+ SET_LIST_BIT (c);
+ c++;
+ }
+ }
+ else if ((obscure_syntax & RE_CHAR_CLASSES)
+ && c == '[' && p[0] == ':')
+ {
+ /* Longest valid character class word has six characters. */
+ char str[CHAR_CLASS_MAX_LENGTH];
+ PATFETCH (c);
+ c1 = 0;
+ /* If no ] at end. */
+ if (p == pend)
+ goto invalid_pattern;
+ while (1)
+ {
+ /* Don't translate the ``character class'' characters. */
+ PATFETCH_RAW (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+ if (p == pend
+ || c == ']' /* End of the bracket expression. */
+ || p[0] != ']'
+ || p + 1 == pend
+ || (strcmp (str, "alpha") != 0
+ && strcmp (str, "upper") != 0
+ && strcmp (str, "lower") != 0
+ && strcmp (str, "digit") != 0
+ && strcmp (str, "alnum") != 0
+ && strcmp (str, "xdigit") != 0
+ && strcmp (str, "space") != 0
+ && strcmp (str, "print") != 0
+ && strcmp (str, "punct") != 0
+ && strcmp (str, "graph") != 0
+ && strcmp (str, "cntrl") != 0))
+ {
+ /* Undo the ending character, the letters, and leave
+ the leading : and [ (but set bits for them). */
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ }
+ else
+ {
+ /* The ] at the end of the character class. */
+ PATFETCH (c);
+ if (c != ']')
+ goto invalid_pattern;
+ for (c = 0; c < (1 << BYTEWIDTH); c++)
+ {
+ if ((strcmp (str, "alpha") == 0 && isalpha (c))
+ || (strcmp (str, "upper") == 0 && isupper (c))
+ || (strcmp (str, "lower") == 0 && islower (c))
+ || (strcmp (str, "digit") == 0 && isdigit (c))
+ || (strcmp (str, "alnum") == 0 && isalnum (c))
+ || (strcmp (str, "xdigit") == 0 && isxdigit (c))
+ || (strcmp (str, "space") == 0 && isspace (c))
+ || (strcmp (str, "print") == 0 && isprint (c))
+ || (strcmp (str, "punct") == 0 && ispunct (c))
+ || (strcmp (str, "graph") == 0 && isgraph (c))
+ || (strcmp (str, "cntrl") == 0 && iscntrl (c)))
+ SET_LIST_BIT (c);
+ }
+ }
+ }
+ else if (translate)
+ SET_LIST_BIT (translate[c]);
+ else
+ SET_LIST_BIT (c);
+ }
+
+ /* Discard any character set/class bitmap bytes that are all
+ 0 at the end of the map. Decrement the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ break;
+
+ case '(':
+ if (! (obscure_syntax & RE_NO_BK_PARENS))
+ goto normal_char;
+ else
+ goto handle_open;
+
+ case ')':
+ if (! (obscure_syntax & RE_NO_BK_PARENS))
+ goto normal_char;
+ else
+ goto handle_close;
+
+ case '\n':
+ if (! (obscure_syntax & RE_NEWLINE_OR))
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case '|':
+ if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
+ && (! laststart || p == pend))
+ goto invalid_pattern;
+ else if (! (obscure_syntax & RE_NO_BK_VBAR))
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case '{':
+ if (! ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ && (obscure_syntax & RE_INTERVALS)))
+ goto normal_char;
+ else
+ goto handle_interval;
+
+ case '\\':
+ if (p == pend) goto invalid_pattern;
+ PATFETCH_RAW (c);
+ switch (c)
+ {
+ case '(':
+ if (obscure_syntax & RE_NO_BK_PARENS)
+ goto normal_backsl;
+ handle_open:
+ if (stackp == stacke) goto nesting_too_deep;
+
+ /* Laststart should point to the start_memory that we are about
+ to push (unless the pattern has RE_NREGS or more ('s). */
+ *stackp++ = b - bufp->buffer;
+ if (regnum < RE_NREGS)
+ {
+ BUFPUSH (start_memory);
+ BUFPUSH (regnum);
+ }
+ *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
+ *stackp++ = regnum++;
+ *stackp++ = begalt - bufp->buffer;
+ fixup_jump = 0;
+ laststart = 0;
+ begalt = b;
+ break;
+
+ case ')':
+ if (obscure_syntax & RE_NO_BK_PARENS)
+ goto normal_backsl;
+ handle_close:
+ if (stackp == stackb) goto unmatched_close;
+ begalt = *--stackp + bufp->buffer;
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+ if (stackp[-1] < RE_NREGS)
+ {
+ BUFPUSH (stop_memory);
+ BUFPUSH (stackp[-1]);
+ }
+ stackp -= 2;
+ fixup_jump = *stackp ? *stackp + bufp->buffer - 1 : 0;
+ laststart = *--stackp + bufp->buffer;
+ break;
+
+ case '|':
+ if ((obscure_syntax & RE_LIMITED_OPS)
+ || (obscure_syntax & RE_NO_BK_VBAR))
+ goto normal_backsl;
+ handle_bar:
+ if (obscure_syntax & RE_LIMITED_OPS)
+ goto normal_char;
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (6);
+ insert_jump (on_failure_jump, begalt, b + 6, b);
+ pending_exact = 0;
+ b += 3;
+ /* The alternative before the previous alternative has a
+ jump after it which gets executed if it gets matched.
+ Adjust that jump so it will jump to the previous
+ alternative's analogous jump (put in below, which in
+ turn will jump to the next (if any) alternative's such
+ jump, etc.). The last such jump jumps to the correct
+ final destination. */
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+
+ /* Leave space for a jump after previous alternative---to be
+ filled in later. */
+ fixup_jump = b;
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+ case '{':
+ if (! (obscure_syntax & RE_INTERVALS)
+ /* Let \{ be a literal. */
+ || ((obscure_syntax & RE_INTERVALS)
+ && (obscure_syntax & RE_NO_BK_CURLY_BRACES))
+ /* If it's the string "\{". */
+ || (p - 2 == pattern && p == pend))
+ goto normal_backsl;
+ handle_interval:
+ beg_interval = p - 1; /* The {. */
+ /* If there is no previous pattern, this isn't an interval. */
+ if (!laststart)
+ {
+ if (obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
+ goto invalid_pattern;
+ else
+ goto normal_backsl;
+ }
+ /* It also isn't an interval if not preceded by an re
+ matching a single character or subexpression, or if
+ the current type of intervals can't handle back
+ references and the previous thing is a back reference. */
+ if (! (*laststart == anychar
+ || *laststart == charset
+ || *laststart == charset_not
+ || *laststart == start_memory
+ || (*laststart == exactn && laststart[1] == 1)
+ || (! (obscure_syntax & RE_NO_BK_REFS)
+ && *laststart == duplicate)))
+ {
+ if (obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ goto normal_char;
+
+ /* Posix extended syntax is handled in previous
+ statement; this is for Posix basic syntax. */
+ if (obscure_syntax & RE_INTERVALS)
+ goto invalid_pattern;
+
+ goto normal_backsl;
+ }
+ lower_bound = -1; /* So can see if are set. */
+ upper_bound = -1;
+ GET_UNSIGNED_NUMBER (lower_bound);
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0)
+ upper_bound = RE_DUP_MAX;
+ }
+ if (upper_bound < 0)
+ upper_bound = lower_bound;
+ if (! (obscure_syntax & RE_NO_BK_CURLY_BRACES))
+ {
+ if (c != '\\')
+ goto invalid_pattern;
+ PATFETCH (c);
+ }
+ if (c != '}' || lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound
+ || ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ && p != pend && *p == '{'))
+ {
+ if (obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ goto unfetch_interval;
+ else
+ goto invalid_pattern;
+ }
+
+ /* If upper_bound is zero, don't want to succeed at all;
+ jump from laststart to b + 3, which will be the end of
+ the buffer after this jump is inserted. */
+
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ insert_jump (jump, laststart, b + 3, b);
+ b += 3;
+ }
+
+ /* Otherwise, after lower_bound number of succeeds, jump
+ to after the jump_n which will be inserted at the end
+ of the buffer, and insert that jump_n. */
+ else
+ { /* Set to 5 if only one repetition is allowed and
+ hence no jump_n is inserted at the current end of
+ the buffer; then only space for the succeed_n is
+ needed. Otherwise, need space for both the
+ succeed_n and the jump_n. */
+
+ unsigned slots_needed = upper_bound == 1 ? 5 : 10;
+
+ GET_BUFFER_SPACE ((int) slots_needed);
+ /* Initialize the succeed_n to n, even though it will
+ be set by its attendant set_number_at, because
+ re_compile_fastmap will need to know it. Jump to
+ what the end of buffer will be after inserting
+ this succeed_n and possibly appending a jump_n. */
+ insert_jump_n (succeed_n, laststart, b + slots_needed,
+ b, lower_bound);
+ b += 5; /* Just increment for the succeed_n here. */
+
+ /* More than one repetition is allowed, so put in at
+ the end of the buffer a backward jump from b to the
+ succeed_n we put in above. By the time we've gotten
+ to this jump when matching, we'll have matched once
+ already, so jump back only upper_bound - 1 times. */
+
+ if (upper_bound > 1)
+ {
+ store_jump_n (b, jump_n, laststart, upper_bound - 1);
+ b += 5;
+ /* When hit this when matching, reset the
+ preceding jump_n's n to upper_bound - 1. */
+ BUFPUSH (set_number_at);
+ GET_BUFFER_SPACE (2);
+ STORE_NUMBER_AND_INCR (b, -5);
+ STORE_NUMBER_AND_INCR (b, upper_bound - 1);
+ }
+ /* When hit this when matching, set the succeed_n's n. */
+ GET_BUFFER_SPACE (5);
+ insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
+ b += 5;
+ }
+ pending_exact = 0;
+ beg_interval = 0;
+ break;
+
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ if (beg_interval)
+ p = beg_interval;
+ else
+ {
+ fprintf (stderr,
+ "regex: no interval beginning to which to backtrack.\n");
+ exit (1);
+ }
+
+ beg_interval = 0;
+ PATFETCH (c); /* normal_char expects char in `c'. */
+ goto normal_char;
+ break;
+
+#ifdef emacs
+ case '=':
+ BUFPUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ BUFPUSH (syntaxspec);
+ PATFETCH (c);
+ BUFPUSH (syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ BUFPUSH (notsyntaxspec);
+ PATFETCH (c);
+ BUFPUSH (syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+ case 'w':
+ laststart = b;
+ BUFPUSH (wordchar);
+ break;
+
+ case 'W':
+ laststart = b;
+ BUFPUSH (notwordchar);
+ break;
+
+ case '<':
+ BUFPUSH (wordbeg);
+ break;
+
+ case '>':
+ BUFPUSH (wordend);
+ break;
+
+ case 'b':
+ BUFPUSH (wordbound);
+ break;
+
+ case 'B':
+ BUFPUSH (notwordbound);
+ break;
+
+ case '`':
+ BUFPUSH (begbuf);
+ break;
+
+ case '\'':
+ BUFPUSH (endbuf);
+ break;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (obscure_syntax & RE_NO_BK_REFS)
+ goto normal_char;
+ c1 = c - '0';
+ if (c1 >= regnum)
+ {
+ if (obscure_syntax & RE_NO_EMPTY_BK_REF)
+ goto invalid_pattern;
+ else
+ goto normal_char;
+ }
+ /* Can't back reference to a subexpression if inside of it. */
+ for (stackt = stackp - 2; stackt > stackb; stackt -= 4)
+ if (*stackt == c1)
+ goto normal_char;
+ laststart = b;
+ BUFPUSH (duplicate);
+ BUFPUSH (c1);
+ break;
+
+ case '+':
+ case '?':
+ if (obscure_syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backsl;
+ break;
+
+ default:
+ normal_backsl:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ if (translate) c = translate[c];
+ goto normal_char;
+ }
+ break;
+
+ default:
+ normal_char: /* Expects the character in `c'. */
+ if (!pending_exact || pending_exact + *pending_exact + 1 != b
+ || *pending_exact == 0177 || *p == '*' || *p == '^'
+ || ((obscure_syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((obscure_syntax & RE_INTERVALS)
+ && ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ laststart = b;
+ BUFPUSH (exactn);
+ pending_exact = b;
+ BUFPUSH (0);
+ }
+ BUFPUSH (c);
+ (*pending_exact)++;
+ }
+ }
+
+ if (fixup_jump)
+ store_jump (fixup_jump, jump, b);
+
+ if (stackp != stackb) goto unmatched_open;
+
+ bufp->used = b - bufp->buffer;
+ return 0;
+
+ invalid_pattern:
+ return "Invalid regular expression";
+
+ unmatched_open:
+ return "Unmatched \\(";
+
+ unmatched_close:
+ return "Unmatched \\)";
+
+ end_of_pattern:
+ return "Premature end of regular expression";
+
+ nesting_too_deep:
+ return "Nesting too deep";
+
+ too_big:
+ return "Regular expression too big";
+
+ memory_exhausted:
+ return "Memory exhausted";
+}
+
+
+/* Store a jump of the form <OPCODE> <relative address>.
+ Store in the location FROM a jump operation to jump to relative
+ address FROM - TO. OPCODE is the opcode to store. */
+
+static void
+store_jump (char *from, char opcode, char *to)
+{
+ from[0] = opcode;
+ STORE_NUMBER(from + 1, to - (from + 3));
+}
+
+
+/* Open up space before char FROM, and insert there a jump to TO.
+ CURRENT_END gives the end of the storage not in use, so we know
+ how much data to copy up. OP is the opcode of the jump to insert.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+insert_jump (char op, char *from, char *to, char *current_end)
+{
+ register char *pfrom = current_end; /* Copy from here... */
+ register char *pto = current_end + 3; /* ...to here. */
+
+ while (pfrom != from)
+ *--pto = *--pfrom;
+ store_jump (from, op, to);
+}
+
+
+/* Store a jump of the form <opcode> <relative address> <n> .
+
+ Store in the location FROM a jump operation to jump to relative
+ address FROM - TO. OPCODE is the opcode to store, N is a number the
+ jump uses, say, to decide how many times to jump.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+store_jump_n (char *from, char opcode, char *to, unsigned n)
+{
+ from[0] = opcode;
+ STORE_NUMBER (from + 1, to - (from + 3));
+ STORE_NUMBER (from + 3, n);
+}
+
+
+/* Similar to insert_jump, but handles a jump which needs an extra
+ number to handle minimum and maximum cases. Open up space at
+ location FROM, and insert there a jump to TO. CURRENT_END gives the
+ end of the storage in use, so we know how much data to copy up. OP is
+ the opcode of the jump to insert.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+insert_jump_n (char op, char *from, char *to, char *current_end, unsigned n)
+{
+ register char *pfrom = current_end; /* Copy from here... */
+ register char *pto = current_end + 5; /* ...to here. */
+
+ while (pfrom != from)
+ *--pto = *--pfrom;
+ store_jump_n (from, op, to, n);
+}
+
+
+/* Open up space at location THERE, and insert operation OP followed by
+ NUM_1 and NUM_2. CURRENT_END gives the end of the storage in use, so
+ we know how much data to copy up.
+
+ If you call this function, you must zero out pending_exact. */
+
+static void
+insert_op_2 (char op, char *there, char *current_end, int num_1, int num_2)
+{
+ register char *pfrom = current_end; /* Copy from here... */
+ register char *pto = current_end + 5; /* ...to here. */
+
+ while (pfrom != there)
+ *--pto = *--pfrom;
+
+ there[0] = op;
+ STORE_NUMBER (there + 1, num_1);
+ STORE_NUMBER (there + 3, num_2);
+}
+
+
+
+/* Given a pattern, compute a fastmap from it. The fastmap records
+ which of the (1 << BYTEWIDTH) possible characters can start a string
+ that matches the pattern. This fastmap is used by re_search to skip
+ quickly over totally implausible text.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as bufp->fastmap.
+ The other components of bufp describe the pattern to be used. */
+
+void
+re_compile_fastmap (struct re_pattern_buffer *bufp)
+{
+ unsigned char *pattern = (unsigned char *) bufp->buffer;
+ int size = bufp->used;
+ register char *fastmap = bufp->fastmap;
+ register unsigned char *p = pattern;
+ register unsigned char *pend = pattern + size;
+ register int j, k;
+ unsigned char *translate = (unsigned char *) bufp->translate;
+
+ unsigned char *stackb[NFAILURES];
+ unsigned char **stackp = stackb;
+
+ unsigned is_a_succeed_n;
+
+ memset (fastmap, 0, (1 << BYTEWIDTH));
+ bufp->fastmap_accurate = 1;
+ bufp->can_be_null = 0;
+
+ while (p)
+ {
+ is_a_succeed_n = 0;
+ if (p == pend)
+ {
+ bufp->can_be_null = 1;
+ break;
+ }
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((enum regexpcode) *p++))
+#else
+ switch ((enum regexpcode) *p++)
+#endif
+ {
+ case exactn:
+ if (translate)
+ fastmap[translate[p[1]]] = 1;
+ else
+ fastmap[p[1]] = 1;
+ break;
+
+ case unused:
+ case begline:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ continue;
+
+ case endline:
+ if (translate)
+ fastmap[translate['\n']] = 1;
+ else
+ fastmap['\n'] = 1;
+
+ if (bufp->can_be_null != 1)
+ bufp->can_be_null = 2;
+ break;
+
+ case jump_n:
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+ /* Jump backward reached implies we just went through
+ the body of a loop and matched nothing.
+ Opcode jumped to should be an on_failure_jump.
+ Just treat it like an ordinary jump.
+ For a * loop, it has pushed its failure point already;
+ If so, discard that as redundant. */
+
+ if ((enum regexpcode) *p != on_failure_jump
+ && (enum regexpcode) *p != succeed_n)
+ continue;
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (stackp != stackb && *stackp == p)
+ stackp--;
+ continue;
+
+ case on_failure_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ *++stackp = p + j;
+ if (is_a_succeed_n)
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ continue;
+
+ case succeed_n:
+ is_a_succeed_n = 1;
+ /* Get to the number of times to succeed. */
+ p += 2;
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+ case start_memory:
+ case stop_memory:
+ p++;
+ continue;
+
+ case duplicate:
+ bufp->can_be_null = 1;
+ fastmap['\n'] = 1;
+ case anychar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (j != '\n')
+ fastmap[j] = 1;
+ if (bufp->can_be_null)
+ return;
+ /* Don't return; check the alternative paths
+ so we can set can_be_null if appropriate. */
+ break;
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+#endif /* not emacs */
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ {
+ if (translate)
+ fastmap[translate[j]] = 1;
+ else
+ fastmap[j] = 1;
+ }
+ break;
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ if (translate)
+ fastmap[translate[j]] = 1;
+ else
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ {
+ if (translate)
+ fastmap[translate[j]] = 1;
+ else
+ fastmap[j] = 1;
+ }
+ break;
+ }
+
+ /* Get here means we have successfully found the possible starting
+ characters of one path of the pattern. We need not follow this
+ path any farther. Instead, look at the next alternative
+ remembered in the stack. */
+ if (stackp != stackb)
+ p = *stackp--;
+ else
+ break;
+ }
+}
+
+
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (struct re_pattern_buffer *pbufp,
+ char *string,
+ int size,
+ int startpos,
+ int range,
+ struct re_registers *regs)
+{
+ return re_search_2 (pbufp, (char *) 0, 0, string, size, startpos, range,
+ regs, size);
+}
+
+
+/* Using the compiled pattern in PBUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on. RANGE is the number of
+ places to try before giving up. If RANGE is negative, it searches
+ backwards, i.e., the starting positions tried are STARTPOS, STARTPOS
+ - 1, etc. STRING1 and STRING2 are of SIZE1 and SIZE2, respectively.
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire PBUFP->buffer and its contained
+ subexpressions. Do not consider matching one past the index MSTOP in
+ the virtual concatenation of STRING1 and STRING2.
+
+ The value returned is the position in the strings at which the match
+ was found, or -1 if no match was found, or -2 if error (such as
+ failure stack overflow). */
+
+int
+re_search_2 (struct re_pattern_buffer *pbufp,
+ char *string1, int size1,
+ char *string2, int size2,
+ int startpos,
+ register int range,
+ struct re_registers *regs,
+ int mstop)
+{
+ register char *fastmap = pbufp->fastmap;
+ register unsigned char *translate = (unsigned char *) pbufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+ int val;
+
+ /* Check for out-of-range starting position. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up range if it would eventually take startpos outside of the
+ virtual concatenation of string1 and string2. */
+ if (endpos < -1)
+ range = -1 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !pbufp->fastmap_accurate)
+ re_compile_fastmap (pbufp);
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ long search for a pattern that says it is anchored. */
+ if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
+ && range > 0)
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+ while (1)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot possibly be the start of a match. Note, however, that
+ if the pattern can possibly match the null string, we must
+ test it at each starting point so that we take the first null
+ string we get. */
+
+ if (fastmap && startpos < total_size && pbufp->can_be_null != 1)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register int lim = 0;
+ register unsigned char *p;
+ int irange = range;
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ p = ((unsigned char *)
+ &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
+
+ while (range > lim && !fastmap[translate
+ ? translate[*p++]
+ : *p++])
+ range--;
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register unsigned char c;
+
+ if (string1 == 0 || startpos >= size1)
+ c = string2[startpos - size1];
+ else
+ c = string1[startpos];
+
+ c &= 0xff;
+ if (translate ? !fastmap[translate[c]] : !fastmap[c])
+ goto advance;
+ }
+ }
+
+ if (range >= 0 && startpos == total_size
+ && fastmap && pbufp->can_be_null == 0)
+ return -1;
+
+ val = re_match_2 (pbufp, string1, size1, string2, size2, startpos,
+ regs, mstop);
+ if (val >= 0)
+ return startpos;
+ if (val == -2)
+ return -2;
+
+#ifdef C_ALLOCA
+ alloca (0);
+#endif /* C_ALLOCA */
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+}
+
+
+
+#ifndef emacs /* emacs never uses this. */
+int
+re_match (struct re_pattern_buffer *pbufp,
+ char *string,
+ int size,
+ int pos,
+ struct re_registers *regs)
+{
+ return re_match_2 (pbufp, (char *) 0, 0, string, size, pos, regs, size);
+}
+#endif /* not emacs */
+
+
+/* The following are used for re_match_2, defined below: */
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always pushed MAX_NUM_FAILURE_ITEMS each time we failed. */
+
+int re_max_failures = 2000;
+
+/* Routine used by re_match_2. */
+static int bcmp_translate (char *, char *, int, unsigned char *);
+
+
+/* Structure and accessing macros used in re_match_2: */
+
+struct register_info
+{
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+};
+
+#define IS_ACTIVE(R) ((R).is_active)
+#define MATCHED_SOMETHING(R) ((R).matched_something)
+
+
+/* Macros used by re_match_2: */
+
+
+/* I.e., regstart, regend, and reg_info. */
+
+#define NUM_REG_ITEMS 3
+
+/* We push at most this many things on the stack whenever we
+ fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are
+ arguments to the PUSH_FAILURE_POINT macro. */
+
+#define MAX_NUM_FAILURE_ITEMS (RE_NREGS * NUM_REG_ITEMS + 2)
+
+
+/* We push this many things on the stack whenever we fail. */
+
+#define NUM_FAILURE_ITEMS (last_used_reg * NUM_REG_ITEMS + 2)
+
+
+/* This pushes most of the information about the current state we will want
+ if we ever fail back to it. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place) \
+ { \
+ short last_used_reg, this_reg; \
+ \
+ /* Find out how many registers are active or have been matched. \
+ (Aside from register zero, which is only set at the end.) */ \
+ for (last_used_reg = RE_NREGS - 1; last_used_reg > 0; last_used_reg--)\
+ if (regstart[last_used_reg] != (unsigned char *) -1) \
+ break; \
+ \
+ if (stacke - stackp < NUM_FAILURE_ITEMS) \
+ { \
+ unsigned char **stackx; \
+ int len = stacke - stackb; \
+ if (len > re_max_failures * MAX_NUM_FAILURE_ITEMS) \
+ return -2; \
+ \
+ /* Roughly double the size of the stack. */ \
+ stackx = (unsigned char **) alloca (2 * len \
+ * sizeof (unsigned char *));\
+ /* Only copy what is in use. */ \
+ memcpy (stackx, stackb, len * sizeof (char *)); \
+ stackp = stackx + (stackp - stackb); \
+ stackb = stackx; \
+ stacke = stackb + 2 * len; \
+ } \
+ \
+ /* Now push the info for each of those registers. */ \
+ for (this_reg = 1; this_reg <= last_used_reg; this_reg++) \
+ { \
+ *stackp++ = regstart[this_reg]; \
+ *stackp++ = regend[this_reg]; \
+ *stackp++ = (unsigned char *) &reg_info[this_reg]; \
+ } \
+ \
+ /* Push how many registers we saved. */ \
+ *stackp++ = (unsigned char *) last_used_reg; \
+ \
+ *stackp++ = pattern_place; \
+ *stackp++ = string_place; \
+ }
+
+
+/* This pops what PUSH_FAILURE_POINT pushes. */
+
+#define POP_FAILURE_POINT() \
+ { \
+ int temp; \
+ stackp -= 2; /* Remove failure points. */ \
+ temp = (int) *--stackp; /* How many regs pushed. */ \
+ temp *= NUM_REG_ITEMS; /* How much to take off the stack. */ \
+ stackp -= temp; /* Remove the register info. */ \
+ }
+
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Is true if there is a first string and if PTR is pointing anywhere
+ inside it or just past the end. */
+
+#define IS_IN_FIRST_STRING(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+
+#define PREFETCH \
+ while (d == dend) \
+ { \
+ /* end of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* end of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Call this when have matched something; it sets `matched' flags for the
+ registers corresponding to the subexpressions of which we currently
+ are inside. */
+#define SET_REGS_MATCHED \
+ { unsigned this_reg; \
+ for (this_reg = 0; this_reg < RE_NREGS; this_reg++) \
+ { \
+ if (IS_ACTIVE(reg_info[this_reg])) \
+ MATCHED_SOMETHING(reg_info[this_reg]) = 1; \
+ else \
+ MATCHED_SOMETHING(reg_info[this_reg]) = 0; \
+ } \
+ }
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of string1 and string2. If there is only one string, we've put it in
+ string2. */
+
+#define AT_STRINGS_BEG (d == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END (d == end2)
+
+#define AT_WORD_BOUNDARY \
+ (AT_STRINGS_BEG || AT_STRINGS_END || IS_A_LETTER (d - 1) != IS_A_LETTER (d))
+
+/* We have two special cases to check for:
+ 1) if we're past the end of string1, we have to look at the first
+ character in string2;
+ 2) if we're before the beginning of string2, we have to look at the
+ last character in string1; we assume there is a string1, so use
+ this in conjunction with AT_STRINGS_BEG. */
+#define IS_A_LETTER(d) \
+ (SYNTAX ((d) == end1 ? *string2 : (d) == string2 - 1 ? *(end1 - 1) : *(d))\
+ == Sword)
+
+
+/* Match the pattern described by PBUFP against the virtual
+ concatenation of STRING1 and STRING2, which are of SIZE1 and SIZE2,
+ respectively. Start the match at index POS in the virtual
+ concatenation of STRING1 and STRING2. In REGS, return the indices of
+ the virtual concatenation of STRING1 and STRING2 that matched the
+ entire PBUFP->buffer and its contained subexpressions. Do not
+ consider matching one past the index MSTOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ If pbufp->fastmap is nonzero, then it had better be up to date.
+
+ The reason that the data to match are specified as two components
+ which are to be regarded as concatenated is so this function can be
+ used directly on the contents of an Emacs buffer.
+
+ -1 is returned if there is no match. -2 is returned if there is an
+ error (such as match stack overflow). Otherwise the value is the
+ length of the substring which was matched. */
+
+int
+re_match_2 (struct re_pattern_buffer *pbufp,
+ char *string1_arg, int size1,
+ char *string2_arg, int size2,
+ int pos,
+ struct re_registers *regs,
+ int mstop)
+{
+ register unsigned char *p = (unsigned char *) pbufp->buffer;
+
+ /* Pointer to beyond end of buffer. */
+ register unsigned char *pend = p + pbufp->used;
+
+ unsigned char *string1 = (unsigned char *) string1_arg;
+ unsigned char *string2 = (unsigned char *) string2_arg;
+ unsigned char *end1; /* Just past end of first string. */
+ unsigned char *end2; /* Just past end of second string. */
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ unsigned char *end_match_1, *end_match_2;
+
+ register unsigned char *d, *dend;
+ register int mcnt; /* Multipurpose. */
+ unsigned char *translate = (unsigned char *) pbufp->translate;
+ unsigned is_a_jump_n = 0;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to the
+ subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where to
+ resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is a
+ ``dummy''; if a failure happens and the failure point is a dummy, it
+ gets discarded and the next next one is tried. */
+
+ unsigned char *initial_stack[MAX_NUM_FAILURE_ITEMS * NFAILURES];
+ unsigned char **stackb = initial_stack;
+ unsigned char **stackp = stackb;
+ unsigned char **stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES];
+
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+
+ unsigned char *regstart[RE_NREGS];
+ unsigned char *regend[RE_NREGS];
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+
+ struct register_info reg_info[RE_NREGS];
+
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+
+ unsigned best_regs_set = 0;
+ unsigned char *best_regstart[RE_NREGS];
+ unsigned char *best_regend[RE_NREGS];
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ \( or ( and \) or ) has been seen for. Also set all registers to
+ inactive and mark them as not having matched anything or ever
+ failed. */
+ for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt] = (unsigned char *) -1;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ if (regs)
+ for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+
+ /* Set up pointers to ends of strings.
+ Don't allow the second string to be empty unless both are empty. */
+ if (size2 == 0)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (mstop <= size1)
+ {
+ end_match_1 = string1 + mstop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + mstop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data. `dend'
+ is the end of the input string that `d' points within. `d' is
+ advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal string2. */
+
+ if (size1 != 0 && pos <= size1)
+ d = string1 + pos, dend = end_match_1;
+ else
+ d = string2 + pos - size1, dend = end_match_2;
+
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if match is complete, or it drops through if match fails
+ at this starting point in the input data. */
+
+ while (1)
+ {
+ is_a_jump_n = 0;
+ /* End of pattern means we might have succeeded. */
+ if (p == pend)
+ {
+ /* If not end of string, try backtracking. Otherwise done. */
+ if (d != end_match_2)
+ {
+ if (stackp != stackb)
+ {
+ /* More failure points to try. */
+
+ unsigned in_same_string =
+ IS_IN_FIRST_STRING (best_regend[0])
+ == MATCHING_IN_FIRST_STRING;
+
+ /* If exceeds best match so far, save it. */
+ if (! best_regs_set
+ || (in_same_string && d > best_regend[0])
+ || (! in_same_string && ! MATCHING_IN_FIRST_STRING))
+ {
+ best_regs_set = 1;
+ best_regend[0] = d; /* Never use regstart[0]. */
+
+ for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+ /* If no failure points, don't restore garbage. */
+ else if (best_regs_set)
+ {
+ restore_best_regs:
+ /* Restore best match. */
+ d = best_regend[0];
+
+ for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ }
+
+ /* If caller wants register contents data back, convert it
+ to indices. */
+ if (regs)
+ {
+ regs->start[0] = pos;
+ if (MATCHING_IN_FIRST_STRING)
+ regs->end[0] = d - string1;
+ else
+ regs->end[0] = d - string2 + size1;
+ for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
+ {
+ if (regend[mcnt] == (unsigned char *) -1)
+ {
+ regs->start[mcnt] = -1;
+ regs->end[mcnt] = -1;
+ continue;
+ }
+ if (IS_IN_FIRST_STRING (regstart[mcnt]))
+ regs->start[mcnt] = regstart[mcnt] - string1;
+ else
+ regs->start[mcnt] = regstart[mcnt] - string2 + size1;
+
+ if (IS_IN_FIRST_STRING (regend[mcnt]))
+ regs->end[mcnt] = regend[mcnt] - string1;
+ else
+ regs->end[mcnt] = regend[mcnt] - string2 + size1;
+ }
+ }
+ return d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+ }
+
+ /* Otherwise match next pattern command. */
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((enum regexpcode) *p++))
+#else
+ switch ((enum regexpcode) *p++)
+#endif
+ {
+
+ /* \( [or `(', as appropriate] is represented by start_memory,
+ \) by stop_memory. Both of those commands are followed by
+ a register number in the next byte. The text matched
+ within the \( and \) is recorded under that number. */
+ case start_memory:
+ regstart[*p] = d;
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+ p++;
+ break;
+
+ case stop_memory:
+ regend[*p] = d;
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* If just failed to match something this time around with a sub-
+ expression that's in a loop, try to force exit from the loop. */
+ if ((! MATCHED_SOMETHING (reg_info[*p])
+ || (enum regexpcode) p[-3] == start_memory)
+ && (p + 1) != pend)
+ {
+ register unsigned char *p2 = p + 1;
+ mcnt = 0;
+ switch (*p2++)
+ {
+ case jump_n:
+ is_a_jump_n = 1;
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p2);
+ if (is_a_jump_n)
+ p2 += 2;
+ break;
+ }
+ p2 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump, exit from the loop by forcing a
+ failure after pushing on the stack the on_failure_jump's
+ jump in the pattern, and d. */
+ if (mcnt < 0 && (enum regexpcode) *p2++ == on_failure_jump)
+ {
+ EXTRACT_NUMBER_AND_INCR (mcnt, p2);
+ PUSH_FAILURE_POINT (p2 + mcnt, d);
+ goto fail;
+ }
+ }
+ p++;
+ break;
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ int regno = *p++; /* Get which register to match against */
+ register unsigned char *d2, *dend2;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((IS_IN_FIRST_STRING (regstart[regno])
+ == IS_IN_FIRST_STRING (regend[regno]))
+ ? regend[regno] : end_match_1);
+ while (1)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+ d2 = string2, dend2 = regend[regno]; /* end of string1 => advance to string2. */
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH;
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate ((char*)d, (char*)d2, mcnt, translate)
+ : memcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+ }
+ }
+ break;
+
+ case anychar:
+ PREFETCH; /* Fetch a data character. */
+ /* Match anything but a newline, maybe even a null. */
+ if ((translate ? translate[*d] : *d) == '\n'
+ || ((obscure_syntax & RE_DOT_NOT_NULL)
+ && (translate ? translate[*d] : *d) == '\000'))
+ goto fail;
+ SET_REGS_MATCHED;
+ d++;
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ int not = 0; /* Nonzero for charset_not. */
+ register int c;
+ if (*(p - 1) == (unsigned char) charset_not)
+ not = 1;
+
+ PREFETCH; /* Fetch a data character. */
+
+ if (translate)
+ c = translate[*d];
+ else
+ c = *d;
+
+ if (c < *p * BYTEWIDTH
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+ SET_REGS_MATCHED;
+ d++;
+ break;
+ }
+
+ case begline:
+ if ((size1 != 0 && d == string1)
+ || (size1 == 0 && size2 != 0 && d == string2)
+ || (d && d[-1] == '\n')
+ || (size1 == 0 && size2 == 0))
+ break;
+ else
+ goto fail;
+
+ case endline:
+ if (d == end2
+ || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
+ break;
+ goto fail;
+
+ /* `or' constructs are handled by starting each alternative with
+ an on_failure_jump that points to the start of the next
+ alternative. Each alternative except the last ends with a
+ jump to the joining point. (Actually, each jump except for
+ the last one really jumps to the following jump, because
+ tensioning the jumps is a hassle.) */
+
+ /* The start of a stupid repeat has an on_failure_jump that points
+ past the end of the repeat text. This makes a failure point so
+ that on failure to match a repetition, matching restarts past
+ as many repetitions have been found with no way to fail and
+ look for another one. */
+
+ /* A smart repeat is similar but loops back to the on_failure_jump
+ so that each repetition makes another failure point. */
+
+ case on_failure_jump:
+ on_failure:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ PUSH_FAILURE_POINT (p + mcnt, d);
+ break;
+
+ /* The end of a smart repeat has a maybe_finalize_jump back.
+ Change it either to a finalize_jump or an ordinary jump. */
+ case maybe_finalize_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ {
+ register unsigned char *p2 = p;
+ /* Compare what follows with the beginning of the repeat.
+ If we can establish that there is nothing that they would
+ both match, we can change to finalize_jump. */
+ while (p2 + 1 != pend
+ && (*p2 == (unsigned char) stop_memory
+ || *p2 == (unsigned char) start_memory))
+ p2 += 2; /* Skip over reg number. */
+ if (p2 == pend)
+ p[-3] = (unsigned char) finalize_jump;
+ else if (*p2 == (unsigned char) exactn
+ || *p2 == (unsigned char) endline)
+ {
+ register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
+ register unsigned char *p1 = p + mcnt;
+ /* p1[0] ... p1[2] are an on_failure_jump.
+ Examine what follows that. */
+ if (p1[3] == (unsigned char) exactn && p1[5] != c)
+ p[-3] = (unsigned char) finalize_jump;
+ else if (p1[3] == (unsigned char) charset
+ || p1[3] == (unsigned char) charset_not)
+ {
+ int not = p1[3] == (unsigned char) charset_not;
+ if (c < p1[4] * BYTEWIDTH
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+ /* `not' is 1 if c would match. */
+ /* That means it is not safe to finalize. */
+ if (!not)
+ p[-3] = (unsigned char) finalize_jump;
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if (p[-1] != (unsigned char) finalize_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ goto nofinalize;
+ }
+ /* Note fall through. */
+
+ /* The end of a stupid repeat has a finalize_jump back to the
+ start, where another failure point will be made which will
+ point to after all the repetitions found so far. */
+
+ /* Take off failure points put on by matching on_failure_jump
+ because didn't fail. Also remove the register information
+ put on by the on_failure_jump. */
+ case finalize_jump:
+ POP_FAILURE_POINT ();
+ /* Note fall through. */
+
+ /* Jump without taking off any failure points. */
+ case jump:
+ nofinalize:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p += mcnt;
+ break;
+
+ case dummy_failure_jump:
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at finalize_jump. We will end up at
+ finalize_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for finalize_jump to pop. */
+ PUSH_FAILURE_POINT (0, 0);
+ goto nofinalize;
+
+
+ /* Have to succeed matching what follows at least n times. Then
+ just handle like an on_failure_jump. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ }
+ else if (mcnt == 0)
+ {
+ p[2] = unused;
+ p[3] = unused;
+ goto on_failure;
+ }
+ else
+ {
+ fprintf (stderr, "regex: the succeed_n's n is not set.\n");
+ exit (1);
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER(p + 2, mcnt);
+ goto nofinalize; /* Do the jump without taking off
+ any failure points. */
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ register unsigned char *p1;
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case unused:
+ break;
+
+ case wordbound:
+ if (AT_WORD_BOUNDARY)
+ break;
+ goto fail;
+
+ case notwordbound:
+ if (AT_WORD_BOUNDARY)
+ goto fail;
+ break;
+
+ case wordbeg:
+ /* Have to check if AT_STRINGS_BEG before looking at d - 1. */
+ if (IS_A_LETTER (d) && (AT_STRINGS_BEG || !IS_A_LETTER (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ /* Have to check if AT_STRINGS_BEG before looking at d - 1. */
+ if (!AT_STRINGS_BEG && IS_A_LETTER (d - 1)
+ && (!IS_A_LETTER (d) || AT_STRINGS_END))
+ break;
+ goto fail;
+
+#ifdef emacs
+ case before_dot:
+ if (PTR_CHAR_POS (d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ if (PTR_CHAR_POS (d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ if (PTR_CHAR_POS (d) <= point)
+ goto fail;
+ break;
+
+ case wordchar:
+ mcnt = (int) Sword;
+ goto matchsyntax;
+
+ case syntaxspec:
+ mcnt = *p++;
+ matchsyntax:
+ PREFETCH;
+ if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+ case notwordchar:
+ mcnt = (int) Sword;
+ goto matchnotsyntax;
+
+ case notsyntaxspec:
+ mcnt = *p++;
+ matchnotsyntax:
+ PREFETCH;
+ if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+#else /* not emacs */
+
+ case wordchar:
+ PREFETCH;
+ if (!IS_A_LETTER (d))
+ goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+ case notwordchar:
+ PREFETCH;
+ if (IS_A_LETTER (d))
+ goto fail;
+ SET_REGS_MATCHED;
+ break;
+
+#endif /* not emacs */
+
+ case begbuf:
+ if (AT_STRINGS_BEG)
+ break;
+ goto fail;
+
+ case endbuf:
+ if (AT_STRINGS_END)
+ break;
+ goto fail;
+
+ case exactn:
+ /* Match the next few pattern characters exactly.
+ mcnt is how many characters to match. */
+ mcnt = *p++;
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH;
+ if (translate[*d++] != *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH;
+ if (*d++ != *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED;
+ break;
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+ /* Jump here if any matching operation fails. */
+ fail:
+ if (stackp != stackb)
+ /* A restart point is known. Restart there and pop it. */
+ {
+ short last_used_reg, this_reg;
+
+ /* If this failure point is from a dummy_failure_point, just
+ skip it. */
+ if (!stackp[-2])
+ {
+ POP_FAILURE_POINT ();
+ goto fail;
+ }
+
+ d = *--stackp;
+ p = *--stackp;
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ /* Restore register info. */
+ last_used_reg = (short) (int) *--stackp;
+
+ /* Make the ones that weren't saved -1 or 0 again. */
+ for (this_reg = RE_NREGS - 1; this_reg > last_used_reg; this_reg--)
+ {
+ regend[this_reg] = (unsigned char *) -1;
+ regstart[this_reg] = (unsigned char *) -1;
+ IS_ACTIVE (reg_info[this_reg]) = 0;
+ MATCHED_SOMETHING (reg_info[this_reg]) = 0;
+ }
+
+ /* And restore the rest from the stack. */
+ for ( ; this_reg > 0; this_reg--)
+ {
+ reg_info[this_reg] = *(struct register_info *) *--stackp;
+ regend[this_reg] = *--stackp;
+ regstart[this_reg] = *--stackp;
+ }
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ }
+
+ if (best_regs_set)
+ goto restore_best_regs;
+ return -1; /* Failure to match. */
+}
+
+
+static int
+bcmp_translate (char *s1, char *s2, int len, unsigned char *translate)
+{
+ register unsigned char *p1 = (unsigned char*)s1;
+ register unsigned char *p2 = (unsigned char*)s2;
+ while (len)
+ {
+ if (translate [*p1++] != translate [*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+
+
+/* Entry points compatible with 4.2 BSD regex library. */
+
+#if 0
+
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (char *s)
+{
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return "No previous regular expression";
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ if (!(re_comp_buf.buffer = (char *) malloc (200)))
+ return "Memory exhausted";
+ re_comp_buf.allocated = 200;
+ if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
+ return "Memory exhausted";
+ }
+ return re_compile_pattern (s, strlen (s), &re_comp_buf);
+}
+
+int
+re_exec (char *s)
+{
+ int len = strlen (s);
+ return 0 <= re_search (&re_comp_buf, s, len, 0, len,
+ (struct re_registers *) 0);
+}
+#endif /* not emacs */
+
+
+
+#ifdef test
+
+#include <stdio.h>
+
+/* Indexed by a character, gives the upper case equivalent of the
+ character. */
+
+char upcase[0400] =
+ { 000, 001, 002, 003, 004, 005, 006, 007,
+ 010, 011, 012, 013, 014, 015, 016, 017,
+ 020, 021, 022, 023, 024, 025, 026, 027,
+ 030, 031, 032, 033, 034, 035, 036, 037,
+ 040, 041, 042, 043, 044, 045, 046, 047,
+ 050, 051, 052, 053, 054, 055, 056, 057,
+ 060, 061, 062, 063, 064, 065, 066, 067,
+ 070, 071, 072, 073, 074, 075, 076, 077,
+ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+ 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+ };
+
+#ifdef canned
+
+#include "tests.h"
+
+typedef enum { extended_test, basic_test } test_type;
+
+/* Use this to run the tests we've thought of. */
+
+void
+main ()
+{
+ test_type t = extended_test;
+
+ if (t == basic_test)
+ {
+ printf ("Running basic tests:\n\n");
+ test_posix_basic ();
+ }
+ else if (t == extended_test)
+ {
+ printf ("Running extended tests:\n\n");
+ test_posix_extended ();
+ }
+}
+
+#else /* not canned */
+
+/* Use this to run interactive tests. */
+
+void
+main (int argc, char **argv)
+{
+ char pat[80];
+ struct re_pattern_buffer buf;
+ int i;
+ char c;
+ char fastmap[(1 << BYTEWIDTH)];
+
+ /* Allow a command argument to specify the style of syntax. */
+ if (argc > 1)
+ obscure_syntax = atoi (argv[1]);
+
+ buf.allocated = 40;
+ buf.buffer = (char *) malloc (buf.allocated);
+ buf.fastmap = fastmap;
+ buf.translate = upcase;
+
+ while (1)
+ {
+ gets (pat);
+
+ if (*pat)
+ {
+ re_compile_pattern (pat, strlen(pat), &buf);
+
+ for (i = 0; i < buf.used; i++)
+ printchar (buf.buffer[i]);
+
+ putchar ('\n');
+
+ printf ("%d allocated, %d used.\n", buf.allocated, buf.used);
+
+ re_compile_fastmap (&buf);
+ printf ("Allowed by fastmap: ");
+ for (i = 0; i < (1 << BYTEWIDTH); i++)
+ if (fastmap[i]) printchar (i);
+ putchar ('\n');
+ }
+
+ gets (pat); /* Now read the string to match against */
+
+ i = re_match (&buf, pat, strlen (pat), 0, 0);
+ printf ("Match value %d.\n", i);
+ }
+}
+
+#endif
+
+
+#ifdef NOTDEF
+void
+print_buf (struct re_pattern_buffer *bufpbufp)
+{
+ int i;
+
+ printf ("buf is :\n----------------\n");
+ for (i = 0; i < bufp->used; i++)
+ printchar (bufp->buffer[i]);
+
+ printf ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
+
+ printf ("Allowed by fastmap: ");
+ for (i = 0; i < (1 << BYTEWIDTH); i++)
+ if (bufp->fastmap[i])
+ printchar (i);
+ printf ("\nAllowed by translate: ");
+ if (bufp->translate)
+ for (i = 0; i < (1 << BYTEWIDTH); i++)
+ if (bufp->translate[i])
+ printchar (i);
+ printf ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
+ printf ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
+}
+#endif /* NOTDEF */
+
+void
+printchar (char c)
+{
+ if (c < 040 || c >= 0177)
+ {
+ putchar ('\\');
+ putchar (((c >> 6) & 3) + '0');
+ putchar (((c >> 3) & 7) + '0');
+ putchar ((c & 7) + '0');
+ }
+ else
+ putchar (c);
+}
+
+void
+error (char *string)
+{
+ puts (string);
+ exit (1);
+}
+#endif /* test */
diff --git a/gnu/lib/libg++/g++-include/regex.h b/gnu/lib/libg++/g++-include/regex.h
new file mode 100644
index 00000000000..5561ce7aba7
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/regex.h
@@ -0,0 +1,274 @@
+/* Definitions for data structures callers pass the regex library.
+
+ Copyright (C) 1985, 1989-92 Free Software Foundation, Inc.
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: regex.h,v 1.1 1995/10/18 08:38:19 deraadt Exp $
+*/
+
+#ifndef __REGEXP_LIBRARY
+#define __REGEXP_LIBRARY
+
+#if defined(SHORT_NAMES) || defined(VMS)
+#define re_compile_pattern recmppat
+#define re_pattern_buffer repatbuf
+#define re_registers reregs
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define number of parens for which we record the beginnings and ends.
+ This affects how much space the `struct re_registers' type takes up. */
+#ifndef RE_NREGS
+#define RE_NREGS 10
+#endif
+
+#define BYTEWIDTH 8
+
+
+/* Maximum number of duplicates an interval can allow. */
+#ifndef RE_DUP_MAX /* kludge for AIX, which defines it */
+#define RE_DUP_MAX ((1 << 15) - 1)
+#endif
+
+/* This defines the various regexp syntaxes. */
+extern int obscure_syntax;
+
+
+/* The following bits are used in the obscure_syntax variable to choose among
+ alternative regexp syntaxes. */
+
+/* If this bit is set, plain parentheses serve as grouping, and backslash
+ parentheses are needed for literal searching.
+ If not set, backslash-parentheses are grouping, and plain parentheses
+ are for literal searching. */
+#define RE_NO_BK_PARENS 1
+
+/* If this bit is set, plain | serves as the `or'-operator, and \| is a
+ literal.
+ If not set, \| serves as the `or'-operator, and | is a literal. */
+#define RE_NO_BK_VBAR (1 << 1)
+
+/* If this bit is not set, plain + or ? serves as an operator, and \+, \? are
+ literals.
+ If set, \+, \? are operators and plain +, ? are literals. */
+#define RE_BK_PLUS_QM (1 << 2)
+
+/* If this bit is set, | binds tighter than ^ or $.
+ If not set, the contrary. */
+#define RE_TIGHT_VBAR (1 << 3)
+
+/* If this bit is set, then treat newline as an OR operator.
+ If not set, treat it as a normal character. */
+#define RE_NEWLINE_OR (1 << 4)
+
+/* If this bit is set, then special characters may act as normal
+ characters in some contexts. Specifically, this applies to:
+ ^ -- only special at the beginning, or after ( or |;
+ $ -- only special at the end, or before ) or |;
+ *, +, ? -- only special when not after the beginning, (, or |.
+ If this bit is not set, special characters (such as *, ^, and $)
+ always have their special meaning regardless of the surrounding
+ context. */
+#define RE_CONTEXT_INDEP_OPS (1 << 5)
+
+/* If this bit is not set, then \ before anything inside [ and ] is taken as
+ a real \.
+ If set, then such a \ escapes the following character. This is a
+ special case for awk. */
+#define RE_AWK_CLASS_HACK (1 << 6)
+
+/* If this bit is set, then \{ and \} or { and } serve as interval operators.
+ If not set, then \{ and \} and { and } are treated as literals. */
+#define RE_INTERVALS (1 << 7)
+
+/* If this bit is not set, then \{ and \} serve as interval operators and
+ { and } are literals.
+ If set, then { and } serve as interval operators and \{ and \} are
+ literals. */
+#define RE_NO_BK_CURLY_BRACES (1 << 8)
+
+/* If this bit is set, then character classes are supported; they are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (1 << 9)
+
+/* If this bit is set, then the dot re doesn't match a null byte.
+ If not set, it does. */
+#define RE_DOT_NOT_NULL (1 << 10)
+
+/* If this bit is set, then [^...] doesn't match a newline.
+ If not set, it does. */
+#define RE_HAT_NOT_NEWLINE (1 << 11)
+
+/* If this bit is set, back references are recognized.
+ If not set, they aren't. */
+#define RE_NO_BK_REFS (1 << 12)
+
+/* If this bit is set, back references must refer to a preceding
+ subexpression. If not set, a back reference to a nonexistent
+ subexpression is treated as literal characters. */
+#define RE_NO_EMPTY_BK_REF (1 << 13)
+
+/* If this bit is set, bracket expressions can't be empty.
+ If it is set, they can be empty. */
+#define RE_NO_EMPTY_BRACKETS (1 << 14)
+
+/* If this bit is set, then *, +, ? and { cannot be first in an re or
+ immediately after a |, or a (. Furthermore, a | cannot be first or
+ last in an re, or immediately follow another | or a (. Also, a ^
+ cannot appear in a nonleading position and a $ cannot appear in a
+ nontrailing position (outside of bracket expressions, that is). */
+#define RE_CONTEXTUAL_INVALID_OPS (1 << 15)
+
+/* If this bit is set, then +, ? and | aren't recognized as operators.
+ If it's not, they are. */
+#define RE_LIMITED_OPS (1 << 16)
+
+/* If this bit is set, then an ending range point has to collate higher
+ or equal to the starting range point.
+ If it's not set, then when the ending range point collates higher
+ than the starting range point, the range is just considered empty. */
+#define RE_NO_EMPTY_RANGES (1 << 17)
+
+/* If this bit is set, then a hyphen (-) can't be an ending range point.
+ If it isn't, then it can. */
+#define RE_NO_HYPHEN_RANGE_END (1 << 18)
+
+
+/* Define combinations of bits for the standard possibilities. */
+#define RE_SYNTAX_POSIX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS)
+#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS | RE_AWK_CLASS_HACK)
+#define RE_SYNTAX_EGREP (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS | RE_NEWLINE_OR)
+#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
+#define RE_SYNTAX_EMACS 0
+#define RE_SYNTAX_POSIX_BASIC (RE_INTERVALS | RE_BK_PLUS_QM \
+ | RE_CHAR_CLASSES | RE_DOT_NOT_NULL \
+ | RE_HAT_NOT_NEWLINE | RE_NO_EMPTY_BK_REF \
+ | RE_NO_EMPTY_BRACKETS | RE_LIMITED_OPS \
+ | RE_NO_EMPTY_RANGES | RE_NO_HYPHEN_RANGE_END)
+
+#define RE_SYNTAX_POSIX_EXTENDED (RE_INTERVALS | RE_NO_BK_CURLY_BRACES \
+ | RE_NO_BK_VBAR | RE_NO_BK_PARENS \
+ | RE_HAT_NOT_NEWLINE | RE_CHAR_CLASSES \
+ | RE_NO_EMPTY_BRACKETS | RE_CONTEXTUAL_INVALID_OPS \
+ | RE_NO_BK_REFS | RE_NO_EMPTY_RANGES \
+ | RE_NO_HYPHEN_RANGE_END)
+
+
+/* This data structure is used to represent a compiled pattern. */
+
+struct re_pattern_buffer
+ {
+ char *buffer; /* Space holding the compiled pattern commands. */
+ long allocated; /* Size of space that `buffer' points to. */
+ long used; /* Length of portion of buffer actually occupied */
+ char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
+ /* re_search uses the fastmap, if there is one,
+ to skip over totally implausible characters. */
+ char *translate; /* Translate table to apply to all characters before
+ comparing, or zero for no translation.
+ The translation is applied to a pattern when it is
+ compiled and to data when it is matched. */
+ char fastmap_accurate;
+ /* Set to zero when a new pattern is stored,
+ set to one when the fastmap is updated from it. */
+ char can_be_null; /* Set to one by compiling fastmap
+ if this pattern might match the null string.
+ It does not necessarily match the null string
+ in that case, but if this is zero, it cannot.
+ 2 as value means can match null string
+ but at end of range or before a character
+ listed in the fastmap. */
+ };
+
+
+/* search.c (search_buffer) needs this one value. It is defined both in
+ regex.c and here. */
+#define RE_EXACTN_VALUE 1
+
+
+/* Structure to store register contents data in.
+
+ Pass the address of such a structure as an argument to re_match, etc.,
+ if you want this information back.
+
+ For i from 1 to RE_NREGS - 1, start[i] records the starting index in
+ the string of where the ith subexpression matched, and end[i] records
+ one after the ending index. start[0] and end[0] are analogous, for
+ the entire pattern. */
+
+struct re_registers
+ {
+ int start[RE_NREGS];
+ int end[RE_NREGS];
+ };
+
+
+
+#if defined(__STDC__) || defined(__cplusplus)
+
+extern char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);
+/* Is this really advertised? */
+extern void re_compile_fastmap (struct re_pattern_buffer *);
+extern int re_search (struct re_pattern_buffer *, char*, int, int, int,
+ struct re_registers *);
+extern int re_search_2 (struct re_pattern_buffer *, char *, int,
+ char *, int, int, int,
+ struct re_registers *, int);
+extern int re_match (struct re_pattern_buffer *, char *, int, int,
+ struct re_registers *);
+extern int re_match_2 (struct re_pattern_buffer *, char *, int,
+ char *, int, int, struct re_registers *, int);
+
+#if 0
+/* 4.2 bsd compatibility. */
+extern char *re_comp (char *);
+extern int re_exec (char *);
+#endif
+
+#else /* !__STDC__ */
+
+#define const /* nothing */
+extern char *re_compile_pattern ();
+/* Is this really advertised? */
+extern void re_compile_fastmap ();
+extern int re_search (), re_search_2 ();
+extern int re_match (), re_match_2 ();
+
+#if 0
+/* 4.2 bsd compatibility. */
+extern char *re_comp ();
+extern int re_exec ();
+#endif
+
+#endif /* __STDC__ */
+
+
+#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
+#endif
+
+#ifdef __cplusplus
+extern int re_max_failures;
+}
+#endif
+
+#endif /* !__REGEXP_LIBRARY */
diff --git a/gnu/lib/libg++/g++-include/shlib_version b/gnu/lib/libg++/g++-include/shlib_version
new file mode 100644
index 00000000000..b52599a164f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/shlib_version
@@ -0,0 +1,2 @@
+major=2
+minor=0
diff --git a/gnu/lib/libg++/g++-include/sqrt.cc b/gnu/lib/libg++/g++-include/sqrt.cc
new file mode 100644
index 00000000000..6df9af3790f
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/sqrt.cc
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <math.h>
+
+long sqrt(long x)
+{
+ if (x <= 0)
+ return 0; // no int error handler, so ...
+ else if (x == 1)
+ return 1;
+ else
+ {
+ long r = x >> 1;
+ long q;
+ for(;;)
+ {
+ q = x / r;
+ if (q >= r)
+ return r;
+ else
+ r = (r + q) >> 1;
+ }
+ }
+}
diff --git a/gnu/lib/libg++/g++-include/std.h b/gnu/lib/libg++/g++-include/std.h
new file mode 100644
index 00000000000..8d851069fda
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/std.h
@@ -0,0 +1,39 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: std.h,v 1.1 1995/10/18 08:38:20 deraadt Exp $
+*/
+
+
+#ifndef _std_h
+#define _std_h 1
+
+#include <_G_config.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+
+extern "C" {
+int strcasecmp _G_ARGS((const char*, const char*));
+}
+
+#endif
diff --git a/gnu/lib/libg++/g++-include/str.cc b/gnu/lib/libg++/g++-include/str.cc
new file mode 100644
index 00000000000..bf77c02547a
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/str.cc
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1990 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+#include <AllocRing.h>
+
+extern AllocRing _libgxx_fmtq;
+
+char* str(const char* s, int width)
+{
+ int len = strlen(s);
+ int wrksiz = len + width + 1;
+ char* fmtbase = (char *) _libgxx_fmtq.alloc(wrksiz);
+ char* fmt = fmtbase;
+ for (int blanks = width - len; blanks > 0; --blanks)
+ *fmt++ = ' ';
+ while (*s != 0)
+ *fmt++ = *s++;
+ *fmt = 0;
+ return fmtbase;
+}
diff --git a/gnu/lib/libg++/g++-include/timer.cc b/gnu/lib/libg++/g++-include/timer.cc
new file mode 100644
index 00000000000..fdf35f4c18e
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/timer.cc
@@ -0,0 +1,130 @@
+/*
+Copyright (C) 1990, 1992 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <builtin.h>
+
+// 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 <osfcn.h>
+#if !_G_HAVE_SYS_RESOURCE || !defined(RUSAGE_SELF)
+#define USE_TIMES
+#include <sys/param.h>
+#include <sys/times.h>
+#if !defined (HZ) && defined(CLK_TCK)
+#define HZ CLK_TCK
+#endif
+static struct tms Old_Time;
+static struct tms New_Time;
+#else
+static struct rusage Old_Time;
+static struct rusage New_Time;
+#endif
+static int Timer_Set = 0;
+
+double start_timer()
+{
+ Timer_Set = 1;
+#ifdef USE_TIMES
+ times(&Old_Time);
+ return((double) Old_Time.tms_utime / HZ);
+#else
+ getrusage(RUSAGE_SELF,&Old_Time); /* set starting process time */
+ return(Old_Time.ru_utime.tv_sec + (Old_Time.ru_utime.tv_usec / 1000000.0));
+#endif
+}
+
+/* Returns process time since Last_Time.
+ If parameter is 0.0, returns time since the Old_Time was set.
+ Returns TIMER_ERROR_VALUE if `start_timer' is not called first. */
+
+double return_elapsed_time(double Last_Time)
+{
+ if (!Timer_Set) {
+ return(TIMER_ERROR_VALUE);
+ }
+ else {
+ /* get process time */
+#ifdef USE_TIMES
+ times(&New_Time);
+#else
+ getrusage(RUSAGE_SELF,&New_Time);
+#endif
+ if (Last_Time == 0.0) {
+#ifdef USE_TIMES
+ return((double) (New_Time.tms_utime - Old_Time.tms_utime) / HZ);
+#else
+ return((New_Time.ru_utime.tv_sec - Old_Time.ru_utime.tv_sec) +
+ ((New_Time.ru_utime.tv_usec - Old_Time.ru_utime.tv_usec)
+ / 1000000.0));
+#endif
+ }
+ else {
+#ifdef USE_TIMES
+ return((double) New_Time.tms_utime / HZ - Last_Time);
+#else
+ return((New_Time.ru_utime.tv_sec +
+ (New_Time.ru_utime.tv_usec / 1000000.0)) - Last_Time);
+#endif
+ }
+ }
+}
+
+#ifdef VMS
+void sys$gettim(unsigned int*) asm("sys$gettim");
+
+getrusage(int dummy,struct rusage* time){
+ double rtime;
+ unsigned int systime[2];
+ int i;
+ sys$gettim(&systime[0]);
+ rtime=systime[1];
+ for(i=0;i<4;i++) rtime *= 256;
+ rtime+= systime[0];
+/* we subtract an offset to make sure that the number fits in a long int*/
+ rtime=rtime/1.0e+7-4.144e+9;
+ time->ru_utime.tv_sec= rtime;
+ rtime=(rtime-time->ru_utime.tv_sec)*1.0e6;
+ time->ru_utime.tv_usec= rtime;
+}
+#endif
+#else /* dummy them out */
+
+double start_timer()
+{
+ return TIMER_ERROR_VALUE;
+}
+
+double return_elapsed_time(double)
+{
+ return TIMER_ERROR_VALUE;
+}
+
+#endif /* timing stuff */
+
+
diff --git a/gnu/lib/libg++/g++-include/values.h b/gnu/lib/libg++/g++-include/values.h
new file mode 100644
index 00000000000..ba4db1ffe43
--- /dev/null
+++ b/gnu/lib/libg++/g++-include/values.h
@@ -0,0 +1,175 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: values.h,v 1.1 1995/10/18 08:38:05 deraadt Exp $
+*/
+
+#ifndef _values_h
+#define _values_h 1
+
+#define BITSPERBYTE 8
+#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
+
+#define CHARBITS BITS(char)
+#define SHORTBITS BITS(short)
+#define INTBITS BITS(int)
+#define LONGBITS BITS(long)
+#define PTRBITS BITS(char*)
+#define DOUBLEBITS BITS(double)
+#define FLOATBITS BITS(float)
+
+#define MINSHORT ((short)(1 << (SHORTBITS - 1)))
+#define MININT (1 << (INTBITS - 1))
+#define MINLONG (1L << (LONGBITS - 1))
+
+#define MAXSHORT ((short)~MINSHORT)
+#define MAXINT (~MININT)
+#define MAXLONG (~MINLONG)
+
+#define HIBITS MINSHORT
+#define HIBITL MINLONG
+
+#if defined(sun) || defined(hp300) || defined(hpux) || defined(masscomp) || defined(sgi)
+#ifdef masscomp
+#define MAXDOUBLE \
+({ \
+ double maxdouble_val; \
+ \
+ __asm ("fmove%.d #0x7fefffffffffffff,%0" /* Max double */ \
+ : "=f" (maxdouble_val) \
+ : /* no inputs */); \
+ maxdouble_val; \
+})
+#define MAXFLOAT ((float) 3.40e+38)
+#else
+#define MAXDOUBLE 1.79769313486231470e+308
+#define MAXFLOAT ((float)3.40282346638528860e+38)
+#endif
+#define MINDOUBLE 4.94065645841246544e-324
+#define MINFLOAT ((float)1.40129846432481707e-45)
+#define _IEEE 1
+#define _DEXPLEN 11
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (-(DMAXEXP + DSIGNIF - _HIDDENBIT - 3))
+#define FMINEXP (-(FMAXEXP + FSIGNIF - _HIDDENBIT - 3))
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+
+#elif defined(sony)
+#define MAXDOUBLE 1.79769313486231470e+308
+#define MAXFLOAT ((float)3.40282346638528860e+38)
+#define MINDOUBLE 2.2250738585072010e-308
+#define MINFLOAT ((float)1.17549435e-38)
+#define _IEEE 1
+#define _DEXPLEN 11
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (-(DMAXEXP + DSIGNIF - _HIDDENBIT - 3))
+#define FMINEXP (-(FMAXEXP + FSIGNIF - _HIDDENBIT - 3))
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+
+#elif defined(sequent)
+extern double _maxdouble, _mindouble;
+extern float _maxfloat, _minfloat;
+#define MAXDOUBLE _maxdouble
+#define MAXFLOAT _maxfloat
+#define MINDOUBLE _mindouble
+#define MINFLOAT _minfloat
+#define _IEEE 1
+#define _DEXPLEN 11
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (-(DMAXEXP - 3))
+#define FMINEXP (-(FMAXEXP - 3))
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+
+#elif defined(i386)
+#define MAXDOUBLE 1.79769313486231570e+308
+#define MAXFLOAT ((float)3.40282346638528860e+38)
+#define MINDOUBLE 2.22507385850720140e-308
+#define MINFLOAT ((float)1.17549435082228750e-38)
+#define _IEEE 0
+#define _DEXPLEN 11
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (-DMAXEXP)
+#define FMINEXP (-FMAXEXP)
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+
+/* from Andrew Klossner <andrew%frip.wv.tek.com@relay.cs.net> */
+#elif defined(m88k)
+ /* These are "good" guesses ...
+ I'll figure out the true mins and maxes later, at the time I find
+ out the mins and maxes that the compiler can tokenize. */
+#define MAXDOUBLE 1.79769313486231e+308
+#define MAXFLOAT ((float)3.40282346638528e+38)
+#define MINDOUBLE 2.22507385850720e-308
+#define MINFLOAT ((float)1.17549435082228e-38)
+#define _IEEE 1
+#define _DEXPLEN 11
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (1-DMAXEXP)
+#define FMINEXP (1-FMAXEXP)
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+
+#elif defined(convex)
+#define MAXDOUBLE 8.9884656743115785e+306
+#define MAXFLOAT ((float) 1.70141173e+38)
+#define MINDOUBLE 5.5626846462680035e-308
+#define MINFLOAT ((float) 2.93873588e-39)
+#define _IEEE 0
+#define _DEXPLEN 11
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (-DMAXEXP)
+#define FMINEXP (-FMAXEXP)
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+
+// #elif defined(vax)
+// use vax versions by default -- they seem to be the most conservative
+#else
+
+#define MAXDOUBLE 1.701411834604692293e+38
+#define MINDOUBLE (2.938735877055718770e-39)
+
+#define MAXFLOAT 1.7014117331926443e+38
+#define MINFLOAT 2.9387358770557188e-39
+
+#define _IEEE 0
+#define _DEXPLEN 8
+#define _FEXPLEN 8
+#define _HIDDENBIT 1
+#define DMINEXP (-DMAXEXP)
+#define FMINEXP (-FMAXEXP)
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
+#endif
+
+#define DSIGNIF (DOUBLEBITS - _DEXPLEN + _HIDDENBIT - 1)
+#define FSIGNIF (FLOATBITS - _FEXPLEN + _HIDDENBIT - 1)
+#define DMAXPOWTWO ((double)(1L << LONGBITS -2)*(1L << DSIGNIF - LONGBITS +1))
+#define FMAXPOWTWO ((float)(1L << FSIGNIF - 1))
+
+#endif
+
diff --git a/gnu/lib/libg++/genclass/Makefile b/gnu/lib/libg++/genclass/Makefile
new file mode 100644
index 00000000000..68d8e6482a3
--- /dev/null
+++ b/gnu/lib/libg++/genclass/Makefile
@@ -0,0 +1,13 @@
+# Makefile for g++ library genclass
+
+PROG= genclass
+SRCS= genclass.sh
+NOMAN=
+STRIP=
+
+genclass: genclass.sh
+ sed -e 's|^PROTODIR=.*|PROTODIR=${DESTDIR}/usr/include/g++/gen|' \
+ -e 's|<VERSION>|2.4|' ${.ALLSRC} > ${.TARGET}
+
+.include <bsd.prog.mk>
+.include "../../../usr.bin/Makefile.inc"
diff --git a/gnu/lib/libg++/genclass/genclass.sh b/gnu/lib/libg++/genclass/genclass.sh
new file mode 100644
index 00000000000..08d510754ad
--- /dev/null
+++ b/gnu/lib/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
+ #
+ # <VERSION> is substituted by the build process.
+ # We currently use the libg++ version number (extracted from ../Makefile).
+ echo "$name: version <VERSION>" ;
+ 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=/projects/gnu-cygnus/gnu-cygnus-2/mips/lib/g++-include/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++/iostream/PlotFile.C b/gnu/lib/libg++/iostream/PlotFile.C
new file mode 100644
index 00000000000..306ba5e9026
--- /dev/null
+++ b/gnu/lib/libg++/iostream/PlotFile.C
@@ -0,0 +1,130 @@
+// 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)
+ converted to use iostream library by Per Bothner (bothner@cygnus.com)
+
+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 <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++/iostream/PlotFile.h b/gnu/lib/libg++/iostream/PlotFile.h
new file mode 100644
index 00000000000..5a85a5cd2cc
--- /dev/null
+++ b/gnu/lib/libg++/iostream/PlotFile.h
@@ -0,0 +1,120 @@
+// 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)
+ converted to use iostream library by Per Bothner (bothner@cygnus.com)
+
+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.
+
+ $Id: PlotFile.h,v 1.1 1995/10/18 08:38:11 deraadt Exp $
+*/
+
+/*
+ a very simple implementation of a class to output unix "plot"
+ format plotter files. See corresponding unix man pages for
+ more details.
+*/
+
+#ifndef _PlotFile_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _PlotFile_h
+
+#include <fstream.h>
+
+/*
+ Some plot libraries have the `box' command to draw boxes. Some don't.
+ `box' is included here via moves & lines to allow both possiblilties.
+*/
+
+
+class PlotFile : public ofstream
+{
+protected:
+ PlotFile& cmd(char c);
+ PlotFile& operator << (const int x);
+ PlotFile& operator << (const char *s);
+
+public:
+
+ PlotFile() : ofstream() { }
+ PlotFile(int fd) : ofstream(fd) { }
+ PlotFile(const char *name, int mode=ios::out, int prot=0664)
+ : ofstream(name, mode, prot) { }
+
+// PlotFile& remove() { ofstream::remove(); return *this; }
+
+// int filedesc() { return ofstream::filedesc(); }
+// const char* name() { return File::name(); }
+// void setname(const char* newname) { File::setname(newname); }
+// int iocount() { return File::iocount(); }
+
+ PlotFile& arc(const int xi, const int yi,
+ const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& box(const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& circle(const int x, const int y, const int r);
+ PlotFile& cont(const int xi, const int yi);
+ PlotFile& dot(const int xi, const int yi, const int dx,
+ int n, const int* pat);
+ PlotFile& erase();
+ PlotFile& label(const char* s);
+ PlotFile& line(const int x0, const int y0,
+ const int x1, const int y1);
+ PlotFile& linemod(const char* s);
+ PlotFile& move(const int xi, const int yi);
+ PlotFile& point(const int xi, const int yi);
+ PlotFile& space(const int x0, const int y0,
+ const int x1, const int y1);
+};
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gnu/lib/libg++/iostream/SFile.C b/gnu/lib/libg++/iostream/SFile.C
new file mode 100644
index 00000000000..9221bb34f7b
--- /dev/null
+++ b/gnu/lib/libg++/iostream/SFile.C
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 1988 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include <SFile.h>
+
+SFile::SFile(const char *filename, int size, int mode, int prot)
+: fstream(filename, mode, prot)
+{
+ sz = size;
+}
+
+SFile::SFile(int fd, int size)
+: fstream(fd)
+{
+ sz = size;
+}
+
+void SFile::open(const char *name, int size, int mode, int prot)
+{
+ fstream::open(name, mode, prot);
+ sz = size;
+}
+
+SFile& SFile::get(void* x)
+{
+ read(x, sz);
+ return *this;
+}
+
+SFile& SFile::put(void* x)
+{
+ write(x, sz);
+ return *this;
+}
+
+SFile& SFile::operator[](long i)
+{
+ if (rdbuf()->seekoff(i * sz, ios::beg) == EOF)
+ set(ios::badbit);
+ return *this;
+}
diff --git a/gnu/lib/libg++/iostream/SFile.h b/gnu/lib/libg++/iostream/SFile.h
new file mode 100644
index 00000000000..d7b75225272
--- /dev/null
+++ b/gnu/lib/libg++/iostream/SFile.h
@@ -0,0 +1,48 @@
+// This may look like C code, but it is really -*- C++ -*-
+/*
+Copyright (C) 1988, 1992 Free Software Foundation
+ written by Doug Lea (dl@rocky.oswego.edu)
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your
+option) any later version. This library is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: SFile.h,v 1.1 1995/10/18 08:38:12 deraadt Exp $
+*/
+
+#ifndef _SFile_h
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _SFile_h 1
+
+#include <fstream.h>
+
+class SFile: public fstream
+{
+ protected:
+ int sz; // unit size for structured binary IO
+
+public:
+ SFile() : fstream() { }
+ SFile(int fd, int size);
+ SFile(const char *name, int size, int mode, int prot=0664);
+ void open(const char *name, int size, int mode, int prot=0664);
+
+ int size() { return sz; }
+ int setsize(int s) { int old = sz; sz = s; return old; }
+
+ SFile& get(void* x);
+ SFile& put(void* x);
+ SFile& operator[](long i);
+};
+
+#endif
diff --git a/gnu/lib/libg++/iostream/editbuf.C b/gnu/lib/libg++/iostream/editbuf.C
new file mode 100644
index 00000000000..3d99e8442d1
--- /dev/null
+++ b/gnu/lib/libg++/iostream/editbuf.C
@@ -0,0 +1,707 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "ioprivate.h"
+#include "editbuf.h"
+#include <stddef.h>
+
+/* NOTE: Some of the code here is taken from GNU emacs */
+/* Hence this file falls under the GNU License! */
+
+// Invariants for edit_streambuf:
+// An edit_streambuf is associated with a specific edit_string,
+// which again is a sub-string of a specific edit_buffer.
+// An edit_streambuf is always in either get mode or put mode, never both.
+// In get mode, gptr() is the current position,
+// and pbase(), pptr(), and epptr() are all NULL.
+// In put mode, pptr() is the current position,
+// and eback(), gptr(), and egptr() are all NULL.
+// Any edit_streambuf that is actively doing insertion (as opposed to
+// replacing) // must have its pptr() pointing to the start of the gap.
+// Only one edit_streambuf can be actively inserting into a specific
+// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf.
+// That edit_streambuf "owns" the gap, and the actual start of the
+// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer
+// will only be updated on an edit_streambuf::overflow().
+
+int edit_streambuf::truncate()
+{
+ str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()),
+ str->buffer->tell(str->end));
+ return 0;
+}
+
+#ifdef OLD_STDIO
+inline void disconnect_gap_from_file(edit_buffer* buffer, FILE* fp)
+{
+ if (buffer->gap_start_ptr != &fp->__bufp)
+ return;
+ buffer->gap_start_normal = fp->__bufp;
+ buffer->gap_start_ptr = &buffer->gap_start_normal;
+}
+#endif
+
+void edit_streambuf::flush_to_buffer(edit_buffer* buffer)
+{
+ if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end())
+ buffer->_gap_start = pptr();
+}
+
+void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer)
+{
+ if (buffer->_writer != this) return;
+ flush_to_buffer(buffer);
+ setp(pptr(),pptr());
+ buffer->_writer = NULL;
+}
+
+buf_index edit_buffer::tell(buf_char *ptr)
+{
+ if (ptr <= gap_start())
+ return ptr - data;
+ else
+ return ptr - gap_end() + size1();
+}
+
+#if 0
+buf_index buf_cookie::tell()
+{
+ return str->buffer->tell(file->__bufp);
+}
+#endif
+
+buf_index edit_buffer::tell(edit_mark*mark)
+{
+ return tell(data + mark->index_in_buffer(this));
+}
+
+// adjust the position of the gap
+
+void edit_buffer::move_gap(buf_offset pos)
+{
+ if (pos < size1())
+ gap_left (pos);
+ else if (pos > size1())
+ gap_right (pos);
+}
+
+void edit_buffer::gap_left (int pos)
+{
+ register buf_char *to, *from;
+ register int i;
+ int new_s1;
+
+ i = size1();
+ from = gap_start();
+ to = from + gap_size();
+ new_s1 = size1();
+
+ /* Now copy the characters. To move the gap down,
+ copy characters up. */
+
+ for (;;)
+ {
+ /* I gets number of characters left to copy. */
+ i = new_s1 - pos;
+ if (i == 0)
+ break;
+#if 0
+ /* If a quit is requested, stop copying now.
+ Change POS to be where we have actually moved the gap to. */
+ if (QUITP)
+ {
+ pos = new_s1;
+ break;
+ }
+#endif
+ /* Move at most 32000 chars before checking again for a quit. */
+ if (i > 32000)
+ i = 32000;
+ new_s1 -= i;
+ while (--i >= 0)
+ *--to = *--from;
+ }
+
+ /* Adjust markers, and buffer data structure, to put the gap at POS.
+ POS is where the loop above stopped, which may be what was specified
+ or may be where a quit was detected. */
+ adjust_markers (pos << 1, size1() << 1, gap_size(), data);
+#ifndef OLD_STDIO
+ _gap_start = data + pos;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + pos;
+#endif
+ __gap_end_pos = to - data;
+/* QUIT;*/
+}
+
+void edit_buffer::gap_right (int pos)
+{
+ register buf_char *to, *from;
+ register int i;
+ int new_s1;
+
+ i = size1();
+ to = gap_start();
+ from = i + gap_end();
+ new_s1 = i;
+
+ /* Now copy the characters. To move the gap up,
+ copy characters down. */
+
+ while (1)
+ {
+ /* I gets number of characters left to copy. */
+ i = pos - new_s1;
+ if (i == 0)
+ break;
+#if 0
+ /* If a quit is requested, stop copying now.
+ Change POS to be where we have actually moved the gap to. */
+ if (QUITP)
+ {
+ pos = new_s1;
+ break;
+ }
+#endif
+ /* Move at most 32000 chars before checking again for a quit. */
+ if (i > 32000)
+ i = 32000;
+ new_s1 += i;
+ while (--i >= 0)
+ *to++ = *from++;
+ }
+
+ adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1,
+ - gap_size(), data);
+#ifndef OLD_STDIO
+ _gap_start = data+pos;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + pos;
+#endif
+ __gap_end_pos = from - data;
+/* QUIT;*/
+}
+
+/* make sure that the gap in the current buffer is at least k
+ characters wide */
+
+void edit_buffer::make_gap(buf_offset k)
+{
+ register buf_char *p1, *p2, *lim;
+ buf_char *old_data = data;
+ int s1 = size1();
+
+ if (gap_size() >= k)
+ return;
+
+ /* Get more than just enough */
+ if (buf_size > 1000) k += 2000;
+ else k += /*200;*/ 20; // for testing!
+
+ p1 = (buf_char *) realloc (data, s1 + size2() + k);
+ if (p1 == 0)
+ abort(); /*memory_full ();*/
+
+ k -= gap_size(); /* Amount of increase. */
+
+ /* Record new location of text */
+ data = p1;
+
+ /* Transfer the new free space from the end to the gap
+ by shifting the second segment upward */
+ p2 = data + buf_size;
+ p1 = p2 + k;
+ lim = p2 - size2();
+ while (lim < p2)
+ *--p1 = *--p2;
+
+ /* Finish updating text location data */
+ __gap_end_pos += k;
+
+#ifndef OLD_STDIO
+ _gap_start = data + s1;
+#else
+ if (gap_start_ptr == &gap_start_normal)
+ gap_start_normal = data + s1;
+#endif
+
+ /* adjust markers */
+ adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data);
+ buf_size += k;
+}
+
+/* Add `amount' to the position of every marker in the current buffer
+ whose current position is between `from' (exclusive) and `to' (inclusive).
+ Also, any markers past the outside of that interval, in the direction
+ of adjustment, are first moved back to the near end of the interval
+ and then adjusted by `amount'. */
+
+void edit_buffer::adjust_markers(register mark_pointer low,
+ register mark_pointer high,
+ int amount, buf_char *old_data)
+{
+ register struct edit_mark *m;
+ register mark_pointer mpos;
+ /* convert to mark_pointer */
+ amount <<= 1;
+
+ if (_writer)
+ _writer->disconnect_gap_from_file(this);
+
+ for (m = mark_list(); m != NULL; m = m->chain)
+ {
+ mpos = m->_pos;
+ if (amount > 0)
+ {
+ if (mpos > high && mpos < high + amount)
+ mpos = high + amount;
+ }
+ else
+ {
+ if (mpos > low + amount && mpos <= low)
+ mpos = low + amount;
+ }
+ if (mpos > low && mpos <= high)
+ mpos += amount;
+ m->_pos = mpos;
+ }
+
+ // Now adjust files
+ edit_streambuf *file;
+
+ for (file = files; file != NULL; file = file->next) {
+ mpos = file->current() - old_data;
+ if (amount > 0)
+ {
+ if (mpos > high && mpos < high + amount)
+ mpos = high + amount;
+ }
+ else
+ {
+ if (mpos > low + amount && mpos <= low)
+ mpos = low + amount;
+ }
+ if (mpos > low && mpos <= high)
+ mpos += amount;
+ char* new_pos = data + mpos;
+ file->set_current(new_pos, file->is_reading());
+ }
+}
+
+#if 0
+stdio_
+ __off == index at start of buffer (need only be valid after seek ? )
+ __buf ==
+
+if read/read_delete/overwrite mode:
+ __endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer))
+
+if inserting:
+ must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp
+ file->edit_string->end->ptr(buffer) == *gap_start_ptr+end
+if write_mode:
+ if before gap
+#endif
+
+int edit_streambuf::underflow()
+{
+ if (!(_mode & ios::in))
+ return EOF;
+ struct edit_buffer *buffer = str->buffer;
+ if (!is_reading()) { // Must switch from put to get mode.
+ disconnect_gap_from_file(buffer);
+ set_current(pptr(), 1);
+ }
+ buf_char *str_end = str->end->ptr(buffer);
+ retry:
+ if (gptr() < egptr()) {
+ return *gptr();
+ }
+ if ((buf_char*)gptr() == str_end)
+ return EOF;
+ if (str_end <= buffer->gap_start()) {
+ setg(eback(), gptr(), str_end);
+ goto retry;
+ }
+ if (gptr() < buffer->gap_start()) {
+ setg(eback(), gptr(), buffer->gap_start());
+ goto retry;
+ }
+ if (gptr() == buffer->gap_start()) {
+ disconnect_gap_from_file(buffer);
+// fp->__offset += fp->__bufp - fp->__buffer;
+ setg(buffer->gap_end(), buffer->gap_end(), str_end);
+ }
+ else
+ setg(eback(), gptr(), str_end);
+ goto retry;
+}
+
+int edit_streambuf::overflow(int ch)
+{
+ if (_mode == ios::in)
+ return EOF;
+ struct edit_buffer *buffer = str->buffer;
+ flush_to_buffer(buffer);
+ if (ch == EOF)
+ return 0;
+ if (is_reading()) { // Must switch from get to put mode.
+ set_current(gptr(), 0);
+ }
+ buf_char *str_end = str->end->ptr(buffer);
+ retry:
+ if (pptr() < epptr()) {
+ *pptr() = ch;
+ pbump(1);
+ return (unsigned char)ch;
+ }
+ if ((buf_char*)pptr() == str_end || inserting()) {
+ /* insert instead */
+ if (buffer->_writer)
+ buffer->_writer->flush_to_buffer(); // Redundant?
+ buffer->_writer = NULL;
+ if (pptr() >= buffer->gap_end())
+ buffer->move_gap(pptr() - buffer->gap_size());
+ else
+ buffer->move_gap(pptr());
+ buffer->make_gap(1);
+ setp(buffer->gap_start(), buffer->gap_end());
+ buffer->_writer = this;
+ *pptr() = ch;
+ pbump(1);
+ return (unsigned char)ch;
+ }
+ if (str_end <= buffer->gap_start()) {
+ // Entire string is left of gap.
+ setp(pptr(), str_end);
+ }
+ else if (pptr() < buffer->gap_start()) {
+ // Current pos is left of gap.
+ setp(pptr(), buffer->gap_start());
+ goto retry;
+ }
+ else if (pptr() == buffer->gap_start()) {
+ // Current pos is at start of gap; move to end of gap.
+// disconnect_gap_from_file(buffer);
+ setp(buffer->gap_end(), str_end);
+// __offset += __bufp - __buffer;
+ }
+ else {
+ // Otherwise, current pos is right of gap.
+ setp(pptr(), str_end);
+ }
+ goto retry;
+}
+
+void edit_streambuf::set_current(char *new_pos, int reading)
+{
+ if (reading) {
+ setg(new_pos, new_pos, new_pos);
+ setp(NULL, NULL);
+ }
+ else {
+ setg(NULL, NULL, NULL);
+ setp(new_pos, new_pos);
+ }
+}
+
+// Called by fseek(fp, pos, whence) if fp is bound to a edit_buffer.
+
+streampos edit_streambuf::seekoff(streamoff offset, _seek_dir dir,
+ int mode /* =ios::in|ios::out*/)
+{
+ struct edit_buffer *buffer = str->buffer;
+ disconnect_gap_from_file(buffer);
+ buf_index cur_pos = buffer->tell((buf_char*)current());;
+ buf_index start_pos = buffer->tell(str->start);
+ buf_index end_pos = buffer->tell(str->end);
+ switch (dir) {
+ case ios::beg:
+ offset += start_pos;
+ break;
+ case ios::cur:
+ offset += cur_pos;
+ break;
+ case ios::end:
+ offset += end_pos;
+ break;
+ }
+ if (offset < start_pos || offset > end_pos)
+ return EOF;
+ buf_char *new_pos = buffer->data + offset;
+ buf_char* gap_start = buffer->gap_start();
+ if (new_pos > gap_start) {
+ buf_char* gap_end = buffer->gap_end();
+ new_pos += gap_end - gap_start;
+ if (new_pos >= buffer->data + buffer->buf_size) abort(); // Paranoia.
+ }
+ set_current(new_pos, is_reading());
+ return EOF;
+}
+
+#if 0
+int buf_seek(void *arg_cookie, fpos_t * pos, int whence)
+{
+ struct buf_cookie *cookie = arg_cookie;
+ FILE *file = cookie->file;
+ struct edit_buffer *buffer = cookie->str->buffer;
+ buf_char *str_start = cookie->str->start->ptr(buffer);
+ disconnect_gap_from_file(buffer, cookie->file);
+ fpos_t cur_pos, new_pos;
+ if (file->__bufp <= *buffer->gap_start_ptr
+ || str_start >= buffer->__gap_end)
+ cur_pos = str_start - file->__bufp;
+ else
+ cur_pos =
+ (*buffer->gap_start_ptr - str_start) + (file->__bufp - __gap_end);
+ end_pos = ...;
+ switch (whence) {
+ case SEEK_SET:
+ new_pos = *pos;
+ break;
+ case SEEK_CUR:
+ new_pos = cur_pos + *pos;
+ break;
+ case SEEK_END:
+ new_pos = end_pos + *pos;
+ break;
+ }
+ if (new_pos > end_pos) {
+ seek to end_pos;
+ insert_nulls(new_pos - end_pos);
+ return;
+ }
+ if (str_start + new_pos <= *gap_start_ptr &* *gap_start_ptr < end) {
+ __buffer = str_start;
+ __off = 0;
+ __bufp = str_start + new_pos;
+ file->__get_limit =
+ *buffer->gap_start_ptr; /* what if gap_start_ptr == &bufp ??? */
+ } else if () {
+
+ }
+ *pos = new_pos;
+}
+#endif
+
+/* Delete characters from `from' up to (but not incl) `to' */
+
+void edit_buffer::delete_range (buf_index from, buf_index to)
+{
+ register int numdel;
+
+ if ((numdel = to - from) <= 0)
+ return;
+
+ /* Make sure the gap is somewhere in or next to what we are deleting */
+ if (from > size1())
+ gap_right (from);
+ if (to < size1())
+ gap_left (to);
+
+ /* Relocate all markers pointing into the new, larger gap
+ to point at the end of the text before the gap. */
+ adjust_markers ((to + gap_size()) << 1, (to + gap_size()) << 1,
+ - numdel - gap_size(), data);
+
+ __gap_end_pos = to + gap_size();
+ _gap_start = data + from;
+}
+
+void edit_buffer::delete_range(struct edit_mark *start, struct edit_mark *end)
+{
+ delete_range(tell(start), tell(end));
+}
+
+void buf_delete_chars(struct edit_buffer *buf, struct edit_mark *mark, size_t count)
+{
+ abort();
+}
+
+edit_streambuf::edit_streambuf(edit_string* bstr, int mode)
+{
+ _mode = mode;
+ str = bstr;
+ edit_buffer* buffer = bstr->buffer;
+ next = buffer->files;
+ buffer->files = this;
+ char* buf_ptr = bstr->start->ptr(buffer);
+ _inserting = 0;
+// setb(buf_ptr, buf_ptr, 0);
+ set_current(buf_ptr, !(mode & ios::out+ios::trunc+ios::app));
+ if (_mode & ios::trunc)
+ truncate();
+ if (_mode & ios::ate)
+ seekoff(0, ios::end);
+}
+
+// Called by fclose(fp) if fp is bound to a edit_buffer.
+
+#if 0
+static int buf_close(void *arg)
+{
+ register struct buf_cookie *cookie = arg;
+ struct edit_buffer *buffer = cookie->str->buffer;
+ struct buf_cookie **ptr;
+ for (ptr = &buffer->files; *ptr != cookie; ptr = &(*ptr)->next) ;
+ *ptr = cookie->next;
+ disconnect_gap_from_file(buffer, cookie->file);
+ free (cookie);
+ return 0;
+}
+#endif
+
+edit_streambuf::~edit_streambuf()
+{
+ if (_mode == ios::out)
+ truncate();
+ // Unlink this from list of files associated with bstr->buffer.
+ edit_streambuf **ptr = &str->buffer->files;
+ for (; *ptr != this; ptr = &(*ptr)->next) { }
+ *ptr = next;
+
+ disconnect_gap_from_file(str->buffer);
+}
+
+edit_buffer::edit_buffer()
+{
+ buf_size = /*200;*/ 15; /* for testing! */
+ data = (buf_char*)malloc(buf_size);
+ files = NULL;
+#ifndef OLD_STDIO
+ _gap_start = data;
+ _writer = NULL;
+#else
+ gap_start_normal = data;
+ gap_start_ptr = &gap_start_normal;
+#endif
+ __gap_end_pos = buf_size;
+ start_mark.chain = &end_mark;
+ start_mark._pos = 0;
+ end_mark.chain = NULL;
+ end_mark._pos = 2 * buf_size + 1;
+}
+
+// Allocate a new mark, which is adjusted by 'delta' bytes from 'this'.
+// Restrict new mark to lie within 'str'.
+
+edit_mark::edit_mark(struct edit_string *str, long delta)
+{
+ struct edit_buffer *buf = str->buffer;
+ chain = buf->start_mark.chain;
+ buf->start_mark.chain = this;
+ mark_pointer size1 = buf->size1() << 1;
+ int gap_size = buf->gap_size() << 1;
+ delta <<= 1;
+
+ // check if new and old marks are opposite sides of gap
+ if (_pos <= size1 && _pos + delta > size1)
+ delta += gap_size;
+ else if (_pos >= size1 + gap_size && _pos + delta < size1 + gap_size)
+ delta -= gap_size;
+
+ _pos = _pos + delta;
+ if (_pos < str->start->_pos & ~1)
+ _pos = (str->start->_pos & ~ 1) + (_pos & 1);
+ else if (_pos >= str->end->_pos)
+ _pos = (str->end->_pos & ~ 1) + (_pos & 1);
+}
+
+// A (slow) way to find the buffer a mark belongs to.
+
+edit_buffer * edit_mark::buffer()
+{
+ struct edit_mark *mark;
+ for (mark = this; mark->chain != NULL; mark = mark->chain) ;
+ // Assume that the last mark on the chain is the end_mark.
+ return (edit_buffer *)((char*)mark - offsetof(edit_buffer, end_mark));
+}
+
+edit_mark::~edit_mark()
+{
+ // Must unlink mark from chain of owning buffer
+ struct edit_buffer *buf = buffer();
+ if (this == &buf->start_mark || this == &buf->end_mark) abort();
+ edit_mark **ptr;
+ for (ptr = &buf->start_mark.chain; *ptr != this; ptr = &(*ptr)->chain) ;
+ *ptr = this->chain;
+}
+
+int edit_string::length() const
+{
+ ptrdiff_t delta = end->ptr(buffer) - start->ptr(buffer);
+ if (end->ptr(buffer) <= buffer->gap_start() ||
+ start->ptr(buffer) >= buffer->gap_end())
+ return delta;
+ return delta - buffer->gap_size();
+}
+
+buf_char * edit_string::copy_bytes(int *lenp) const
+{
+ char *new_str;
+ int len1, len2;
+ buf_char *start1, *start2;
+ start1 = start->ptr(buffer);
+ if (end->ptr(buffer) <= buffer->gap_start()
+ || start->ptr(buffer) >= buffer->gap_end()) {
+ len1 = end->ptr(buffer) - start1;
+ len2 = 0;
+ start2 = NULL; // To avoid a warning from g++.
+ }
+ else {
+ len1 = buffer->gap_start() - start1;
+ start2 = buffer->gap_end();
+ len2 = end->ptr(buffer) - start2;
+ }
+ new_str = (char*)malloc(len1 + len2 + 1);
+ memcpy(new_str, start1, len1);
+ if (len2 > 0) memcpy(new_str + len1, start2, len2);
+ new_str[len1+len2] = '\0';
+ *lenp = len1+len2;
+ return new_str;
+}
+
+// Replace the buf_chars in 'this' with ones from 'src'.
+// Equivalent to deleting this, then inserting src, except tries
+// to leave marks in place: Marks whose offset from the start
+// of 'this' is less than 'src->length()' will still have the
+// same offset in 'this' when done.
+
+void edit_string::assign(struct edit_string *src)
+{
+ edit_streambuf dst_file(this, ios::out);
+ if (buffer == src->buffer /*&& ???*/) { /* overly conservative */
+ int src_len;
+ buf_char *new_str;
+ new_str = src->copy_bytes(&src_len);
+ dst_file.sputn(new_str, src_len);
+ free (new_str);
+ } else {
+ edit_streambuf src_file(src, ios::in);
+ for ( ; ; ) {
+ int ch = src_file.sbumpc();
+ if (ch == EOF) break;
+ dst_file.sputc(ch);
+ }
+ }
+}
diff --git a/gnu/lib/libg++/iostream/editbuf.h b/gnu/lib/libg++/iostream/editbuf.h
new file mode 100644
index 00000000000..6562d73702e
--- /dev/null
+++ b/gnu/lib/libg++/iostream/editbuf.h
@@ -0,0 +1,175 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: editbuf.h,v 1.1 1995/10/18 08:38:12 deraadt Exp $
+
+#ifndef _EDITBUF_H
+#define _EDITBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <stdio.h>
+#include <fstream.h>
+
+typedef unsigned long mark_pointer;
+// At some point, it might be nice to parameterize this code
+// in terms of buf_char.
+typedef /*unsigned*/ char buf_char;
+
+// Logical pos from start of buffer (does not count gap).
+typedef long buf_index;
+
+// Pos from start of buffer, possibly including gap_size.
+typedef long buf_offset;
+
+#if 0
+struct buf_cookie {
+ FILE *file;
+ struct edit_string *str;
+ struct buf_cookie *next;
+ buf_index tell();
+};
+#endif
+
+struct edit_buffer;
+struct edit_mark;
+
+// A edit_string is defined as the region between the 'start' and 'end' marks.
+// Normally (always?) 'start->insert_before()' should be false,
+// and 'end->insert_before()' should be true.
+
+struct edit_string {
+ struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to
+ struct edit_mark *start, *end;
+ int length() const; // count of buf_chars currently in string
+ edit_string(struct edit_buffer *b,
+ struct edit_mark *ms, struct edit_mark *me)
+ { buffer = b; start = ms; end = me; }
+/* Make a fresh, contiguous copy of the data in STR.
+ Assign length of STR to *LENP.
+ (Output has extra NUL at out[*LENP].) */
+ buf_char *copy_bytes(int *lenp) const;
+// FILE *open_file(char *mode);
+ void assign(struct edit_string *src); // copy bytes from src to this
+};
+
+struct edit_streambuf : public streambuf {
+ friend edit_buffer;
+ edit_string *str;
+ edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer.
+ short _mode;
+ edit_streambuf(edit_string* bstr, int mode);
+ ~edit_streambuf();
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ void flush_to_buffer();
+ void flush_to_buffer(edit_buffer* buffer);
+ int _inserting;
+ int inserting() { return _inserting; }
+ void inserting(int i) { _inserting = i; }
+// int delete_chars(int count, char* cut_buf); Not implemented.
+ int truncate();
+ int is_reading() { return gptr() != NULL; }
+ buf_char* current() { return is_reading() ? gptr() : pptr(); }
+ void set_current(char *p, int is_reading);
+ protected:
+ void disconnect_gap_from_file(edit_buffer* buffer);
+};
+
+// A 'edit_mark' indicates a position in a buffer.
+// It is "attached" the text (rather than the offset).
+// There are two kinds of mark, which have different behavior
+// when text is inserted at the mark:
+// If 'insert_before()' is true the mark will be adjusted to be
+// *after* the new text.
+
+struct edit_mark {
+ struct edit_mark *chain;
+ mark_pointer _pos;
+ inline int insert_before() { return _pos & 1; }
+ inline unsigned long index_in_buffer(struct edit_buffer *buffer)
+ { return _pos >> 1; }
+ inline buf_char *ptr(struct edit_buffer *buf);
+ buf_index tell();
+ edit_mark() { }
+ edit_mark(struct edit_string *str, long delta);
+ edit_buffer *buffer();
+ ~edit_mark();
+};
+
+// A 'edit_buffer' consists of a sequence of buf_chars (the data),
+// a list of edit_marks pointing into the data, and a list of FILEs
+// also pointing into the data.
+// A 'edit_buffer' coerced to a edit_string is the string of
+// all the buf_chars in the buffer.
+
+// This implementation uses a conventional buffer gap (as in Emacs).
+// The gap start is defined by de-referencing a (buf_char**).
+// This is because sometimes a FILE is inserting into the buffer,
+// so rather than having each putc adjust the gap, we use indirection
+// to have the gap be defined as the write pointer of the FILE.
+// (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.)
+
+struct edit_buffer {
+ buf_char *data; /* == emacs buffer_text.p1+1 */
+ buf_char *_gap_start;
+ edit_streambuf* _writer; // If non-NULL, currently writing stream
+ inline buf_char *gap_start()
+ { return _writer ? _writer->pptr() : _gap_start; }
+ buf_offset __gap_end_pos; // size of part 1 + size of gap
+ /* int gap; implicit: buf_size - size1 - size2 */
+ int buf_size;
+ struct edit_streambuf *files;
+ struct edit_mark start_mark;
+ struct edit_mark end_mark;
+ edit_buffer();
+ inline buf_offset gap_end_pos() { return __gap_end_pos; }
+ inline struct edit_mark *start_marker() { return &start_mark; }
+ inline struct edit_mark *end_marker() { return &end_mark; }
+/* these should be protected, ultimately */
+ buf_index tell(edit_mark*);
+ buf_index tell(buf_char*);
+ inline buf_char *gap_end() { return data + gap_end_pos(); }
+ inline int gap_size() { return gap_end() - gap_start(); }
+ inline int size1() { return gap_start() - data; }
+ inline int size2() { return buf_size - gap_end_pos(); }
+ inline struct edit_mark * mark_list() { return &start_mark; }
+ void make_gap (buf_offset);
+ void move_gap (buf_offset pos);
+ void move_gap (buf_char *pos) { move_gap(pos - data); }
+ void gap_left (int pos);
+ void gap_right (int pos);
+ void adjust_markers(mark_pointer low, mark_pointer high,
+ int amount, buf_char *old_data);
+ void delete_range(buf_index from, buf_index to);
+ void delete_range(struct edit_mark *start, struct edit_mark *end);
+};
+
+extern buf_char * bstr_copy(struct edit_string *str, int *lenp);
+
+// Convert a edit_mark to a (buf_char*)
+
+inline buf_char *edit_mark::ptr(struct edit_buffer *buf)
+ { return buf->data + index_in_buffer(buf); }
+
+inline void edit_streambuf::flush_to_buffer()
+{
+ edit_buffer* buffer = str->buffer;
+ if (buffer->_writer == this) flush_to_buffer(buffer);
+}
+#endif /* !_EDITBUF_H*/
+
diff --git a/gnu/lib/libg++/iostream/filebuf.C b/gnu/lib/libg++/iostream/filebuf.C
new file mode 100644
index 00000000000..4d49d7f0e60
--- /dev/null
+++ b/gnu/lib/libg++/iostream/filebuf.C
@@ -0,0 +1,580 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991, 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "ioprivate.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+// An fstream can be in at most one of put mode, get mode, or putback mode.
+// Putback mode is a variant of get mode.
+
+// In a filebuf, there is only one current position, instead of two
+// separate get and put pointers. In get mode, the current posistion
+// is that of gptr(); in put mode that of pptr().
+
+// The position in the buffer that corresponds to the position
+// in external file system is file_ptr().
+// This is normally egptr(), except in putback mode, when it is _save_egptr.
+// If the field _fb._offset is >= 0, it gives the offset in
+// the file as a whole corresponding to eGptr(). (???)
+
+// PUT MODE:
+// If a filebuf is in put mode, pbase() is non-NULL and equal to base().
+// Also, epptr() == ebuf().
+// Also, eback() == gptr() && gptr() == egptr().
+// The un-flushed character are those between pbase() and pptr().
+// GET MODE:
+// If a filebuf is in get or putback mode, eback() != egptr().
+// In get mode, the unread characters are between gptr() and egptr().
+// The OS file position corresponds to that of egptr().
+// PUTBACK MODE:
+// Putback mode is used to remember "excess" characters that have
+// been sputbackc'd in a separate putback buffer.
+// In putback mode, the get buffer points to the special putback buffer.
+// The unread characters are the characters between gptr() and egptr()
+// in the putback buffer, as well as the area between save_gptr()
+// and save_egptr(), which point into the original reserve buffer.
+// (The pointers save_gptr() and save_egptr() are the values
+// of gptr() and egptr() at the time putback mode was entered.)
+// The OS position corresponds to that of save_egptr().
+//
+// LINE BUFFERED OUTPUT:
+// During line buffered output, pbase()==base() && epptr()==base().
+// However, ptr() may be anywhere between base() and ebuf().
+// This forces a call to filebuf::overflow(int C) on every put.
+// If there is more space in the buffer, and C is not a '\n',
+// then C is inserted, and pptr() incremented.
+//
+// UNBUFFERED STREAMS:
+// If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
+
+#define CLOSED_FILEBUF_FLAGS \
+ (_S_IS_FILEBUF+_S_NO_READS+_S_NO_WRITES+_S_TIED_PUT_GET)
+
+void filebuf::init()
+{
+ _fb._offset = 0;
+
+ _link_in();
+ _fb._fileno = -1;
+}
+
+filebuf::filebuf() : backupbuf(CLOSED_FILEBUF_FLAGS)
+{
+ init();
+}
+
+filebuf::filebuf(int fd) : backupbuf(CLOSED_FILEBUF_FLAGS)
+{
+ init();
+ attach(fd);
+}
+
+filebuf::filebuf(int fd, char* p, int len) : backupbuf(CLOSED_FILEBUF_FLAGS)
+{
+ init();
+ attach(fd);
+ setbuf(p, len);
+}
+
+filebuf::~filebuf()
+{
+ if (!(xflags() & _S_DELETE_DONT_CLOSE))
+ close();
+
+ _un_link();
+}
+
+filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot)
+{
+ if (is_open())
+ 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 = _S_NO_READS;
+ else if (mode & (int)ios::in)
+ posix_mode = O_RDONLY, read_write = _S_NO_WRITES;
+ else
+ posix_mode = 0, read_write = _S_NO_READS+_S_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 |= _S_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;
+ _fb._fileno = fd;
+ xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING);
+ if (mode & (ios::ate|ios::app)) {
+ if (seekoff(0, ios::end) == EOF)
+ return NULL;
+ }
+ _link_in();
+ return this;
+}
+
+filebuf* filebuf::open(const char *filename, const char *mode)
+{
+ if (is_open())
+ return NULL;
+ int oflags = 0, omode;
+ int read_write;
+ int oprot = 0666;
+ switch (*mode++) {
+ case 'r':
+ omode = O_RDONLY;
+ read_write = _S_NO_WRITES;
+ break;
+ case 'w':
+ omode = O_WRONLY;
+ oflags = O_CREAT|O_TRUNC;
+ read_write = _S_NO_READS;
+ break;
+ case 'a':
+ omode = O_WRONLY;
+ oflags = O_CREAT|O_APPEND;
+ read_write = _S_NO_READS|_S_IS_APPENDING;
+ break;
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+ if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) {
+ omode = O_RDWR;
+ read_write &= _S_IS_APPENDING;
+ }
+ int fdesc = ::open(filename, omode|oflags, oprot);
+ if (fdesc < 0)
+ return NULL;
+ _fb._fileno = fdesc;
+ xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING);
+ if (read_write & _S_IS_APPENDING)
+ if (seekoff(0, ios::end) == EOF)
+ return NULL;
+ _link_in();
+ return this;
+}
+
+filebuf* filebuf::attach(int fd)
+{
+ if (is_open())
+ return NULL;
+ _fb._fileno = fd;
+ xsetflags(0, _S_NO_READS+_S_NO_WRITES);
+ return this;
+}
+
+streambuf* filebuf::setbuf(char* p, int len)
+{
+ if (streambuf::setbuf(p, len) == NULL)
+ return NULL;
+ setp(_base, _base);
+ setg(_base, _base, _base);
+ return this;
+}
+
+int filebuf::overflow(int c)
+{
+ if (xflags() & _S_NO_WRITES) // SET ERROR
+ return EOF;
+ // Allocate a buffer if needed.
+ if (base() == NULL) {
+ doallocbuf();
+ if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(_base, _base);
+ else setp(_base, _ebuf);
+ setg(_base, _base, _base);
+ _flags |= _S_CURRENTLY_PUTTING;
+ }
+ // If currently reading, switch to writing.
+ else if ((_flags & _S_CURRENTLY_PUTTING) == 0) {
+ if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(gptr(), gptr());
+ else setp(gptr(), ebuf());
+ setg(egptr(), egptr(), egptr());
+ _flags |= _S_CURRENTLY_PUTTING;
+ }
+ if (c == EOF)
+ return do_flush();
+ if (pptr() == ebuf() ) // Buffer is really full
+ if (do_flush() == EOF)
+ return EOF;
+ xput_char(c);
+ if (unbuffered() || (linebuffered() && c == '\n'))
+ if (do_flush() == EOF)
+ return EOF;
+ return (unsigned char)c;
+}
+
+int filebuf::underflow()
+{
+#if 0
+ /* SysV does not make this test; take it out for compatibility */
+ if (fp->_flags & __SEOF)
+ return (EOF);
+#endif
+
+ if (xflags() & _S_NO_READS)
+ return EOF;
+ if (gptr() < egptr())
+ return *(unsigned char*)gptr();
+ allocbuf();
+
+ // FIXME This can/should be moved to __streambuf ??
+ if ((xflags() & _S_LINE_BUF) || unbuffered()) {
+ // Flush all line buffered files before reading.
+ streambuf::flush_all_linebuffered();
+ }
+
+ switch_to_get_mode();
+
+ _G_ssize_t count = sys_read(base(), ebuf() - base());
+ if (count <= 0) {
+ if (count == 0)
+ xsetflags(_S_EOF_SEEN);
+ else
+ xsetflags(_S_ERR_SEEN), count = 0;
+ }
+ setg(base(), base(), base() + count);
+ setp(base(), base());
+ if (count == 0)
+ return EOF;
+ if (_fb._offset >= 0)
+ _fb._offset += count;
+ return *(unsigned char*)gptr();
+}
+
+int filebuf::do_write(const char *data, int to_do)
+{
+ if (to_do == 0)
+ return 0;
+ if (xflags() & _S_IS_APPENDING) {
+ // On a system without a proper O_APPEND implementation,
+ // you would need to sys_seek(0, ios::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.
+ _fb._offset = -1;
+ }
+ else if (egptr() != pbase()) {
+ long new_pos = sys_seek(pbase()-egptr(), ios::cur);
+ if (new_pos == -1)
+ return EOF;
+ _fb._offset = new_pos;
+ }
+ _G_ssize_t count = sys_write(data, to_do);
+ if (_cur_column)
+ _cur_column = __adjust_column(_cur_column - 1, data, to_do) + 1;
+ setg(base(), base(), base());
+ if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(base(), base());
+ else setp(base(), ebuf());
+ return count != to_do ? EOF : 0;
+}
+
+int filebuf::sync()
+{
+// char* ptr = cur_ptr();
+ if (pptr() > pbase())
+ if (do_flush()) return EOF;
+ if (gptr() != egptr()) {
+ streampos delta = gptr() - egptr();
+ if (in_backup())
+ delta -= eGptr() - Gbase();
+ _G_fpos_t new_pos = sys_seek(delta, ios::cur);
+ if (new_pos == EOF)
+ return EOF;
+ _fb._offset = new_pos;
+ setg(eback(), gptr(), gptr());
+ }
+ // FIXME: Cleanup - can this be shared?
+// setg(base(), ptr, ptr);
+ return 0;
+}
+
+streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
+{
+ streampos result, new_offset, delta;
+ _G_ssize_t count;
+
+ if (mode == 0) // Don't move any pointers.
+ dir = ios::cur, offset = 0;
+
+ // 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.)
+ if (pptr() > pbase() || put_mode())
+ if (switch_to_get_mode()) return EOF;
+
+ if (base() == NULL) {
+ doallocbuf();
+ setp(base(), base());
+ setg(base(), base(), base());
+ }
+ switch (dir) {
+ case ios::cur:
+ if (_fb._offset < 0) {
+ _fb._offset = sys_seek(0, ios::cur);
+ if (_fb._offset < 0)
+ return EOF;
+ }
+ // Make offset absolute, assuming current pointer is file_ptr().
+ offset += _fb._offset;
+
+ offset -= _egptr - _gptr;
+ if (in_backup())
+ offset -= _other_egptr - _other_gbase;
+ dir = ios::beg;
+ break;
+ case ios::beg:
+ break;
+ case ios::end:
+ struct stat st;
+ if (sys_stat(&st) == 0 && S_ISREG(st.st_mode)) {
+ offset += st.st_size;
+ dir = ios::beg;
+ }
+ else
+ goto dumb;
+ }
+ // At this point, dir==ios::beg.
+
+ // If destination is within current buffer, optimize:
+ if (_fb._offset >= 0 && _eback != NULL) {
+ // Offset relative to start of main get area.
+ _G_fpos_t rel_offset = offset - _fb._offset
+ + (eGptr()-Gbase());
+ if (rel_offset >= 0) {
+ if (in_backup())
+ switch_to_main_get_area();
+ if (rel_offset <= _egptr - _eback) {
+ setg(base(), base() + rel_offset, egptr());
+ setp(base(), base());
+ return offset;
+ }
+ // If we have streammarkers, seek forward by reading ahead.
+ if (have_markers()) {
+ int to_skip = rel_offset - (_gptr - _eback);
+ if (ignore(to_skip) != to_skip)
+ goto dumb;
+ return offset;
+ }
+ }
+ if (rel_offset < 0 && rel_offset >= Bbase() - Bptr()) {
+ if (!in_backup())
+ switch_to_backup_area();
+ gbump(_egptr + rel_offset - gptr());
+ return offset;
+ }
+ }
+
+ unsave_markers();
+
+ // Try to seek to a block boundary, to improve kernel page management.
+ new_offset = offset & ~(ebuf() - base() - 1);
+ delta = offset - new_offset;
+ if (delta > ebuf() - base()) {
+ new_offset = offset;
+ delta = 0;
+ }
+ result = sys_seek(new_offset, ios::beg);
+ if (result < 0)
+ return EOF;
+ if (delta == 0)
+ count = 0;
+ else {
+ count = sys_read(base(), ebuf()-base());
+ if (count < delta) {
+ // We weren't allowed to read, but try to seek the remainder.
+ offset = count == EOF ? delta : delta-count;
+ dir = ios::cur;
+ goto dumb;
+ }
+ }
+ setg(base(), base()+delta, base()+count);
+ setp(base(), base());
+ _fb._offset = result + count;
+ xflags(xflags() & ~ _S_EOF_SEEN);
+ return offset;
+ dumb:
+ unsave_markers();
+ result = sys_seek(offset, dir);
+ if (result != EOF) {
+ xflags(xflags() & ~_S_EOF_SEEN);
+ }
+ _fb._offset = result;
+ setg(base(), base(), base());
+ setp(base(), base());
+ return result;
+}
+
+filebuf* filebuf::close()
+{
+ if (!is_open())
+ return NULL;
+
+ // This flushes as well as switching mode.
+ if (pptr() > pbase() || put_mode())
+ if (switch_to_get_mode()) return NULL;
+
+ unsave_markers();
+
+ int status = sys_close();
+
+ // Free buffer.
+ setb(NULL, NULL, 0);
+ setg(NULL, NULL, NULL);
+ setp(NULL, NULL);
+
+ _un_link();
+ _flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
+ _fb._fileno = EOF;
+ _fb._offset = 0;
+
+ return status < 0 ? NULL : this;
+}
+
+_G_ssize_t filebuf::sys_read(char* buf, size_t size)
+{
+ for (;;) {
+ _G_ssize_t count = ::read(_fb._fileno, buf, size);
+ if (count != -1 || errno != EINTR)
+ return count;
+ }
+}
+
+_G_fpos_t filebuf::sys_seek(_G_fpos_t offset, _seek_dir dir)
+{
+ return ::lseek(fd(), offset, (int)dir);
+}
+
+_G_ssize_t filebuf::sys_write(const void *buf, long n)
+{
+ long to_do = n;
+ while (to_do > 0) {
+ _G_ssize_t count = ::write(fd(), buf, to_do);
+ if (count == EOF) {
+ if (errno == EINTR)
+ continue;
+ else {
+ _flags |= _S_ERR_SEEN;
+ break;
+ }
+ }
+ to_do -= count;
+ buf = (void*)((char*)buf + count);
+ }
+ n -= to_do;
+ if (_fb._offset >= 0)
+ _fb._offset += n;
+ return n;
+}
+
+int filebuf::sys_stat(void* st)
+{
+ return ::_fstat(fd(), (struct stat*)st);
+}
+
+int filebuf::sys_close()
+{
+ return ::close(fd());
+}
+
+int filebuf::xsputn(const char *s, int n)
+{
+ 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.
+
+ int to_do = n;
+ int must_flush = 0;
+ // First figure out how much space is available in the buffer.
+ int count = _epptr - _pptr; // Space available.
+ if (linebuffered() && (_flags & _S_CURRENTLY_PUTTING)) {
+ count =_ebuf - _pptr;
+ if (count >= n) {
+ for (register const char *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(pptr(), s, count);
+ s += count;
+ }
+ else {
+ register char *p = pptr();;
+ for (register int i = count; --i >= 0; ) *p++ = *s++;
+ }
+ pbump(count);
+ to_do -= count;
+ }
+ if (to_do + must_flush > 0) {
+ // Next flush the (full) buffer.
+ if (__overflow(this, EOF) == EOF)
+ return n - to_do;
+
+ // Try to maintain alignment: write a whole number of blocks.
+ // dont_write is what gets left over.
+ int block_size = _ebuf - _base;
+ int dont_write = block_size >= 128 ? to_do % block_size : 0;
+
+ _G_ssize_t count = to_do - dont_write;
+ if (do_write(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 streambuf::sputn handle the general case.
+ if (dont_write)
+ to_do -= streambuf::sputn(s+count, dont_write);
+ }
+ return n - to_do;
+}
+
+int filebuf::xsgetn(char *s, int 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++/iostream/floatconv.C b/gnu/lib/libg++/iostream/floatconv.C
new file mode 100644
index 00000000000..fb70052c035
--- /dev/null
+++ b/gnu/lib/libg++/iostream/floatconv.C
@@ -0,0 +1,2416 @@
+#include <ioprivate.h>
+#ifdef USE_DTOA
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Some cleaning up by Per Bothner, bothner@cygnus.com, 1992, 1993. */
+
+/* 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 Just_16 to store 16 bits per 32-bit long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ * #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
+
+#include <stdlib.h>
+#include <string.h>
+#define CONST const
+
+#include <errno.h>
+#include <float.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__)
+#define IEEE_8087
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+
+#if FLT_RADIX==16
+#define IBM
+#elif DBL_MANT_DIG==56
+#define VAX
+#elif 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
+
+#ifdef IEEE_8087
+#define HIWORD 1
+#define LOWORD 0
+#define TEST_ENDIANNESS /* nothing */
+#elif defined(IEEE_MC68k)
+#define HIWORD 0
+#define LOWORD 1
+#define TEST_ENDIANNESS /* nothing */
+#else
+static int HIWORD = -1, LOWORD;
+static void test_endianness()
+{
+ union doubleword {
+ double d;
+ unsigned long u[2];
+ } dw;
+ dw.d = 10;
+ if (dw.u[0] != 0) /* big-endian */
+ HIWORD=0, LOWORD=1;
+ else
+ HIWORD=1, LOWORD=0;
+}
+#define TEST_ENDIANNESS if (HIWORD<0) test_endianness();
+#endif
+#define word0(x) ((unsigned long *)&x)[HIWORD]
+#define word1(x) ((unsigned long *)&x)[LOWORD]
+
+/* The following definition of Storeinc is appropriate for MIPS processors. */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#elif 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
+
+/* #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
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per long.
+ */
+#ifndef Pack_32
+#define Pack_32
+#endif
+#endif
+
+#define Kmax 15
+
+extern "C" double _Xstrtod(const char *s00, char **se);
+extern "C" char *dtoa(double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+
+struct Bigint {
+ /* Note: Order of fields is significant: Cfr. Bcopy macro. */
+ struct Bigint *next;
+ int k; /* Parameter given to Balloc(k) */
+ int maxwds; /* Allocated space: equals 1<<k. */
+ int sign;
+ int wds; /* Current length. */
+ unsigned long x[1]; /* Actually: x[maxwds] */
+};
+
+ typedef struct Bigint Bigint;
+
+ static Bigint *freelist[Kmax+1];
+
+/* 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 (rv = freelist[k]) {
+ freelist[k] = rv->next;
+ }
+ else {
+ x = 1 << k;
+ rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(long));
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ rv->sign = rv->wds = 0;
+ return rv;
+ }
+
+ static void
+Bfree
+#ifdef KR_headers
+ (v) Bigint *v;
+#else
+ (Bigint *v)
+#endif
+{
+ if (v) {
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ }
+ }
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(long) + 2*sizeof(int))
+
+/* Return b*m+a. b is modified. */
+
+ 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;
+ unsigned long *x, y;
+#ifdef Pack_32
+ unsigned long xi, z;
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int)(z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (int)(y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ }
+ while(++i < wds);
+ if (a) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+ }
+
+ static Bigint *
+s2b
+#ifdef KR_headers
+ (s, nd0, nd, y9) CONST char *s; int nd0, nd; unsigned long y9;
+#else
+ (CONST char *s, int nd0, int nd, unsigned long y9)
+#endif
+{
+ Bigint *b;
+ int i, k;
+ long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do b = multadd(b, 10, *s++ - '0');
+ while(++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+ }
+
+ static int
+hi0bits
+#ifdef KR_headers
+ (x) register unsigned long x;
+#else
+ (register unsigned long 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) unsigned long *y;
+#else
+ (unsigned long *y)
+#endif
+{
+ register int k;
+ register unsigned long 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
+ (i) int i;
+#else
+ (int i)
+#endif
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+ }
+
+ static Bigint *
+mult
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ unsigned long carry, y, z;
+ unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ unsigned long z2;
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(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;
+#ifdef Pack_32
+ 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;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+ }
+
+ static Bigint *p5s;
+
+/* Returns b*(5**k). b is modified. */
+
+ static Bigint *
+pow5mult
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static int p05[3] = { 5, 25, 125 };
+
+ if (i = k & 3)
+ b = multadd(b, p05[i-1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = p5s)) {
+ /* first time */
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+ }
+
+ static Bigint *
+lshift
+#ifdef KR_headers
+ (b, k) Bigint *b; int k;
+#else
+ (Bigint *b, int k)
+#endif
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ unsigned long *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+ }
+
+ static int
+cmp
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ unsigned long *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;
+ }
+
+ static Bigint *
+diff
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ Bigint *c;
+ int i, wa, wb;
+ long borrow, y; /* We need signed shifts here. */
+ unsigned long *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ long z;
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(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;
+#ifdef Pack_32
+ 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);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+ }
+
+ static double
+ulp
+#ifdef KR_headers
+ (x) double x;
+#else
+ (double x)
+#endif
+{
+ register long L;
+ double a;
+
+ L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0(a) = L;
+ word1(a) = 0;
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ word0(a) = 0x80000 >> L;
+ word1(a) = 0;
+ }
+ else {
+ word0(a) = 0;
+ L -= Exp_shift;
+ word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+ }
+ }
+#endif
+ return a;
+ }
+
+ static double
+b2d
+#ifdef KR_headers
+ (a, e) Bigint *a; int *e;
+#else
+ (Bigint *a, int *e)
+#endif
+{
+ unsigned long *xa, *xa0, w, y, z;
+ int k;
+ double d;
+#ifdef VAX
+ unsigned long d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ 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;
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+ word0(d) = d0 >> 16 | d0 << 16;
+ word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return d;
+ }
+
+ static Bigint *
+d2b
+#ifdef KR_headers
+ (d, e, bits) double d; int *e, *bits;
+#else
+ (double d, int *e, int *bits)
+#endif
+{
+ Bigint *b;
+ int de, i, k;
+ unsigned long *x, y, z;
+#ifdef VAX
+ unsigned long d0, d1;
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->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_msk1;
+#endif
+
+#ifdef Pack_32
+ if (y = d1) {
+ if (k = lo0bits(&y)) {
+ x[0] = y | z << 32 - k;
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = d1) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+ }
+#undef d0
+#undef d1
+
+ static double
+ratio
+#ifdef KR_headers
+ (a, b) Bigint *a, *b;
+#else
+ (Bigint *a, Bigint *b)
+#endif
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ word0(da) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ word0(db) += (k >> 2)*Exp_msk1;
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0(da) += k*Exp_msk1;
+ else {
+ k = -k;
+ word0(db) += k*Exp_msk1;
+ }
+#endif
+ return da / db;
+ }
+
+ static double
+tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+ };
+
+ static double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+ double
+_Xstrtod
+#ifdef KR_headers
+ (s00, se) CONST char *s00; char **se;
+#else
+ (CONST char *s00, char **se)
+#endif
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ long L;
+ unsigned long y, z;
+ Bigint *bb, *bb1, *bd, *bd0, *bs, *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:
+ goto ret;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+ break2:
+ if (*s == '0') {
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == '.') {
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ e = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ e = 10*e + c - '0';
+ if (s - s1 > 8)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 9999999;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+ rv = tens[k - 9] * rv + z;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0(rv) -= P*Exp_msk1;
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ word0(rv) += P*Exp_msk1;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if (i = e1 & 15)
+ rv *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ errno = ERANGE;
+#ifndef HUGE_VAL
+#define HUGE_VAL 1.7976931348623157E+308
+#endif
+ rv = HUGE_VAL;
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0(rv) -= P*Exp_msk1;
+ rv *= bigtens[j];
+ if ((z = word0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if (i = e1 & 15)
+ rv /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (!rv) {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (!rv) {
+ undfl:
+ rv = 0.;
+ errno = ERANGE;
+ goto ret;
+ }
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(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) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ 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(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+ && word1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ word0(rv) = (word0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+ word1(rv) = 0;
+ break;
+ }
+ }
+ else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = word0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ word0(rv) = L | Bndry_mask1;
+ word1(rv) = 0xffffffff;
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (!rv)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (word1(rv) == Tiny1 && !word0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = word0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ word0(rv) -= P*Exp_msk1;
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((word0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ goto ovfl;
+ word0(rv) = Big0;
+ word1(rv) = Big1;
+ goto cont;
+ }
+ else
+ word0(rv) += P*Exp_msk1;
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ word0(rv) += P*Exp_msk1;
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (word0(rv0) == Tiny0
+ && word1(rv0) == Tiny1)
+ goto undfl;
+ word0(rv) = Tiny0;
+ word1(rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0(rv) -= P*Exp_msk1;
+ }
+ else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = word0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = (long)aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -rv : rv;
+ }
+
+ static int
+quorem
+#ifdef KR_headers
+ (b, S) Bigint *b, *S;
+#else
+ (Bigint *b, Bigint *S)
+#endif
+{
+ int n;
+ long borrow, y;
+ unsigned long carry, q, ys;
+ unsigned long *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ long z;
+ unsigned long si, zs;
+#endif
+
+ 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 {
+#ifdef Pack_32
+ 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);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ 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 {
+#ifdef Pack_32
+ 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);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ 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 *
+dtoa
+#ifdef KR_headers
+ (d, mode, ndigits, decpt, sign, rve)
+ double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+ (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ spec_case, try_quick;
+ long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ unsigned long x;
+#endif
+ Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ double d2, ds, eps;
+ char *s, *s0;
+ static Bigint *result;
+ static int result_k;
+
+ TEST_ENDIANNESS;
+ if (result) {
+ result->k = result_k;
+ result->maxwds = 1 << result_k;
+ Bfree(result);
+ result = 0;
+ }
+
+ if (word0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+ if (word0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+#ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff))
+ {
+ s = "Infinity";
+ if (*rve)
+ *rve = s + 8;
+ }
+ else
+#endif
+ {
+ s = "NaN";
+ if (rve)
+ *rve = s +3;
+ }
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (!d) {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(d, &be, &bbits);
+ i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#ifndef Sudden_Underflow
+ if (i) {
+#endif
+ d2 = d;
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+ d2 /= 1 << j;
+#endif
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
+ : word1(d) << 32 - i;
+ d2 = x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+
+ /* Now i is the unbiased base-2 exponent. */
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = i*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = i*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i) by 0.301029995663981; since |i| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ /* i is now an upper bound of the number of digits to generate. */
+ j = sizeof(unsigned long);
+ /* The test is <= so as to allow room for the final '\0'. */
+ for(result_k = 0; sizeof(Bigint) - sizeof(unsigned long) + j <= i;
+ j <<= 1) result_k++;
+ result = Balloc(result_k);
+ s = s0 = (char *)result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if (j1 = -k) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0) {
+ S = mhi = 0;
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = (long)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for(i = 1;; i++, d *= 10.) {
+ L = (long)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++) {
+ L = (long)(d / ds);
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ d += d;
+ if (d > ds || d == ds && L & 1) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ 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(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) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if (j = b5 - m5)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(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.
+ */
+#ifdef Pack_32
+ if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
+ i = 32 - i;
+#else
+ if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+ i = 16 - i;
+#endif
+ 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.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ 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);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#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(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+ }
+#endif /* USE_DTOA */
diff --git a/gnu/lib/libg++/iostream/floatio.h b/gnu/lib/libg++/iostream/floatio.h
new file mode 100644
index 00000000000..d3d2d0e5201
--- /dev/null
+++ b/gnu/lib/libg++/iostream/floatio.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * $Id: floatio.h,v 1.1 1995/10/18 08:38:12 deraadt Exp $
+ */
+
+/*
+ * 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++/iostream/fstream.C b/gnu/lib/libg++/iostream/fstream.C
new file mode 100644
index 00000000000..9b45573ea03
--- /dev/null
+++ b/gnu/lib/libg++/iostream/fstream.C
@@ -0,0 +1,65 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+#include "ioprivate.h"
+#include <fstream.h>
+
+fstreambase::fstreambase()
+{
+ init(new filebuf());
+}
+
+fstreambase::fstreambase(int fd)
+{
+ init(new filebuf(fd));
+}
+
+fstreambase::fstreambase(const char *name, int mode, int prot)
+{
+ init(new filebuf());
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+void fstreambase::open(const char *name, int mode, int prot)
+{
+ clear();
+ if (!rdbuf()->open(name, mode, prot))
+ set(ios::badbit);
+}
+
+void fstreambase::close()
+{
+ if (!rdbuf()->close())
+ set(ios::failbit);
+}
+
+#if 0
+static int mode_to_sys(enum open_mode mode)
+{
+ return O_WRONLY;
+}
+
+static char* fopen_cmd_arg(io_mode i)
+{
+ return "w";
+}
+#endif
diff --git a/gnu/lib/libg++/iostream/fstream.h b/gnu/lib/libg++/iostream/fstream.h
new file mode 100644
index 00000000000..7395dc8b878
--- /dev/null
+++ b/gnu/lib/libg++/iostream/fstream.h
@@ -0,0 +1,72 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: fstream.h,v 1.1 1995/10/18 08:38:12 deraadt Exp $
+
+#ifndef _FSTREAM_H
+#define _FSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <iostream.h>
+
+class fstreambase : virtual public ios {
+ public:
+ fstreambase();
+ fstreambase(int fd);
+ fstreambase(const char *name, int mode, int prot=0664);
+ void close();
+ filebuf* rdbuf() const { return (filebuf*)_strbuf; }
+ void open(const char *name, int mode, int prot=0664);
+ int is_open() const { return rdbuf()->is_open(); }
+ void setbuf(char *ptr, int len) { rdbuf()->setbuf(ptr, len); }
+#ifdef _STREAM_COMPAT
+ int filedesc() { return rdbuf()->fd(); }
+ fstreambase& raw() { rdbuf()->setbuf(NULL, 0); return *this; }
+#endif
+};
+
+class ifstream : public fstreambase, public istream {
+ public:
+ ifstream() : fstreambase() { }
+ ifstream(int fd) : fstreambase(fd) { }
+ ifstream(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(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) { }
+ void open(const char *name, int mode, int prot=0664)
+ { fstreambase::open(name, mode, prot); }
+};
+#endif /*!_FSTREAM_H*/
diff --git a/gnu/lib/libg++/iostream/igetline.C b/gnu/lib/libg++/iostream/igetline.C
new file mode 100644
index 00000000000..90ed189feaf
--- /dev/null
+++ b/gnu/lib/libg++/iostream/igetline.C
@@ -0,0 +1,135 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "iostream.h"
+#include <string.h>
+
+istream& istream::getline(char* buf, int len, char delim)
+{
+ _gcount = 0;
+ if (ipfx1()) {
+ streambuf *sb = rdbuf();
+ long count = sb->sgetline(buf, len, delim, -1);
+ if (count == len-1)
+ set(ios::failbit);
+ else {
+ int ch = sb->sbumpc();
+ if (ch == EOF)
+ set(ios::failbit|ios::eofbit);
+ else if (ch == (unsigned char)delim)
+ count++;
+ else
+ sb->sungetc(); // Leave delimiter unread.
+ }
+ _gcount = count;
+ }
+ return *this;
+}
+
+istream& istream::get(char* buf, int len, char delim)
+{
+ _gcount = 0;
+ if (ipfx1()) {
+ streambuf *sbuf = rdbuf();
+ long count = sbuf->sgetline(buf, len, delim, -1);
+ if (count < 0 || (count == 0 && sbuf->sgetc() == EOF))
+ set(ios::failbit|ios::eofbit);
+ else
+ _gcount = count;
+ }
+ return *this;
+}
+
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Free Software Foundation.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// 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+1];
+ char *ptr;
+ int ch;
+
+ long count = sb->sgetline(buf, CHUNK_SIZE+1, terminator, -1);
+ if (count == EOF)
+ return NULL;
+ ch = sb->sbumpc();
+ long old_total = total;
+ total += count;
+ if (ch != EOF && ch != terminator) {
+ total++; // Include ch in total.
+ ptr = _sb_readline(sb, total, terminator);
+ if (ptr) {
+ memcpy(ptr + old_total, buf, count);
+ ptr[old_total+count] = ch;
+ }
+ return ptr;
+ }
+
+ if (ptr = new char[total+1]) {
+ ptr[total] = '\0';
+ memcpy(ptr + total - count, buf, count);
+ return ptr;
+ }
+ else
+ return NULL;
+}
+
+/* Reads an arbitrarily long input line terminated by TERMINATOR.
+ This routine allocates its own memory, so the user should
+ only supply the address of a (char *). */
+
+istream& istream::gets(char **s, char delim /* = '\n' */)
+{
+ if (ipfx1()) {
+ long size = 0;
+ streambuf *sb = rdbuf();
+ *s = _sb_readline (sb, size, delim);
+ _gcount = *s ? size : 0;
+ if (sb->_flags & _S_EOF_SEEN) {
+ set(ios::eofbit);
+ if (_gcount == 0)
+ set(ios::failbit);
+ }
+ }
+ else {
+ _gcount = 0;
+ *s = NULL;
+ }
+ return *this;
+}
diff --git a/gnu/lib/libg++/iostream/igetsb.C b/gnu/lib/libg++/iostream/igetsb.C
new file mode 100644
index 00000000000..a6a2e6315d6
--- /dev/null
+++ b/gnu/lib/libg++/iostream/igetsb.C
@@ -0,0 +1,48 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "ioprivate.h"
+#include "iostream.h"
+
+istream& istream::get(streambuf& sb, char delim /* = '\n' */)
+{
+ _gcount = 0;
+ if (ipfx1()) {
+ register streambuf* isb = rdbuf();
+ for (;;) {
+ int len = isb->egptr() - isb->gptr();
+ if (len <= 0)
+ if (isb->underflow() == EOF)
+ break;
+ else
+ len = isb->egptr() - isb->gptr();
+ char *delimp = (char*)memchr((void*)isb->gptr(), delim, len);
+ if (delimp != NULL)
+ len = delimp - isb->gptr();
+ int written = sb.sputn(isb->gptr(), len);
+ isb->gbump(written);
+ _gcount += written;
+ if (written != len) {
+ set(ios::failbit);
+ break;
+ }
+ if (delimp != NULL)
+ break;
+ }
+ }
+ return *this;
+}
diff --git a/gnu/lib/libg++/iostream/indstream.C b/gnu/lib/libg++/iostream/indstream.C
new file mode 100644
index 00000000000..b58e362d4bd
--- /dev/null
+++ b/gnu/lib/libg++/iostream/indstream.C
@@ -0,0 +1,108 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <indstream.h>
+
+indirectbuf::indirectbuf(streambuf *get, streambuf *put, int delete_mode)
+: streambuf()
+{
+ _get_stream = get;
+ _put_stream = put == NULL ? get : put;
+ _delete_flags = delete_mode;
+}
+
+indirectbuf::~indirectbuf()
+{
+ if (_delete_flags & ios::in) delete get_stream();
+ if (_delete_flags & ios::out) delete put_stream();
+}
+
+int indirectbuf::xsputn(const char* s, int n)
+{
+ return put_stream()->sputn(s, n);
+}
+
+int indirectbuf::xsgetn(char* s, int n)
+{
+ return get_stream()->sgetn(s, n);
+}
+
+int indirectbuf::overflow(int c /* = EOF */)
+{
+ if (c == EOF)
+ return put_stream()->overflow(c);
+ else
+ return put_stream()->sputc(c);
+}
+
+int indirectbuf::underflow()
+{
+ return get_stream()->sbumpc();
+}
+
+streampos indirectbuf::seekoff(streamoff off, _seek_dir dir, int mode)
+{
+ int ret_val = 0;
+ int select = mode == 0 ? (ios::in|ios::out) : mode;
+ streambuf *gbuf = (select & ios::in) ? get_stream() : NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : NULL;
+ if (gbuf == pbuf)
+ ret_val = gbuf->seekoff(off, dir, mode);
+ else {
+ if (gbuf)
+ ret_val = gbuf->seekoff(off, dir, ios::in);
+ if (pbuf && ret_val != EOF)
+ ret_val = pbuf->seekoff(off, dir, ios::out);
+ }
+ return ret_val;
+}
+
+streampos indirectbuf::seekpos(streampos pos, int mode)
+{
+ int ret_val = EOF;
+ int select = mode == 0 ? (ios::in|ios::out) : mode;
+ streambuf *gbuf = (select & ios::in) ? get_stream() : NULL;
+ streambuf *pbuf = (select & ios::out) ? put_stream() : NULL;
+ if (gbuf == pbuf)
+ ret_val = gbuf->seekpos(pos, mode);
+ else {
+ if (gbuf)
+ ret_val = gbuf->seekpos(pos, ios::in);
+ if (pbuf && ret_val != EOF)
+ ret_val = pbuf->seekpos(pos, ios::out);
+ }
+ return ret_val;
+}
+
+int indirectbuf::sync()
+{
+ streambuf *gbuf = get_stream();
+ int ret_val = gbuf->sync();
+ if (ret_val == EOF) return ret_val;
+ streambuf *pbuf = put_stream();
+ if (pbuf != gbuf) return pbuf->sync();
+ else return ret_val;
+}
+
+int indirectbuf::pbackfail(int c)
+{
+ return get_stream()->sputbackc(c);
+}
diff --git a/gnu/lib/libg++/iostream/indstream.h b/gnu/lib/libg++/iostream/indstream.h
new file mode 100644
index 00000000000..5c3febe6b37
--- /dev/null
+++ b/gnu/lib/libg++/iostream/indstream.h
@@ -0,0 +1,67 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: indstream.h,v 1.1 1995/10/18 08:38:13 deraadt Exp $
+
+#ifndef _INDSTREAM_H
+#define _INDSTREAM_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <iostream.h>
+
+// An indirectbuf is one that forwards all of its I/O requests
+// to another streambuf.
+// All get-related requests are sent to get_stream().
+// All put-related requests are sent to put_stream().
+
+// An indirectbuf can be used to implement Common Lisp
+// synonym-streams and two-way-streams.
+//
+// class synonymbuf : public indirectbuf {
+// Symbol *sym;
+// synonymbuf(Symbol *s) { sym = s; }
+// virtual streambuf *lookup_stream(int mode) {
+// return coerce_to_streambuf(lookup_value(sym)); }
+// };
+
+class indirectbuf : public streambuf {
+ protected:
+ streambuf *_get_stream; // Optional cache for get_stream().
+ streambuf *_put_stream; // Optional cache for put_stream().
+ int _delete_flags;
+ public:
+ streambuf *get_stream()
+ { return _get_stream ? _get_stream : lookup_stream(ios::in); }
+ streambuf *put_stream()
+ { return _put_stream ? _put_stream : lookup_stream(ios::out); }
+ virtual streambuf *lookup_stream(int/*mode*/) { return NULL; } // ERROR!
+ indirectbuf(streambuf *get=NULL, streambuf *put=NULL, int delete_mode=0);
+ virtual ~indirectbuf();
+ virtual int xsputn(const char* s, int n);
+ virtual int xsgetn(char* s, int n);
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ virtual int sync();
+ virtual int pbackfail(int c);
+};
+
+#endif /* !_INDSTREAM_H */
diff --git a/gnu/lib/libg++/iostream/iomanip.C b/gnu/lib/libg++/iostream/iomanip.C
new file mode 100644
index 00000000000..b2aec86396b
--- /dev/null
+++ b/gnu/lib/libg++/iostream/iomanip.C
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+// This is part of the iostream library, providing parametrized manipulators
+// Written by Heinz G. Seidl, Copyright (C) 1992 Cygnus Support
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#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;
+}
diff --git a/gnu/lib/libg++/iostream/iomanip.h b/gnu/lib/libg++/iostream/iomanip.h
new file mode 100644
index 00000000000..25589a3f9f1
--- /dev/null
+++ b/gnu/lib/libg++/iostream/iomanip.h
@@ -0,0 +1,152 @@
+// -*- C++ -*-
+// This is part of the iostream library, providing parametrized manipulators
+// Written by Heinz G. Seidl, Copyright (C) 1992 Cygnus Support
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: iomanip.h,v 1.1 1995/10/18 08:38:13 deraadt Exp $
+
+#ifndef _IOMANIP_H
+//
+// Not specifying `pragma interface' causes the compiler to emit the
+// template definitions in the files, where they are used.
+//
+//#ifdef __GNUG__
+//#pragma interface
+//#endif
+#define _IOMANIP_H
+
+#include <_G_config.h>
+
+#ifndef _G_NO_TEMPLATES
+
+#include <iostream.h>
+
+//-----------------------------------------------------------------------------
+// Parametrized Manipulators as specified by ANSI draft
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class smanip; // TP = Type Param
+
+template<class TP> class sapp {
+ ios& (*_f)(ios&, TP);
+public:
+ sapp(ios& (*f)(ios&, TP)) : _f(f) {}
+ //
+ smanip<TP> operator()(TP a)
+ { return smanip<TP>(_f, a); }
+};
+
+template <class TP> class smanip {
+ ios& (*_f)(ios&, TP);
+ TP _a;
+public:
+ smanip(ios& (*f)(ios&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ istream& operator>>(istream& i, const smanip<TP>& m);
+ friend
+ ostream& operator<<(ostream& o, const smanip<TP>& m);
+};
+
+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;}
+
+//-----------------------------------------------------------------------------
+// Input-Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class imanip;
+
+template<class TP> class iapp {
+ istream& (*_f)(istream&, TP);
+public:
+ iapp(ostream& (*f)(istream&,TP)) : _f(f) {}
+ //
+ imanip<TP> operator()(TP a)
+ { return imanip<TP>(_f, a); }
+};
+
+template <class TP> class imanip {
+ istream& (*_f)(istream&, TP);
+ TP _a;
+public:
+ imanip(istream& (*f)(istream&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ istream& operator>>(istream& i, const imanip<TP>& m)
+ { return (*m._f)( i, m._a); }
+};
+
+
+//-----------------------------------------------------------------------------
+// Output-Stream Manipulators
+//-----------------------------------------------------------------------------
+//
+template<class TP> class omanip;
+
+template<class TP> class oapp {
+ ostream& (*_f)(ostream&, TP);
+public:
+ oapp(ostream& (*f)(ostream&,TP)) : _f(f) {}
+ //
+ omanip<TP> operator()(TP a)
+ { return omanip<TP>(_f, a); }
+};
+
+template <class TP> class omanip {
+ ostream& (*_f)(ostream&, TP);
+ TP _a;
+public:
+ omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {}
+ //
+ friend
+ ostream& operator<<(ostream& o, omanip<TP>& m)
+ { return (*m._f)(o, m._a); }
+};
+
+
+//-----------------------------------------------------------------------------
+// Available Manipulators
+//-----------------------------------------------------------------------------
+
+//
+// Macro to define an iomanip function, with one argument
+// The underlying function is `__iomanip_<name>'
+//
+#define __DEFINE_IOMANIP_FN1(type,param,function) \
+ extern ios& __iomanip_##function (ios&, param); \
+ inline type<param> function (param n) \
+ { return type<param> (__iomanip_##function, n); }
+
+__DEFINE_IOMANIP_FN1( smanip, int, setbase)
+__DEFINE_IOMANIP_FN1( smanip, int, setfill)
+__DEFINE_IOMANIP_FN1( smanip, int, setprecision)
+__DEFINE_IOMANIP_FN1( smanip, int, setw)
+
+__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, resetiosflags)
+__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, setiosflags)
+
+#endif /*!_G_NO_TEMPLATES*/
+#endif /*!_IOMANIP_H*/
diff --git a/gnu/lib/libg++/iostream/ioprivate.h b/gnu/lib/libg++/iostream/ioprivate.h
new file mode 100644
index 00000000000..b8b00c209b0
--- /dev/null
+++ b/gnu/lib/libg++/iostream/ioprivate.h
@@ -0,0 +1,66 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: ioprivate.h,v 1.1 1995/10/18 08:38:13 deraadt Exp $
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "streambuf.h"
+#include <stdarg.h>
+#include <stddef.h>
+
+#define _fstat(x, y) fstat(x,y)
+#define _isatty(fd) isatty(fd)
+
+extern int __cvt_double(double number, register int prec, int flags,
+ int *signp, int fmtch, char *startp, char *endp);
+
+/*#define USE_MALLOC_BUF*/
+
+#ifndef USE_MALLOC_BUF
+#define ALLOC_BUF(size) new char[size]
+#define FREE_BUF(ptr) delete [] (ptr)
+#else
+#define ALLOC_BUF(size) (char*)malloc(size)
+#define FREE_BUF(ptr) free(ptr)
+#endif
+
+#define USE_DTOA
+
+// Advantages:
+// - Input gets closest value
+// - Output emits string that when read yields identical value.
+// - Handles Infinity and NaNs (but not re-readable).
+// Disadvantages of dtoa:
+// - May not work for all double formats.
+// - Big chunck of code.
+// - Not reentrant - uses atatic variables freelist,
+// result, result_k in dtoa
+// (plus initializes p5s, HOWORD, and LOWORD).
+
+#ifdef USE_DTOA
+extern "C" double _Xstrtod(const char *s00, char **se);
+#define strtod(s, e) _Xstrtod(s, e)
+extern "C" char *dtoa(double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+extern int __outfloat(double value, streambuf *sb, char mode,
+ int width, int precision, __fmtflags flags,
+ char sign_mode, char fill);
+#endif
+
diff --git a/gnu/lib/libg++/iostream/iostream.C b/gnu/lib/libg++/iostream/iostream.C
new file mode 100644
index 00000000000..21e26c57475
--- /dev/null
+++ b/gnu/lib/libg++/iostream/iostream.C
@@ -0,0 +1,783 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991, 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#define _STREAM_COMPAT
+#include "ioprivate.h"
+#include <iostream.h>
+#include <stdio.h> /* Needed for sprintf */
+#include <ctype.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) : ios(sb, tied)
+{
+ _flags |= ios::dont_close;
+ _gcount = 0;
+}
+
+int skip_ws(streambuf* sb)
+{
+ int ch;
+ for (;;) {
+ ch = sb->sbumpc();
+ if (ch == EOF || !isspace(ch))
+ return ch;
+ }
+}
+
+istream& istream::get(char& c)
+{
+ if (ipfx1()) {
+ int ch = _strbuf->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ _gcount = 0;
+ }
+ else {
+ c = (char)ch;
+ _gcount = 1;
+ }
+ }
+ return *this;
+}
+
+int istream::peek()
+{
+ if (!good())
+ return EOF;
+ if (_tie && rdbuf()->in_avail() == 0)
+ _tie->flush();
+ int ch = _strbuf->sgetc();
+ if (ch == EOF)
+ set(ios::eofbit);
+ return ch;
+}
+
+istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
+{
+ if (ipfx1()) {
+ register streambuf* sb = _strbuf;
+ if (delim == EOF) {
+ _gcount = sb->ignore(n);
+ return *this;
+ }
+ _gcount = 0;
+ for (;;) {
+#if 0
+ if (n != MAXINT) // FIXME
+#endif
+ if (--n < 0)
+ break;
+ int ch = sb->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit|ios::failbit);
+ break;
+ }
+ _gcount++;
+ if (ch == delim)
+ break;
+ }
+ }
+ return *this;
+}
+
+istream& istream::read(char *s, int n)
+{
+ if (ipfx1()) {
+ _gcount = _strbuf->sgetn(s, n);
+ if (_gcount != n)
+ set(ios::failbit);
+ }
+ return *this;
+}
+
+istream& istream::seekg(streampos pos)
+{
+ pos = _strbuf->seekpos(pos, ios::in);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+istream& istream::seekg(streamoff off, _seek_dir dir)
+{
+ streampos pos = _strbuf->seekoff(off, dir, ios::in);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos istream::tellg()
+{
+ streampos pos = _strbuf->seekoff(0, ios::cur, ios::in);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+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, _G_va_list args)
+{
+ if (ipfx0())
+ _strbuf->vscan(format, args, this);
+ return *this;
+}
+
+istream& istream::operator>>(char& c)
+{
+ if (ipfx0()) {
+ int ch = _strbuf->sbumpc();
+ if (ch == EOF)
+ set(ios::eofbit|ios::failbit);
+ else
+ c = (char)ch;
+ }
+ return *this;
+}
+
+istream& istream::operator>>(char* ptr)
+{
+ register char *p = ptr;
+ int w = width(0);
+ if (ipfx0()) {
+ register streambuf* sb = _strbuf;
+ for (;;)
+ {
+ int ch = sb->sbumpc();
+ if (ch == EOF)
+ {
+ set(p == ptr ? (ios::eofbit|ios::failbit) : (ios::eofbit));
+ break;
+ }
+ else if (isspace(ch))
+ {
+ sb->sputbackc(ch);
+ break;
+ }
+ else if (w == 1)
+ {
+ set(ios::failbit);
+ sb->sputbackc(ch);
+ break;
+ }
+ else *p++ = ch;
+ w--;
+ }
+ }
+ *p = '\0';
+ return *this;
+}
+
+#ifdef __GNUC__
+#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)
+#ifdef __GNUG__
+READ_INT(long long)
+READ_INT(unsigned long long)
+#endif
+
+istream& istream::operator>>(double& x)
+{
+ if (ipfx0())
+ scan("%lg", &x);
+ return *this;
+}
+
+istream& istream::operator>>(float& x)
+{
+ if (ipfx0())
+ scan("%g", &x);
+ return *this;
+}
+
+istream& istream::operator>>(register streambuf* sbuf)
+{
+ if (ipfx0()) {
+ register streambuf* inbuf = rdbuf();
+ // FIXME: Should optimize!
+ for (;;) {
+ register int ch = inbuf->sbumpc();
+ if (ch == EOF) {
+ set(ios::eofbit);
+ break;
+ }
+ if (sbuf->sputc(ch) == EOF) {
+ set(ios::failbit);
+ break;
+ }
+ }
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(char c)
+{
+ if (opfx()) {
+#if 1
+ // This is what the cfront implementation does.
+ _strbuf->sputc(c);
+#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)) // Default adjustment.
+ while (--padding >= 0) sb->sputc(fill_char);
+ sb->sputc(c);
+ if (flags() & ios::left) // Left adjustment.
+ while (--padding >= 0) sb->sputc(fill_char);
+#endif
+ 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) && (val != 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) && (val != 0)) {
+ show_base = xdigs + 16; // Either "0X" or "0x".
+ show_base_len = 2;
+ }
+ }
+ else { // Decimal
+#ifdef __GNUC__
+ // 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.
+ sbuf->padn(fill_char, padding);
+ if (sign < 0) sbuf->sputc('-');
+ else if (show_pos) sbuf->sputc('+');
+ if (show_base_len)
+ sbuf->sputn(show_base, show_base_len);
+ if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
+ sbuf->padn(fill_char, padding);
+ sbuf->sputn(buf_ptr, buf_len);
+ if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
+ sbuf->padn(fill_char, padding);
+ stream.osfx();
+}
+
+ostream& ostream::operator<<(int n)
+{
+ if (opfx()) {
+ int sign = 1;
+ if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
+ n = -n, sign = -1;
+ write_int(*this, 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;
+ if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
+ n = -n, sign = -1;
+ write_int(*this, n, sign);
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(unsigned long n)
+{
+ if (opfx())
+ write_int(*this, n, 0);
+ return *this;
+}
+
+#ifdef __GNUG__
+ostream& ostream::operator<<(long long n)
+{
+ if (opfx()) {
+ int sign = 1;
+ if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
+ n = -n, sign = -1;
+ write_int(*this, n, sign);
+ }
+ return *this;
+}
+
+
+ostream& ostream::operator<<(unsigned long long n)
+{
+ if (opfx())
+ write_int(*this, n, 0);
+ return *this;
+}
+#endif /*__GNUG__*/
+
+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 0
+ if (flags() ios::showpos) sign = '+';
+#endif
+ 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 fpprec = 0; // 'Extra' (suppressed) floating precision.
+ int prec = precision();
+ if (prec > MAXFRACT) {
+ if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
+ fpprec = prec - MAXFRACT;
+ prec = MAXFRACT;
+ }
+ else if (prec <= 0 && !(flags() & ios::fixed))
+ prec = 6; /* default */
+
+ // Do actual conversion.
+#ifdef USE_DTOA
+ if (__outfloat(n, rdbuf(), format_char, width(0),
+ prec, flags(), 0, fill()) < 0)
+ set(ios::badbit|ios::failbit); // ??
+#else
+ 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 = '-';
+ 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.
+ sbuf->sputn(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);
+ char fill_char = fill();
+ register streambuf *sbuf = rdbuf();
+ register int padding = w > len ? w - len : 0;
+ if (!(flags() & ios::left)) // Default adjustment.
+ while (--padding >= 0) sbuf->sputc(fill_char);
+ sbuf->sputn(s, len);
+ if (flags() & ios::left) // Left adjustment.
+ while (--padding >= 0) sbuf->sputc(fill_char);
+ osfx();
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(const void *p)
+{
+ if (opfx()) {
+ form("%p", p);
+ osfx();
+ }
+ return *this;
+}
+
+ostream& ostream::operator<<(register streambuf* sbuf)
+{
+ if (opfx()) {
+ register streambuf* outbuf = rdbuf();
+ // FIXME: Should optimize!
+ for (;;) {
+ register int ch = sbuf->sbumpc();
+ if (ch == EOF) break;
+ if (outbuf->sputc(ch) == EOF) {
+ set(ios::badbit);
+ break;
+ }
+ }
+ osfx();
+ }
+ return *this;
+}
+
+ostream::ostream(streambuf* sb, ostream* tied) : ios(sb, tied)
+{
+ _flags |= ios::dont_close;
+}
+
+ostream& ostream::seekp(streampos pos)
+{
+ pos = _strbuf->seekpos(pos, ios::out);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+ostream& ostream::seekp(streamoff off, _seek_dir dir)
+{
+ streampos pos = _strbuf->seekoff(off, dir, ios::out);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return *this;
+}
+
+streampos ostream::tellp()
+{
+ streampos pos = _strbuf->seekoff(0, ios::cur, ios::out);
+ if (pos == streampos(EOF))
+ set(ios::badbit);
+ return pos;
+}
+
+ostream& ostream::form(const char *format ...)
+{
+ if (opfx()) {
+ va_list ap;
+ va_start(ap, format);
+ _strbuf->vform(format, ap);
+ va_end(ap);
+ }
+ return *this;
+}
+
+ostream& ostream::vform(const char *format, _G_va_list args)
+{
+ if (opfx())
+ _strbuf->vform(format, args);
+ return *this;
+}
+
+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, int n)
+{
+ if (opfx()) {
+ if (_strbuf->sputn(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) : ios(sb, tied)
+{
+ _flags |= ios::dont_close;
+ _gcount = 0;
+}
+
+// NOTE: extension for compatibility with old libg++.
+// Not really compatible with fistream::close().
+#ifdef _STREAM_COMPAT
+void ios::close()
+{
+ if (!(_flags & (unsigned int)ios::dont_close))
+ delete _strbuf;
+ else if (_strbuf->_flags & _S_IS_FILEBUF)
+ ((struct filebuf*)_strbuf)->close();
+ else if (_strbuf != NULL)
+ _strbuf->sync();
+ _flags |= ios::dont_close;
+ _strbuf = NULL;
+ _state = badbit;
+}
+
+int istream::skip(int i)
+{
+ int old = (_flags & ios::skipws) != 0;
+ if (i)
+ _flags |= ios::skipws;
+ else
+ _flags &= ~ios::skipws;
+ return old;
+}
+#endif
diff --git a/gnu/lib/libg++/iostream/iostream.h b/gnu/lib/libg++/iostream/iostream.h
new file mode 100644
index 00000000000..d6742721524
--- /dev/null
+++ b/gnu/lib/libg++/iostream/iostream.h
@@ -0,0 +1,228 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: iostream.h,v 1.1 1995/10/18 08:38:13 deraadt Exp $
+
+#ifndef _IOSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#define _IOSTREAM_H
+
+#include <streambuf.h>
+
+class istream; class ostream;
+typedef ios& (*__manip)(ios&);
+typedef istream& (*__imanip)(istream&);
+typedef ostream& (*__omanip)(ostream&);
+
+extern istream& ws(istream& ins);
+extern ostream& flush(ostream& outs);
+extern ostream& endl(ostream& outs);
+extern ostream& ends(ostream& outs);
+
+class ostream : virtual public ios
+{
+ // NOTE: If fields are changed, you must fix _fake_ostream in stdstreams.C!
+ void do_osfx();
+ public:
+ ostream() { }
+ ostream(streambuf* sb, ostream* tied=NULL);
+ int opfx() {
+ if (!good()) return 0; else { if (_tie) _tie->flush(); return 1;} }
+ void osfx() { if (flags() & (ios::unitbuf|ios::stdio))
+ do_osfx(); }
+ streambuf* ostreambuf() const { return _strbuf; }
+ ostream& flush();
+ ostream& put(char c) { _strbuf->sputc(c); return *this; }
+ ostream& put(unsigned char c) { return put((char)c); }
+
+ ostream& write(const char *s, int n);
+ ostream& write(const unsigned char *s, int n) { return write((const char*)s, n);}
+#ifndef _G_BROKEN_SIGNED_CHAR
+ ostream& put(signed char c) { return put((char)c); }
+ ostream& write(const signed char *s, int n) { return write((const char*)s, n);}
+#endif
+ ostream& write(const void *s, int n) { return write((const char*)s, n);}
+ ostream& seekp(streampos);
+ ostream& seekp(streamoff, _seek_dir);
+ streampos tellp();
+ ostream& form(const char *format ...);
+ ostream& vform(const char *format, _G_va_list args);
+
+ ostream& operator<<(char c);
+ ostream& operator<<(unsigned char c) { return (*this) << (char)c; }
+#ifndef _G_BROKEN_SIGNED_CHAR
+ ostream& operator<<(signed char c) { return (*this) << (char)c; }
+#endif
+ ostream& operator<<(const char *s);
+ ostream& operator<<(const unsigned char *s)
+ { return (*this) << (const char*)s; }
+#ifndef _G_BROKEN_SIGNED_CHAR
+ ostream& operator<<(const signed char *s)
+ { return (*this) << (const char*)s; }
+#endif
+ ostream& operator<<(const void *p);
+ ostream& operator<<(int n);
+ ostream& operator<<(unsigned int n);
+ ostream& operator<<(long n);
+ ostream& operator<<(unsigned long n);
+#ifdef __GNUG__
+ 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);}
+ ostream& operator<<(double n);
+ ostream& operator<<(float n) { return operator<<((double)n); }
+ ostream& operator<<(__omanip func) { return (*func)(*this); }
+ ostream& operator<<(__manip func) {(*func)(*this); return *this;}
+ ostream& operator<<(streambuf*);
+};
+
+class istream : virtual public ios
+{
+ // NOTE: If fields are changed, you must fix _fake_istream in stdstreams.C!
+ _G_ssize_t _gcount;
+
+ int _skip_ws();
+ public:
+ istream() { _gcount = 0; }
+ istream(streambuf* sb, ostream*tied=NULL);
+ streambuf* istreambuf() const { return _strbuf; }
+ 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); }
+#ifndef _G_BROKEN_SIGNED_CHAR
+ 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); }
+#endif
+ istream& read(char *ptr, int n);
+ istream& read(unsigned char *ptr, int n) { return read((char*)ptr, n); }
+#ifndef _G_BROKEN_SIGNED_CHAR
+ istream& read(signed char *ptr, int n) { return read((char*)ptr, n); }
+#endif
+ istream& read(void *ptr, int n) { return read((char*)ptr, n); }
+ istream& get(streambuf& sb, char delim = '\n');
+ istream& gets(char **s, char delim = '\n');
+ int ipfx(int need) {
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush();
+ if (!need && (flags() & ios::skipws)) return _skip_ws();
+ else return 1;
+ }
+ }
+ int ipfx0() { // Optimized version of ipfx(0).
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ if (_tie) _tie->flush();
+ if (flags() & ios::skipws) return _skip_ws();
+ else return 1;
+ }
+ }
+ int ipfx1() { // Optimized version of ipfx(1).
+ if (!good()) { set(ios::failbit); return 0; }
+ else {
+ if (_tie && rdbuf()->in_avail() == 0) _tie->flush();
+ return 1;
+ }
+ }
+ void isfx() { }
+ int get() { if (!ipfx1()) return EOF;
+ else { int ch = _strbuf->sbumpc();
+ if (ch == EOF) set(ios::eofbit);
+ return ch;
+ } }
+ int peek();
+ _G_ssize_t gcount() { return _gcount; }
+ istream& ignore(int n=1, int delim = EOF);
+ istream& seekg(streampos);
+ istream& seekg(streamoff, _seek_dir);
+ streampos tellg();
+ istream& putback(char ch) {
+ if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::badbit);
+ return *this;}
+ istream& unget() {
+ if (good() && _strbuf->sungetc() == EOF) clear(ios::badbit);
+ return *this;}
+ istream& scan(const char *format ...);
+ istream& vscan(const char *format, _G_va_list args);
+#ifdef _STREAM_COMPAT
+ istream& unget(char ch) { return putback(ch); }
+ int skip(int i);
+#endif
+
+ istream& operator>>(char*);
+ istream& operator>>(unsigned char* p) { return operator>>((char*)p); }
+#ifndef _G_BROKEN_SIGNED_CHAR
+ istream& operator>>(signed char*p) { return operator>>((char*)p); }
+#endif
+ istream& operator>>(char& c);
+ istream& operator>>(unsigned char& c) {return operator>>((char&)c);}
+#ifndef _G_BROKEN_SIGNED_CHAR
+ istream& operator>>(signed char& c) {return operator>>((char&)c);}
+#endif
+ istream& operator>>(int&);
+ istream& operator>>(long&);
+#ifdef __GNUG__
+ istream& operator>>(long long&);
+#endif
+ istream& operator>>(short&);
+ istream& operator>>(unsigned int&);
+ istream& operator>>(unsigned long&);
+#ifdef __GNUG__
+ istream& operator>>(unsigned long long&);
+#endif
+ istream& operator>>(unsigned short&);
+ istream& operator>>(float&);
+ istream& operator>>(double&);
+ istream& operator>>( __manip func) {(*func)(*this); return *this;}
+ istream& operator>>(__imanip func) { return (*func)(*this); }
+ istream& operator>>(streambuf*);
+};
+
+
+class iostream : public istream, public ostream
+{
+ _G_ssize_t _gcount;
+ public:
+ iostream() { _gcount = 0; }
+ iostream(streambuf* sb, ostream*tied=NULL);
+};
+
+extern istream cin;
+extern ostream cout, cerr, clog; // clog->rdbuf() == cerr->rdbuf()
+
+struct Iostream_init { } ; // Compatibility hack for AT&T library.
+
+inline ios& dec(ios& i)
+{ i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; }
+inline ios& hex(ios& i)
+{ i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; }
+inline ios& oct(ios& i)
+{ i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; }
+
+#endif /*!_IOSTREAM_H*/
diff --git a/gnu/lib/libg++/iostream/makebuf.C b/gnu/lib/libg++/iostream/makebuf.C
new file mode 100644
index 00000000000..592f59ec396
--- /dev/null
+++ b/gnu/lib/libg++/iostream/makebuf.C
@@ -0,0 +1,71 @@
+/*
+ * 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.
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+#include "ioprivate.h"
+#include "fstream.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/*
+ * 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 filebuf::doallocate()
+{
+ register size_t size, couldbetty;
+ register char *p;
+ struct stat st;
+
+ if (fd() < 0 || _fstat(fd(), &st) < 0) {
+ couldbetty = 0;
+ size = _G_BUFSIZ;
+#if 0
+ /* do not try to optimise fseek() */
+ fp->_flags |= __SNPT;
+#endif
+ } else {
+ couldbetty = S_ISCHR(st.st_mode);
+#if _G_HAVE_ST_BLKSIZE
+ size = st.st_blksize <= 0 ? _G_BUFSIZ : st.st_blksize;
+#else
+ size = _G_BUFSIZ;
+#endif
+ }
+#ifdef USE_MALLOC_BUF
+ if ((p = malloc(size)) == NULL) {
+ unbuffered(1);
+// fp->_bf._base = fp->_p = fp->_nbuf;
+// fp->_bf._size = 1;
+ return EOF;
+ }
+#else
+ p = ALLOC_BUF(size);
+#endif
+ setb(p, p+size, 1);
+ if (couldbetty && _isatty(fd()))
+ _flags |= _S_LINE_BUF;
+ return 1;
+}
diff --git a/gnu/lib/libg++/iostream/outfloat.C b/gnu/lib/libg++/iostream/outfloat.C
new file mode 100644
index 00000000000..c677844b839
--- /dev/null
+++ b/gnu/lib/libg++/iostream/outfloat.C
@@ -0,0 +1,183 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "ioprivate.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 __outfloat(double value, streambuf *sb, char type,
+ int width, int precision, ios::fmtflags flags,
+ char sign_mode, char fill)
+{
+ int count = 0;
+#define PUT(x) do {if (sb->sputc(x) < 0) goto error; count++;} while (0)
+#define PUTN(p, n) \
+ do {int _n=n; count+=_n; if (sb->sputn(p,_n) != _n) goto error;} while(0)
+#define PADN(fill, n) \
+ do {int _n = n; count+=_n; if (sb->padn(fill, _n) < 0) goto error;} while (0)
+ ios::fmtflags pad_kind = flags & (ios::left|ios::right|ios::internal);
+ int skip_zeroes = 0;
+ int show_dot = (flags & ios::showpoint) != 0;
+ int decpt;
+ int sign;
+ int mode;
+#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 & ios::showpoint))
+ skip_zeroes = 1;
+ type = 'g';
+ mode = 2;
+ break;
+ }
+ /* Do the actual convension */
+ if (precision == 999 && mode != 3)
+ mode = 0;
+ char *p = dtoa(value, mode, precision, &decpt, &sign, &end);
+ register int i;
+ int useful_digits = end-p;
+ char *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;
+ }
+ }
+ int 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).
+ int trailing_zeroes = 0;
+ 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;
+ int print_sign;
+ 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).
+ int unpadded_width =
+ (print_sign != 0) + trailing_zeroes + exponent_size + show_dot
+ + useful_digits
+ + (decpt > useful_digits ? decpt - useful_digits
+ : decpt > 0 ? 0 : 1 - decpt);
+
+ int padding = width > unpadded_width ? width - unpadded_width : 0;
+ if (padding > 0
+ && pad_kind != (ios::fmtflags)ios::left
+ && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
+ PADN(fill, padding);
+ if (print_sign)
+ PUT(print_sign);
+ if (pad_kind == (ios::fmtflags)ios::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 == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
+ PADN(fill, padding);
+ return count;
+ error:
+ return EOF;
+}
diff --git a/gnu/lib/libg++/iostream/parsestream.C b/gnu/lib/libg++/iostream/parsestream.C
new file mode 100644
index 00000000000..49135da7709
--- /dev/null
+++ b/gnu/lib/libg++/iostream/parsestream.C
@@ -0,0 +1,307 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "ioprivate.h"
+#include "parsestream.h"
+
+streambuf* parsebuf::setbuf(char*, int)
+{
+ return NULL;
+}
+
+int parsebuf::tell_in_line()
+{
+ return 0;
+}
+
+int parsebuf::pbackfail(int c)
+{
+ if (c == EOF)
+ return 0;
+ if (seekoff(-1, ios::cur) == EOF)
+ return EOF;
+ return (unsigned char)c;
+}
+
+char* parsebuf::current_line() { return NULL; }
+
+streampos parsebuf::seekoff(streamoff offset, _seek_dir dir, int)
+{
+ // Make offset relative to line start.
+ switch (dir) {
+ case ios::beg:
+ offset -= pos_at_line_start;
+ break;
+ case ios::cur:
+ offset += tell_in_line();
+ break;
+ default:
+ return EOF;
+ }
+ if (offset < -1)
+ return EOF;
+ if (offset > _line_length + 1)
+ return EOF;
+ return seek_in_line(offset) + pos_at_line_start;
+}
+
+// string_parsebuf invariants:
+// The reserve ares (base() .. ebuf()) is always the entire string.
+// The get area (eback() .. egptr()) is the extended current line
+// (i.e. with the '\n' at either end, if these exist).
+
+string_parsebuf::string_parsebuf(char *buf, int len,
+ int delete_at_close /* = 0*/)
+: parsebuf()
+{
+ setb(buf, buf+len, delete_at_close);
+ register char *ptr = buf;
+ while (ptr < ebuf() && *ptr != '\n') ptr++;
+ _line_length = ptr - buf;
+ setg(buf, buf, ptr);
+}
+
+int string_parsebuf::underflow()
+{
+ register char* ptr = egptr(); // Point to end of current_line
+ do {
+ int i = right() - ptr;
+ if (i <= 0)
+ return EOF;
+ ptr++; i--; // Skip '\n'.
+ char *line_start = ptr;
+ while (ptr < right() && *ptr == '\n') ptr++;
+ setg(line_start-1, line_start, ptr + (ptr < right()));
+ pos_at_line_start = line_start - left();
+ _line_length = ptr - line_start;
+ __line_number++;
+ } while (gptr() == ptr);
+ return *gptr();
+}
+
+char* string_parsebuf::current_line()
+{
+ char *ptr = eback();
+ if (__line_number > 0)
+ ptr++; // Skip '\n' at end of previous line.
+ return ptr;
+}
+
+int string_parsebuf::tell_in_line()
+{
+ int offset = gptr() - eback();
+ if (__line_number > 0)
+ offset--;
+ return offset;
+}
+
+int string_parsebuf::seek_in_line(int i)
+{
+ int delta = i - tell_in_line();
+ gbump(delta); // FIXME: Needs error (bounds) checking!
+ return i;
+}
+
+static const char NewLine[1] = { '\n' };
+
+general_parsebuf::general_parsebuf(streambuf *buf, int delete_arg_buf)
+ : parsebuf()
+{
+ delete_buf = delete_arg_buf;
+ sbuf = buf;
+ int buf_size = 128;
+ char* buffer = ALLOC_BUF(buf_size);
+ setb(buffer, buffer+buf_size, 1);
+// setg(buffer, buffer, buffer);
+}
+
+general_parsebuf::~general_parsebuf()
+{
+ if (delete_buf)
+ delete sbuf;
+}
+
+int general_parsebuf::underflow()
+{
+ register char *ptr = base();
+ int has_newline = eback() < gptr() && gptr()[-1] == '\n';
+ if (has_newline)
+ *ptr++ = '\n';
+ register streambuf *sb = sbuf;
+ register int ch;
+ for (;;) {
+ ch = sb->sbumpc();
+ if (ch == EOF)
+ break;
+ if (ptr == ebuf()) {
+ int old_size = ebuf() - base();
+ char *new_buffer = new char[old_size * 2];
+ memcpy(new_buffer, base(), old_size);
+ setb(new_buffer, new_buffer + 2 * old_size, 1);
+ ptr = new_buffer + old_size;
+ }
+ *ptr++ = ch;
+ if (ch == '\n')
+ break;
+ }
+ char *cur_pos = base() + has_newline;
+ pos_at_line_start += _line_length + 1;
+ _line_length = ptr - cur_pos;
+ if (ch != EOF || _line_length > 0)
+ __line_number++;
+ setg(base(), cur_pos, ptr);
+ return ptr == cur_pos ? EOF : cur_pos[0];
+}
+
+char* general_parsebuf::current_line()
+{
+ char* ret = base();
+ if (__line_number > 1)
+ ret++; // Move past '\n' from end of previous line.
+ return ret;
+}
+
+int general_parsebuf::tell_in_line()
+{
+ int off = gptr() - base();
+ if (__line_number > 1)
+ off--; // Subtract 1 for '\n' from end of previous line.
+ return off;
+}
+
+int general_parsebuf::seek_in_line(int i)
+{
+ if (__line_number == 0)
+ (void)general_parsebuf::underflow();
+ if (__line_number > 1)
+ i++; // Add 1 for '\n' from end of previous line.
+ if (i < 0) i = 0;
+ int len = egptr() - eback();
+ if (i > len) i = len;
+ setg(base(), base() + i, egptr());
+ return i;
+}
+
+func_parsebuf::func_parsebuf(CharReader func, void *argm) : parsebuf()
+{
+ read_func = func;
+ arg = argm;
+ buf_start = NULL;
+ buf_end = NULL;
+ setb((char*)NewLine, (char*)NewLine+1, 0);
+ setg((char*)NewLine, (char*)NewLine+1, (char*)NewLine+1);
+ backed_up_to_newline = 0;
+}
+
+int func_parsebuf::tell_in_line()
+{
+ if (buf_start == NULL)
+ return 0;
+ if (egptr() != (char*)NewLine+1)
+ // Get buffer was line buffer.
+ return gptr() - buf_start;
+ if (backed_up_to_newline)
+ return -1; // Get buffer is '\n' preceding current line.
+ // Get buffer is '\n' following current line.
+ return (buf_end - buf_start) + (gptr() - (char*)NewLine);
+}
+
+char* func_parsebuf::current_line()
+{
+ return buf_start;
+}
+
+int func_parsebuf::seek_in_line(int i)
+{
+ if (i < 0) {
+ // Back up to preceding '\n'.
+ if (i < -1) i = -1;
+ backed_up_to_newline = 1;
+ setg((char*)NewLine, (char*)NewLine+(i+1), (char*)NewLine+1);
+ return i;
+ }
+ backed_up_to_newline = 0;
+ int line_length = buf_end-buf_start;
+ if (i <= line_length) {
+ setg(buf_start, buf_start+i, buf_end);
+ return i;
+ }
+ i -= line_length;
+ if (i > 0) i = 1;
+ setg((char*)NewLine, (char*)NewLine+i, (char*)NewLine+1);
+ return line_length + i;
+}
+
+int func_parsebuf::underflow()
+{
+ retry:
+ if (gptr() < egptr())
+ return *gptr();
+ if (gptr() != (char*)NewLine+1) {
+ // Get buffer was line buffer. Move to following '\n'.
+ setg((char*)NewLine, (char*)NewLine, (char*)NewLine+1);
+ return *gptr();
+ }
+ if (backed_up_to_newline)
+ // Get buffer was '\n' preceding current line. Move to current line.
+ backed_up_to_newline = 0;
+ else {
+ // Get buffer was '\n' following current line. Read new line.
+ if (buf_start) free(buf_start);
+ char *str = (*read_func)(arg);
+ buf_start = str;
+ if (str == NULL)
+ return EOF;
+ // Initially, _line_length == -1, so pos_at_line_start becomes 0.
+ pos_at_line_start += _line_length + 1;
+ _line_length = strlen(str);
+ buf_end = str + _line_length;
+ __line_number++;
+ }
+ setg(buf_start, buf_start, buf_end);
+ goto retry;
+}
+
+#if 0
+size_t parsebuf::line_length()
+{
+ if (current_line_length == (size_t)(-1)) // Initial value;
+ (void)sgetc();
+ return current_line_length;
+}
+#endif
+
+int parsebuf::seek_in_line(int i)
+{
+#if 1
+ abort();
+ return 0; // Suppress warning.
+#else
+ if (i > 0) {
+ size_t len = line_length();
+ if ((unsigned)i > len) i = len;
+ }
+ else if (i < -1) i = -1;
+ int new_pos = seekoff(pos_at_line_start + i, ios::beg);
+ if (new_pos == EOF)
+ return tell_in_line();
+ else return new_pos - pos_at_line_start;
+#endif
+}
diff --git a/gnu/lib/libg++/iostream/parsestream.h b/gnu/lib/libg++/iostream/parsestream.h
new file mode 100644
index 00000000000..95c1242928a
--- /dev/null
+++ b/gnu/lib/libg++/iostream/parsestream.h
@@ -0,0 +1,147 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: parsestream.h,v 1.1 1995/10/18 08:38:13 deraadt Exp $
+
+#ifndef PARSESTREAM_H
+#define PARSESTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include "streambuf.h"
+
+// A parsebuf is a streambuf optimized for scanning text files.
+// It keeps track of line and column numbers.
+// It is guaranteed to remember the entire current line,
+// as well the '\n'-s on either side of it (if they exist).
+// You can arbitrarily seek (or unget) within this extended line.
+// Other backward seeks are not supported.
+// Normal read semantics are supported (and hence istream operators like >>).
+
+class parsebuf : public backupbuf {
+ protected:
+ _G_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() : backupbuf() { chain= NULL;
+ __line_number = 0; pos_at_line_start = 0; _line_length = -1; }
+ virtual int pbackfail(int c);
+};
+
+// A string_parsebuf is a parsebuf whose source is a fixed string.
+
+class string_parsebuf : public parsebuf {
+ public:
+ int do_delete;
+ string_parsebuf(char *str, int len, int delete_at_close=0);
+ virtual int underflow();
+ virtual char* current_line();
+ virtual int seek_in_line(int i);
+ virtual int tell_in_line();
+ char *left() const { return base(); }
+ char *right() const { return ebuf(); }
+// streampos seekoff(streamoff, _seek_dir, int);
+};
+
+// A func_parsebuf calls a given function to get new input.
+// Each call returns an entire NUL-terminated line (without the '\n').
+// That line has been allocated with malloc(), not new.
+// The interface is tailored to the GNU readline library.
+// Example:
+// char* DoReadLine(void* arg)
+// {
+// char *line = readline((char*)arg); /* 'arg' is used as prompt. */
+// if line == NULL) { putc('\n', stderr); return NULL; }
+// if (line[0] != '\0') add_history(line);
+// return line;
+// }
+// char PromptBuffer[100] = "> ";
+// func_parsebuf my_stream(DoReadLine, PromptBuffer);
+
+typedef char *(*CharReader)(void *arg);
+class istream;
+
+class func_parsebuf : public parsebuf {
+ public:
+ void *arg;
+ CharReader read_func;
+ int backed_up_to_newline;
+ func_parsebuf(CharReader func, void *argm = NULL);
+ int underflow();
+ virtual int tell_in_line();
+ virtual int seek_in_line(int i);
+ virtual char* current_line();
+};
+
+// A general_parsebuf is a parsebuf which gets its input from some
+// other streambuf. It explicitly buffers up an entire line.
+
+class general_parsebuf : public parsebuf {
+ public:
+ streambuf *sbuf;
+ int delete_buf; // Delete sbuf when destroying this.
+ general_parsebuf(streambuf *buf, int delete_arg_buf = 0);
+ int underflow();
+ virtual int tell_in_line();
+ virtual int seek_in_line(int i);
+ ~general_parsebuf();
+ virtual char* current_line();
+};
+
+#if 0
+class parsestream : public istream {
+ streammarker marks[2];
+ short _first; // of the two marks; either 0 or 1
+ int _lineno;
+ int first() { return _first; }
+ int second() { return 1-_first; }
+ int line_length() { marks[second].delta(marks[first]); }
+ int line_length() { marks[second].delta(marks[first]); }
+ int seek_in_line(int i);
+ int tell_in_line();
+ int line_number();
+};
+#endif
+#endif /*!defined(PARSESTREAM_H)*/
diff --git a/gnu/lib/libg++/iostream/procbuf.C b/gnu/lib/libg++/iostream/procbuf.C
new file mode 100644
index 00000000000..842cd3c41e2
--- /dev/null
+++ b/gnu/lib/libg++/iostream/procbuf.C
@@ -0,0 +1,126 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#define _POSIX_SOURCE
+#include "ioprivate.h"
+#include "procbuf.h"
+#include <signal.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+#ifndef FORK
+#define FORK vfork
+#ifndef __NetBSD__
+extern "C" _G_pid_t vfork(void);
+#else
+extern "C" int vfork(void);
+#endif
+#endif
+
+procbuf::procbuf(const char *command, int mode) : filebuf()
+{
+ open(command, mode);
+}
+
+procbuf *procbuf::open(const char *command, int mode)
+{
+ int read_or_write;
+ if (is_open())
+ return NULL;
+ int pipe_fds[2];
+ int parent_end, child_end;
+ if (::pipe(pipe_fds) < 0)
+ return NULL;
+ if (mode == ios::in) {
+ parent_end = pipe_fds[0];
+ child_end = pipe_fds[1];
+ read_or_write = _S_NO_WRITES;
+ }
+ else {
+ parent_end = pipe_fds[1];
+ child_end = pipe_fds[0];
+ read_or_write = _S_NO_READS;
+ }
+ _pid = FORK();
+ if (_pid == 0) {
+ ::close(parent_end);
+ int child_std_end = mode == ios::in ? 1 : 0;
+ if (child_end != child_std_end) {
+ ::dup2(child_end, child_std_end);
+ ::close(child_end);
+ }
+ ::execl("/bin/sh", "sh", "-c", command, NULL);
+ ::_exit(127);
+ }
+ ::close(child_end);
+ if (_pid < 0) {
+ ::close(parent_end);
+ return NULL;
+ }
+ _fb._fileno = parent_end;
+ xsetflags(read_or_write, _S_NO_READS|_S_NO_WRITES);
+ return this;
+}
+
+/* #define USE_SIGMASK */
+
+int procbuf::sys_close()
+{
+ _G_pid_t wait_pid;
+ int status = filebuf::sys_close();
+ if (status < 0)
+ return status;
+ int wstatus;
+#if defined(SIG_BLOCK) && defined(SIG_SETMASK)
+ sigset_t set, oset;
+ sigemptyset (&set);
+ sigaddset (&set, SIGINT);
+ sigaddset (&set, SIGQUIT);
+ sigaddset (&set, SIGHUP);
+ sigprocmask (SIG_BLOCK, &set, &oset);
+#else
+#ifdef USE_SIGMASK
+ int mask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGHUP));
+#else
+ typedef void (*void_func)(int);
+ void_func intsave = (void_func)signal(SIGINT, SIG_IGN);
+ void_func quitsave = (void_func)signal(SIGQUIT, SIG_IGN);
+ void_func hupsave = (void_func)signal(SIGHUP, SIG_IGN);
+#endif
+#endif
+ while ((wait_pid = wait(&wstatus)) != _pid && wait_pid != -1) { }
+#if defined(SIG_BLOCK) && defined(SIG_SETMASK)
+ sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+#else
+#ifdef USE_SIGMASK
+ (void) sigsetmask(mask);
+#else
+ signal(SIGINT, intsave);
+ signal(SIGQUIT, quitsave);
+ signal(SIGHUP, hupsave);
+#endif
+#endif
+ if (wait_pid == -1)
+ return -1;
+ return 0;
+}
+
+procbuf::~procbuf()
+{
+ close();
+}
diff --git a/gnu/lib/libg++/iostream/procbuf.h b/gnu/lib/libg++/iostream/procbuf.h
new file mode 100644
index 00000000000..1100fcfc792
--- /dev/null
+++ b/gnu/lib/libg++/iostream/procbuf.h
@@ -0,0 +1,31 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: procbuf.h,v 1.1 1995/10/18 08:38:13 deraadt Exp $
+
+#include <streambuf.h>
+
+class procbuf : public filebuf {
+ _G_pid_t _pid;
+ public:
+ procbuf() : filebuf() { }
+ procbuf(const char *command, int mode);
+ procbuf* open(const char *command, int mode);
+ procbuf *close() { return (procbuf*)filebuf::close(); }
+ virtual int sys_close();
+ ~procbuf();
+};
diff --git a/gnu/lib/libg++/iostream/sbufvform.C b/gnu/lib/libg++/iostream/sbufvform.C
new file mode 100644
index 00000000000..533fd719d09
--- /dev/null
+++ b/gnu/lib/libg++/iostream/sbufvform.C
@@ -0,0 +1,856 @@
+/*
+ * 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 "ioprivate.h"
+#include <string.h>
+#include <stdarg.h>
+
+/*
+ * Define FLOATING_POINT to get floating point.
+ */
+#ifndef NO_FLOATING_POINT
+#define FLOATING_POINT
+#endif
+
+/* end of configuration stuff */
+
+
+/*
+ * Helper class and function for `fprintf to unbuffered': creates a
+ * temporary buffer. We only work on write-only files; this avoids
+ * worries about ungetc buffers and so forth.
+ */
+
+class help_streambuf : public backupbuf {
+ public:
+ char *buffer;
+ int buf_size;
+ streambuf *sb;
+ help_streambuf(streambuf *sbuf, char *buf, int n) {
+ sb = sbuf; buffer = buf; buf_size = n;
+ setp(buffer, buffer+buf_size); }
+ ~help_streambuf();
+ virtual int overflow(int c = EOF);
+};
+
+int help_streambuf::overflow(int c)
+{
+ int used = pptr() - pbase();
+ if (used) {
+ sb->sputn(pbase(), used);
+ pbump(-used);
+ }
+ if (c == EOF || buf_size == 0)
+ return sb->overflow(c);
+ return sputc(c);
+}
+help_streambuf::~help_streambuf()
+{
+ int used = pptr() - pbase();
+ if (used) {
+ sb->sputn(pbase(), used);
+ pbump(-used);
+ }
+}
+
+int help_vform(streambuf *sb, char const *fmt0, va_list ap)
+{
+ char buf[_G_BUFSIZ];
+ help_streambuf helper(sb, buf, _G_BUFSIZ);
+ return helper.vform(fmt0, ap);
+}
+
+#ifdef FLOATING_POINT
+
+#include "floatio.h"
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+#define DEFPREC 6
+extern "C" double modf(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 streambuf::vform(char const *fmt0, _G_va_list ap)
+{
+ register const char *fmt; /* format string */
+ register int ch; /* character from fmt */
+ register int n; /* handy integer (short term usage) */
+ register char *cp; /* handy char pointer (short term usage) */
+ const char *fmark; /* for remembering a place in fmt */
+ register int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format (%.3d), or -1 */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+#ifdef FLOATING_POINT
+ int softsign; /* temporary negative sign for floats */
+ double _double; /* double precision arguments %[eEfgG] */
+#ifndef USE_DTOA
+ int fpprec; /* `extra' floating precision in [eEfgG] */
+#endif
+#endif
+ unsigned long _ulong; /* integer arguments %[diouxX] */
+ enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int dpad; /* extra 0 padding needed for integers */
+ int fieldsz; /* field size expanded by sign, dpad etc */
+ // The initialization of 'size' is to suppress a warning that
+ // 'size' might be used unitialized. It seems gcc can't
+ // quite grok this spaghetti code ...
+ int size = 0; /* size of converted field or string */
+ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
+ char ox[2]; /* space for 0x hex-prefix */
+
+ /*
+ * Choose PADSIZE to trade efficiency vs size. If larger
+ * printf fields occur frequently, increase PADSIZE (and make
+ * the initialisers below longer).
+ */
+#define PADSIZE 16 /* pad chunk size */
+ 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'};
+
+ /*
+ * BEWARE, these `goto error' on error, and PAD uses `n'.
+ */
+#define PRINT(ptr, len) \
+ do { if (sputn(ptr, len) != len) goto error; } while (0)
+#if 1
+#define PAD_SP(howmany) if (padn(' ', howmany) < 0) goto error;
+#define PAD_0(howmany) if (padn('0', howmany) < 0) goto error;
+#else
+#define PAD(howmany, with) { \
+ if ((n = (howmany)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT(with, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT(with, n); \
+ } \
+}
+#define PAD_SP(howmany) PAD(howmany, blanks)
+#define PAD_0(howmany) PAD(howmany, zeroes)
+#endif
+
+ /*
+ * 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 cerr (and other unbuffered Unix files) */
+ if (unbuffered())
+ return help_vform(this, fmt0, ap);
+
+ fmt = fmt0;
+ ret = 0;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (fmark = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if ((n = fmt - fmark) != 0) {
+ PRINT(fmark, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+#if defined(FLOATING_POINT) && !defined (USE_DTOA)
+ fpprec = 0;
+#endif
+ width = 0;
+ prec = -1;
+ sign = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ if ((width = va_arg(ap, int)) >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ flags &= ~ZEROPAD; /* '-' disables '0' */
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ n = va_arg(ap, int);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ }
+ prec = n < 0 ? -1 : n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ if (!(flags & LADJUST))
+ flags |= ZEROPAD; /* '-' disables '0' */
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ flags |= LONGINT;
+ goto rflag;
+ case 'c':
+ *(cp = buf) = va_arg(ap, int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ _ulong = SARG();
+ if ((long)_ulong < 0) {
+ _ulong = -_ulong;
+ sign = '-';
+ }
+ base = DEC;
+ goto number;
+#ifdef FLOATING_POINT
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ _double = va_arg(ap, double);
+#ifdef USE_DTOA
+ {
+ ios::fmtflags fmt_flags = 0;
+ int fill = ' ';
+ if (flags & ALT)
+ fmt_flags |= ios::showpoint;
+ if (flags & LADJUST)
+ fmt_flags |= ios::left;
+ else if (flags & ZEROPAD)
+ fmt_flags |= ios::internal, fill = '0';
+ n = __outfloat(_double, this, ch, width,
+ prec < 0 ? DEFPREC : prec,
+ fmt_flags, sign, fill);
+ if (n < 0)
+ goto error;
+ ret += n;
+ }
+ // CHECK ERROR!
+ continue;
+#else
+ /*
+ * don't do unrealistic precision; just pad it with
+ * zeroes later, so buffer size stays rational.
+ */
+ if (prec > MAXFRACT) {
+ if ((ch != 'g' && ch != 'G') || (flags&ALT))
+ fpprec = prec - MAXFRACT;
+ prec = MAXFRACT;
+ } else if (prec == -1)
+ prec = DEFPREC;
+ // __cvt_double may have to round up before the
+ // "start" of its buffer, i.e.
+ // ``intf("%.2f", (double)9.999);'';
+ // if the first character is still NUL, it did.
+ // softsign avoids negative 0 if _double < 0 but
+ // no significant digits will be shown.
+ cp = buf;
+ *cp = '\0';
+ size = __cvt_double(_double, prec, flags, &softsign,
+ ch, cp, buf + sizeof(buf));
+ if (softsign)
+ sign = '-';
+ if (*cp == '\0')
+ cp++;
+ break;
+#endif
+#endif /* FLOATING_POINT */
+ case 'n':
+ if (flags & LONGINT)
+ *va_arg(ap, long *) = ret;
+ else if (flags & SHORTINT)
+ *va_arg(ap, short *) = ret;
+ else
+ *va_arg(ap, int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ _ulong = UARG();
+ base = OCT;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ /* NOSTRICT */
+ _ulong = (unsigned long)va_arg(ap, void *);
+ base = HEX;
+ flags |= HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = va_arg(ap, char *)) == NULL)
+ cp = "(null)";
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = (char*)memchr(cp, 0, prec);
+
+ if (p != NULL) {
+ size = p - cp;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = strlen(cp);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ _ulong = UARG();
+ base = DEC;
+ goto nosign;
+ case 'X':
+ case 'x':
+ _ulong = UARG();
+ base = HEX;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT && _ulong != 0)
+ flags |= HEXPREFIX;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = buf + BUF;
+ if (_ulong != 0 || prec != 0) {
+ char *xdigs; /* digits for [xX] conversion */
+ /*
+ * unsigned mod is hard, and unsigned mod
+ * by a constant is easier than that by
+ * a variable; hence this switch.
+ */
+ switch (base) {
+ case OCT:
+ do {
+ *--cp = to_char(_ulong & 7);
+ _ulong >>= 3;
+ } while (_ulong);
+ /* handle octal leading 0 */
+ if (flags & ALT && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case DEC:
+ /* many numbers are 1 digit */
+ while (_ulong >= 10) {
+ *--cp = to_char(_ulong % 10);
+ _ulong /= 10;
+ }
+ *--cp = to_char(_ulong);
+ break;
+
+ case HEX:
+ if (ch == 'X')
+ xdigs = "0123456789ABCDEF";
+ else /* ch == 'x' || ch == 'p' */
+ xdigs = "0123456789abcdef";
+ do {
+ *--cp = xdigs[_ulong & 15];
+ _ulong >>= 4;
+ } while (_ulong);
+ break;
+
+ default:
+ cp = "bug in vform: bad base";
+ goto skipsize;
+ }
+ }
+ size = buf + BUF - cp;
+ skipsize:
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = buf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point,
+ * `cp' points to a string which (if not flags&LADJUST)
+ * should be padded out to `width' places. If
+ * flags&ZEROPAD, it should first be prefixed by any
+ * sign or other prefix; otherwise, it should be blank
+ * padded before the prefix is emitted. After any
+ * left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print
+ * the string proper, then emit zeroes required by any
+ * leftover floating precision; finally, if LADJUST,
+ * pad with blanks.
+ */
+
+ /*
+ * compute actual size, so we know how much to pad.
+ */
+#if defined(FLOATING_POINT) && !defined (USE_DTOA)
+ fieldsz = size + fpprec;
+#else
+ fieldsz = size;
+#endif
+ dpad = dprec - size;
+ if (dpad < 0)
+ dpad = 0;
+
+ if (sign)
+ fieldsz++;
+ else if (flags & HEXPREFIX)
+ fieldsz += 2;
+ fieldsz += dpad;
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD_SP(width - fieldsz);
+
+ /* prefix */
+ if (sign) {
+ PRINT(&sign, 1);
+ } else if (flags & HEXPREFIX) {
+ ox[0] = '0';
+ ox[1] = ch;
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD_0(width - fieldsz);
+
+ /* leading zeroes from decimal precision */
+ PAD_0(dpad);
+
+ /* the string or number proper */
+ PRINT(cp, size);
+
+#if defined(FLOATING_POINT) && !defined (USE_DTOA)
+ /* trailing f.p. zeroes */
+ PAD_0(fpprec);
+#endif
+
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD_SP(width - fieldsz);
+
+ /* finally, adjust ret */
+ ret += width > fieldsz ? width : fieldsz;
+
+ }
+done:
+ return ret;
+error:
+ return EOF;
+ /* NOTREACHED */
+}
+
+#if defined(FLOATING_POINT) && !defined(USE_DTOA)
+
+static char *exponent(register char *p, register int exp, int fmtch)
+{
+ register char *t;
+ char expbuf[MAXEXP];
+
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXP;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXP; *p++ = *t++);
+ }
+ else {
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return (p);
+}
+
+static char * round(double fract, int *exp,
+ register char *start, register char *end,
+ char ch, int *signp)
+{
+ double tmp;
+
+ if (fract)
+ (void)modf(fract * 10, &tmp);
+ else
+ tmp = to_digit(ch);
+ if (tmp > 4)
+ for (;; --end) {
+ if (*end == '.')
+ --end;
+ if (++*end <= '9')
+ break;
+ *end = '0';
+ if (end == start) {
+ if (exp) { /* e/E; increment exponent */
+ *end = '1';
+ ++*exp;
+ }
+ else { /* f; add extra digit */
+ *--end = '1';
+ --start;
+ }
+ break;
+ }
+ }
+ /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
+ else if (*signp == '-')
+ for (;; --end) {
+ if (*end == '.')
+ --end;
+ if (*end != '0')
+ break;
+ if (end == start)
+ *signp = 0;
+ }
+ return (start);
+}
+
+int __cvt_double(double number, register int prec, int flags, int *signp,
+ int fmtch, char *startp, char *endp)
+{
+ register char *p, *t;
+ register double fract;
+ int dotrim = 0, expcnt, gformat = 0;
+ double integer, tmp;
+
+ expcnt = 0;
+ if (number < 0) {
+ number = -number;
+ *signp = '-';
+ } else
+ *signp = 0;
+
+ fract = modf(number, &integer);
+
+ /* get an extra slot for rounding. */
+ t = ++startp;
+
+ /*
+ * get integer portion of number; put into the end of the buffer; the
+ * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
+ */
+ for (p = endp - 1; integer; ++expcnt) {
+ tmp = modf(integer / 10, &integer);
+ *p-- = to_char((int)((tmp + .01) * 10));
+ }
+ switch (fmtch) {
+ case 'f':
+ case 'F':
+ /* reverse integer into beginning of buffer */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point.
+ */
+ if (prec || flags&ALT)
+ *t++ = '.';
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, (int *)NULL, startp,
+ t - 1, (char)0, signp);
+ }
+ for (; prec--; *t++ = '0');
+ break;
+ case 'e':
+ case 'E':
+eformat: if (expcnt) {
+ *t++ = *++p;
+ if (prec || flags&ALT)
+ *t++ = '.';
+ /* if requires more precision and some integer left */
+ for (; prec && ++p < endp; --prec)
+ *t++ = *p;
+ /*
+ * if done precision and more of the integer component,
+ * round using it; adjust fract so we don't re-round
+ * later.
+ */
+ if (!prec && ++p < endp) {
+ fract = 0;
+ startp = round((double)0, &expcnt, startp,
+ t - 1, *p, signp);
+ }
+ /* adjust expcnt for digit in front of decimal */
+ --expcnt;
+ }
+ /* until first fractional digit, decrement exponent */
+ else if (fract) {
+ /* adjust expcnt for digit in front of decimal */
+ for (expcnt = -1;; --expcnt) {
+ fract = modf(fract * 10, &tmp);
+ if (tmp)
+ break;
+ }
+ *t++ = to_char((int)tmp);
+ if (prec || flags&ALT)
+ *t++ = '.';
+ }
+ else {
+ *t++ = '0';
+ if (prec || flags&ALT)
+ *t++ = '.';
+ }
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec)
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while (--prec && fract);
+ if (fract)
+ startp = round(fract, &expcnt, startp,
+ t - 1, (char)0, signp);
+ }
+ /* if requires more precision */
+ for (; prec--; *t++ = '0');
+
+ /* unless alternate flag, trim any g/G format trailing 0's */
+ if (gformat && !(flags&ALT)) {
+ while (t > startp && *--t == '0');
+ if (*t == '.')
+ --t;
+ ++t;
+ }
+ t = exponent(t, expcnt, fmtch);
+ break;
+ case 'g':
+ case 'G':
+ /* a precision of 0 is treated as a precision of 1. */
+ if (!prec)
+ ++prec;
+ /*
+ * ``The style used depends on the value converted; style e
+ * will be used only if the exponent resulting from the
+ * conversion is less than -4 or greater than the precision.''
+ * -- ANSI X3J11
+ */
+ if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
+ /*
+ * g/G format counts "significant digits, not digits of
+ * precision; for the e/E format, this just causes an
+ * off-by-one problem, i.e. g/G considers the digit
+ * before the decimal point significant and e/E doesn't
+ * count it as precision.
+ */
+ --prec;
+ fmtch -= 2; /* G->E, g->e */
+ gformat = 1;
+ goto eformat;
+ }
+ /*
+ * reverse integer into beginning of buffer,
+ * note, decrement precision
+ */
+ if (expcnt)
+ for (; ++p < endp; *t++ = *p, --prec);
+ else
+ *t++ = '0';
+ /*
+ * if precision required or alternate flag set, add in a
+ * decimal point. If no digits yet, add in leading 0.
+ */
+ if (prec || flags&ALT) {
+ dotrim = 1;
+ *t++ = '.';
+ }
+ else
+ dotrim = 0;
+ /* if requires more precision and some fraction left */
+ if (fract) {
+ if (prec) {
+ /* If no integer part, don't count initial
+ * zeros as significant digits. */
+ do {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ } while(!tmp && !expcnt);
+ while (--prec && fract) {
+ fract = modf(fract * 10, &tmp);
+ *t++ = to_char((int)tmp);
+ }
+ }
+ if (fract)
+ startp = round(fract, (int *)NULL, startp,
+ t - 1, (char)0, signp);
+ }
+ /* alternate format, adds 0's for precision, else trim 0's */
+ if (flags&ALT)
+ for (; prec--; *t++ = '0');
+ else if (dotrim) {
+ while (t > startp && *--t == '0');
+ if (*t != '.')
+ ++t;
+ }
+ }
+ return (t - startp);
+}
+
+#endif /* defined(FLOATING_POINT) && !defined(USE_DTOA) */
+
+int streambuf::form(char const *format ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int count = vform(format, ap);
+ va_end(ap);
+ return count;
+}
diff --git a/gnu/lib/libg++/iostream/sbufvscan.C b/gnu/lib/libg++/iostream/sbufvscan.C
new file mode 100644
index 00000000000..3c7d29a8c78
--- /dev/null
+++ b/gnu/lib/libg++/iostream/sbufvscan.C
@@ -0,0 +1,746 @@
+/*
+ * 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.
+// Changes copyright Per Bothner 1992.
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ioprivate.h>
+#include <ctype.h>
+#ifndef NO_STDARG
+#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 */
+
+/*
+ * The following are used in numeric conversions only:
+ * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+
+#define DPTOK 0x100 /* (float) decimal point is still legal */
+#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
+
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* integer, i.e., strtol or strtoul */
+#define CT_FLOAT 4 /* floating, i.e., strtod */
+
+#define u_char unsigned char
+#define u_long unsigned long
+
+extern "C" u_long strtoul(const char*, char**, int);
+static const u_char *__sccl(register char *tab, register const u_char *fmt);
+
+// If state is non-NULL, set failbit and/or eofbit as appropriate.
+
+int streambuf::vscan(char const *fmt0,
+ _G_va_list ap,
+ ios *stream /* = NULL */)
+{
+ register const u_char *fmt = (const u_char *)fmt0;
+ register int c; /* character from format, or conversion */
+ register size_t width; /* field width, or 0 */
+ register char *p; /* points into all kinds of strings */
+ register int n; /* handy integer */
+ register int flags; /* 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)(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 = sbumpc();
+ if (c == EOF)
+ goto eof_failure;
+ if (!isspace(c)) {
+ sputbackc(c);
+ 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 = sbumpc();
+ if (n == EOF)
+ goto eof_failure;
+ if (n != c) {
+ sputbackc(n);
+ goto match_failure;
+ }
+ nread++;
+ continue;
+
+ case '*':
+ flags |= SUPPRESS;
+ goto again;
+ case 'l':
+ flags |= LONG;
+ goto again;
+ case 'L':
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ 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 (sgetc() == EOF)
+ goto eof_failure;
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ n = (unsigned char)*_gptr;
+ while (isspace(n)) {
+ _gptr++;
+ nread++;
+ n = sgetc();
+ 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) {
+ size_t sum = 0;
+ for (;;) {
+ if ((n = _egptr - _gptr) < (int)width) {
+ sum += n;
+ width -= n;
+ _gptr += n;
+ if (underflow() == EOF)
+ if (sum == 0)
+ goto eof_failure;
+ else {
+ seen_eof++;
+ break;
+ }
+ } else {
+ sum += width;
+ _gptr += width;
+ break;
+ }
+ }
+ nread += sum;
+ } else {
+ size_t r = sgetn((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)*_gptr]) {
+ n++, _gptr++;
+ if (--width == 0)
+ break;
+ if (sgetc() == 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)*_gptr]) {
+ *p++ = *_gptr++;
+ if (--width == 0)
+ break;
+ if (sgetc() == 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)*_gptr)) {
+ n++, _gptr++;
+ if (--width == 0)
+ break;
+ if (sgetc() == EOF) {
+ seen_eof++;
+ break;
+ }
+ }
+ nread += n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace((unsigned char)*_gptr)) {
+ *p++ = *_gptr++;
+ if (--width == 0)
+ break;
+ if (sgetc() == 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)*_gptr;
+ /*
+ * 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;
+ _gptr++;
+ if (sgetc() == 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) sputbackc(*(u_char *)--p);
+ goto match_failure;
+ }
+ c = ((u_char *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ (void) sputbackc(c);
+ }
+ 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)*_gptr;
+ /*
+ * 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;
+ _gptr++;
+ if (sgetc() == 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)
+ sputbackc(*(u_char *)--p);
+ goto match_failure;
+ }
+ /* just a bad exponent (e and maybe sign) */
+ c = *(u_char *)--p;
+ if (c != 'e' && c != 'E') {
+ (void)sputbackc(c);/* sign */
+ c = *(u_char *)--p;
+ }
+ (void) sputbackc(c);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ double res;
+ *p = 0;
+#ifdef USE_DTOA
+ res = 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;
+match_failure:
+ if (stream)
+ stream->set(ios::failbit);
+done:
+ if (stream && seen_eof)
+ stream->set(ios::eofbit);
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static const u_char *__sccl(register char *tab, register const u_char *fmt)
+{
+ register int c, n, v;
+
+ /* first `clear' the whole table */
+ c = *fmt++; /* first char hat => negated scanset */
+ if (c == '^') {
+ v = 1; /* default => accept */
+ c = *fmt++; /* get new first char */
+ } else
+ v = 0; /* default => reject */
+ /* should probably use memset here */
+ for (n = 0; n < 256; n++)
+ tab[n] = v;
+ if (c == 0)
+ return (fmt - 1);/* format ended before closing ] */
+
+ /*
+ * Now set the entries corresponding to the actual scanset
+ * to the opposite of the above.
+ *
+ * The first character may be ']' (or '-') without being special;
+ * the last character may be '-'.
+ */
+ v = 1 - v;
+ for (;;) {
+ tab[c] = v; /* take character c */
+doswitch:
+ n = *fmt++; /* and examine the next */
+ switch (n) {
+
+ case 0: /* format ended too soon */
+ return (fmt - 1);
+
+ case '-':
+ /*
+ * A scanset of the form
+ * [01+-]
+ * is defined as `the digit 0, the digit 1,
+ * the character +, the character -', but
+ * the effect of a scanset such as
+ * [a-zA-Z0-9]
+ * is implementation defined. The V7 Unix
+ * scanf treats `a-z' as `the letters a through
+ * z', but treats `a-a' as `the letter a, the
+ * character -, and the letter a'.
+ *
+ * For compatibility, the `-' is not considerd
+ * to define a range if the character following
+ * it is either a close bracket (required by ANSI)
+ * or is not numerically greater than the character
+ * we just stored in the table (c).
+ */
+ n = *fmt;
+ if (n == ']' || n < c) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ do { /* fill in the range */
+ tab[++c] = v;
+ } while (c < n);
+#if 1 /* XXX another disgusting compatibility hack */
+ /*
+ * Alas, the V7 Unix scanf also treats formats
+ * such as [a-c-e] as `the letters a through e'.
+ * This too is permitted by the standard....
+ */
+ goto doswitch;
+#else
+ c = *fmt++;
+ if (c == 0)
+ return (fmt - 1);
+ if (c == ']')
+ return (fmt);
+#endif
+ break;
+
+ case ']': /* end of scanset */
+ return (fmt);
+
+ default: /* just another character */
+ c = n;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
+
+int streambuf::scan(char const *format ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ int count = vscan(format, ap);
+ va_end(ap);
+ return count;
+}
diff --git a/gnu/lib/libg++/iostream/sgetline.C b/gnu/lib/libg++/iostream/sgetline.C
new file mode 100644
index 00000000000..04745969223
--- /dev/null
+++ b/gnu/lib/libg++/iostream/sgetline.C
@@ -0,0 +1,64 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "ioprivate.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-1).
+// If extract_delim < 0, leave delimiter unread.
+// If extract_delim > 0, insert delim in output.
+
+long streambuf::sgetline(char* buf, size_t n, char delim, int extract_delim)
+{
+ register char *ptr = buf;
+ if (n <= 0)
+ return EOF;
+ n--; // Leave space for final '\0'.
+ do {
+ int len = egptr() - gptr();
+ if (len <= 0)
+ if (underflow() == EOF)
+ break;
+ else
+ len = egptr() - gptr();
+ if (len >= (int)n)
+ len = n;
+ char *t = (char*)memchr((void*)_gptr, delim, len);
+ if (t != NULL) {
+ size_t old_len = ptr-buf;
+ len = t - _gptr;
+ if (extract_delim >= 0) {
+ t++;
+ old_len++;
+ if (extract_delim > 0)
+ len++;
+ }
+ memcpy((void*)ptr, (void*)_gptr, len);
+ ptr[len] = 0;
+ _gptr = t;
+ return old_len + len;
+ }
+ memcpy((void*)ptr, (void*)_gptr, len);
+ _gptr += len;
+ ptr += len;
+ n -= len;
+ } while (n != 0);
+ *ptr = 0;
+ return ptr - buf;
+}
diff --git a/gnu/lib/libg++/iostream/stdiostream.C b/gnu/lib/libg++/iostream/stdiostream.C
new file mode 100644
index 00000000000..960a9a4a60f
--- /dev/null
+++ b/gnu/lib/libg++/iostream/stdiostream.C
@@ -0,0 +1,112 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include <stdiostream.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);
+}
+
+_G_ssize_t stdiobuf::sys_read(char* buf, size_t size)
+{
+ return fread(buf, 1, size, _file);
+}
+
+_G_ssize_t stdiobuf::sys_write(const void *buf, long n)
+{
+ _G_ssize_t count = fwrite(buf, 1, n, _file);
+ if (_fb._offset >= 0)
+ _fb._offset += n;
+ return count;
+}
+
+_G_fpos_t stdiobuf::sys_seek(_G_fpos_t 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 (filebuf::sync() == EOF)
+ return EOF;
+ if (!(xflags() & _S_NO_WRITES))
+ if (fflush(_file))
+ return EOF;
+#if 0
+ // This loses when writing to a pipe.
+ if (fseek(_file, 0, SEEK_CUR) == EOF)
+ return EOF;
+#endif
+ return 0;
+}
+
+int stdiobuf::overflow(int c /* = EOF*/)
+{
+ if (filebuf::overflow(c) == EOF)
+ return EOF;
+ if (c != EOF)
+ return c;
+ return fflush(_file);
+}
+
+int stdiobuf::xsputn(const char* s, int n)
+{
+ // The filebuf implementation of sputn loses.
+ return streambuf::xsputn(s, n);
+}
diff --git a/gnu/lib/libg++/iostream/stdiostream.h b/gnu/lib/libg++/iostream/stdiostream.h
new file mode 100644
index 00000000000..9e397b7eed9
--- /dev/null
+++ b/gnu/lib/libg++/iostream/stdiostream.h
@@ -0,0 +1,45 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: stdiostream.h,v 1.1 1995/10/18 08:38:14 deraadt Exp $
+
+#ifndef _STDIOSTREAM_H
+#define _STDIOSTREAM_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <streambuf.h>
+#include <stdio.h>
+
+class stdiobuf : public filebuf {
+ protected:
+ FILE *_file;
+ public:
+ FILE* stdiofile() const { return _file; }
+ stdiobuf(FILE *f);
+ virtual _G_ssize_t sys_read(char* buf, _G_size_t size);
+ virtual _G_fpos_t sys_seek(_G_fpos_t, _seek_dir);
+ virtual _G_ssize_t sys_write(const void*, long);
+ virtual int sys_close();
+ virtual int sync();
+ virtual int overflow(int c = EOF);
+ virtual int xsputn(const char* s, int n);
+};
+
+#endif /* !_STDIOSTREAM_H */
diff --git a/gnu/lib/libg++/iostream/stdstrbufs.C b/gnu/lib/libg++/iostream/stdstrbufs.C
new file mode 100644
index 00000000000..2ae80fa9c41
--- /dev/null
+++ b/gnu/lib/libg++/iostream/stdstrbufs.C
@@ -0,0 +1,113 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "ioprivate.h"
+#include <stdio.h>
+
+// This file defines the standard streambufs, corresponding to cin, cout, cerr.
+// We define two sets:
+//
+// __std_filebuf_0, __std_filebuf_1, __std_filebuf_2 are filebufs using
+// file descriptor 0/1/2.
+//
+// __stdin_stdiobuf, __stdout_stdiobuf, __stderr_stdiobuf are stdiostreams
+// pointing to stdin, stdout, stderr.
+
+
+// To avoid problems depending on constructor order (and for
+// efficiency) the standard streambufs (and streams) are
+// constructed statically using C-style '{ ... }' initializers.
+// Since you're not allowed to do this for structs that
+// have virtuals, we define fake streambuf and stream classes
+// that don't have any C++-isms, and initialize those.
+// To initialize the vtable field of the standard filebufs,
+// we use the expression 'vt_filebuf' which must evaluate to
+// (the address of) the virtual function table for the
+// filebuf class.
+
+#if _G_NAMES_HAVE_UNDERSCORE
+#define UNDERSCORE "_"
+#else
+#define UNDERSCORE ""
+#endif
+
+// First define the filebuf-based objects.
+
+#if !defined(vt_filebuf)
+#ifndef __GNUG__
+// This works for cfront.
+#define vt_filebuf __vtbl__7filebuf
+extern char vt_filebuf[1];
+#elif _G_DOLLAR_IN_LABEL
+extern char vt_filebuf[1] asm(UNDERSCORE "_vt$filebuf");
+#else
+extern char vt_filebuf[1] asm(UNDERSCORE "_vt.filebuf");
+#endif
+#endif /* !defined(vt_filebuf) */
+
+struct _fake_filebuf {
+ struct __streambuf s;
+ char* vtable;
+ struct __file_fields f;
+};
+
+#define FILEBUF_LITERAL(CHAIN, FLAGS) \
+ { _IO_MAGIC+_S_LINKED+_S_IS_FILEBUF+_S_IS_BACKUPBUF+FLAGS, \
+ 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, 0, 0, 0, 0, 0}
+
+#define DEF_FILEBUF(NAME, FD, CHAIN, FLAGS) \
+ _fake_filebuf NAME = {FILEBUF_LITERAL(CHAIN, FLAGS), vt_filebuf, {FD}};
+
+DEF_FILEBUF(__std_filebuf_0, 0, 0, _S_NO_WRITES);
+DEF_FILEBUF(__std_filebuf_1, 1, (streambuf*)&__std_filebuf_0, _S_NO_READS);
+DEF_FILEBUF(__std_filebuf_2, 2, (streambuf*)&__std_filebuf_1,
+ _S_NO_READS+_S_UNBUFFERED);
+
+// Nest define the stdiobuf-bases objects.
+
+#if !defined(vt_stdiobuf)
+#ifndef __GNUG__
+// This works for cfront.
+#define vt_stdiobuf __vtbl__8stdiobuf
+extern char vt_stdiobuf[1];
+#elif _G_DOLLAR_IN_LABEL
+extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt$stdiobuf");
+#else
+extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt.stdiobuf");
+#endif
+#endif /* !defined(vt_stdiobuf) */
+
+struct _fake_stdiobuf {
+ struct __streambuf s;
+ char* vtable;
+ struct __file_fields f;
+ FILE *_f;
+};
+
+#define DEF_STDIOBUF(NAME, FILE, FD, CHAIN, FLAGS) \
+ _fake_stdiobuf NAME[1] = {{ \
+ FILEBUF_LITERAL(CHAIN, (FLAGS)|_S_UNBUFFERED),\
+ vt_stdiobuf, {FD}, FILE}};
+
+DEF_STDIOBUF(__stdin_stdiobuf, stdin, 0, (streambuf*)&__std_filebuf_2,
+ _S_NO_WRITES);
+DEF_STDIOBUF(__stdout_stdiobuf, stdout, 1, (streambuf*)__stdin_stdiobuf,
+ _S_NO_READS);
+DEF_STDIOBUF(__stderr_stdiobuf, stderr, 2, (streambuf*)__stdout_stdiobuf,
+ _S_NO_READS);
+
+streambuf* streambuf::_list_all = (streambuf*)__stderr_stdiobuf;
diff --git a/gnu/lib/libg++/iostream/stdstreams.C b/gnu/lib/libg++/iostream/stdstreams.C
new file mode 100644
index 00000000000..991371a1077
--- /dev/null
+++ b/gnu/lib/libg++/iostream/stdstreams.C
@@ -0,0 +1,145 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "ioprivate.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 &__std_filebuf_0/&__std_filebuf_1/&__std_filebuf_2.
+
+#ifdef _STDIO_USES_IOSTREAM
+#define USE_FILEBUF
+#endif
+
+#ifdef NAMES_HAVE_UNDERSCORE
+#define UNDERSCORE "_"
+#else
+#define UNDERSCORE ""
+#endif
+
+#ifdef USE_FILEBUF
+#define CIN_SBUF __std_filebuf_0
+#define COUT_SBUF __std_filebuf_1
+#define CERR_SBUF __std_filebuf_2
+static int use_stdiobuf = 0;
+#else
+#define CIN_SBUF __stdin_stdiobuf
+#define COUT_SBUF __stdout_stdiobuf
+#define CERR_SBUF __stderr_stdiobuf
+static int use_stdiobuf = 1;
+#endif
+
+struct _fake_filebuf;
+extern _fake_filebuf __std_filebuf_0, __std_filebuf_1, __std_filebuf_2;
+struct _fake_stdiobuf;
+extern _fake_stdiobuf __stdin_stdiobuf, __stdout_stdiobuf, __stderr_stdiobuf;
+
+#define cin CIN
+#define cout COUT
+#define cerr CERR
+#define clog CLOG
+#include "iostream.h"
+#undef cin
+#undef cout
+#undef cerr
+#undef clog
+
+#ifdef __GNUC__
+#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 */
+ _G_ssize_t _gcount;
+#else
+ /* This is supposedly correct for cfront. */
+ _G_ssize_t _gcount;
+ void *vptr;
+ _ios_fields *vb; /* pointer to virtual base class ios */
+#endif
+ } mine;
+ _ios_fields base;
+ char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD];
+};
+struct _fake_ostream {
+ struct myfields {
+#ifndef __GNUC__
+ void *vptr;
+#endif
+ _ios_fields *vb; /* pointer to virtual base class ios */
+ } mine;
+ _ios_fields base;
+ char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD];
+};
+
+#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
+ (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
+
+#ifdef __GNUC__
+#define OSTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
+ TYPE NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#define ISTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
+ TYPE NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#else
+#define OSTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
+ TYPE NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#define ISTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
+ TYPE NAME = { {0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
+#endif
+
+OSTREAM_DEF(_fake_ostream, cout, COUT_SBUF, NULL, 0)
+OSTREAM_DEF(_fake_ostream, cerr, CERR_SBUF, (ostream*)&cout, ios::unitbuf)
+ISTREAM_DEF(_fake_istream, cin, CIN_SBUF, (ostream*)&cout, 0)
+
+/* Only for (partial) compatibility with AT&T's library. */
+OSTREAM_DEF(_fake_ostream, clog, CERR_SBUF, (ostream*)&cout, 0)
+
+// Switches between using __std_filebuf_{0,1,2} and
+// __std{in,out,err}_stdiobuf for standard streams. This is
+// normally not needed, 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) {
+ cout.base._strbuf = (streambuf*)&__stdout_stdiobuf;
+ cin.base._strbuf = (streambuf*)&__stdin_stdiobuf;
+ cerr.base._strbuf = (streambuf*)&__stderr_stdiobuf;
+ clog.base._strbuf = (streambuf*)&__stderr_stdiobuf;
+ } else {
+ cout.base._strbuf = (streambuf*)&__std_filebuf_1;
+ cin.base._strbuf = (streambuf*)&__std_filebuf_0;
+ cerr.base._strbuf = (streambuf*)&__std_filebuf_2;
+ clog.base._strbuf = (streambuf*)&__std_filebuf_2;
+ }
+ int old_state = use_stdiobuf;
+ use_stdiobuf = new_state;
+ return old_state;
+#endif
+}
diff --git a/gnu/lib/libg++/iostream/stream.C b/gnu/lib/libg++/iostream/stream.C
new file mode 100644
index 00000000000..5ee6bbeb5a5
--- /dev/null
+++ b/gnu/lib/libg++/iostream/stream.C
@@ -0,0 +1,120 @@
+#include <stdarg.h>
+#include "ioprivate.h"
+#include "stream.h"
+#include "strstream.h"
+
+static char Buffer[_G_BUFSIZ];
+#define EndBuffer (Buffer+_G_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 < (_G_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++/iostream/stream.h b/gnu/lib/libg++/iostream/stream.h
new file mode 100644
index 00000000000..5f87b7eef77
--- /dev/null
+++ b/gnu/lib/libg++/iostream/stream.h
@@ -0,0 +1,33 @@
+// $Id: stream.h,v 1.1 1995/10/18 08:38:14 deraadt Exp $
+
+#ifndef _COMPAT_STREAM_H
+#define _COMPAT_STREAM_H
+
+// Compatibility with old library.
+
+#define _STREAM_COMPAT
+#include <iostream.h>
+
+extern char* form(const char*, ...);
+
+extern char* dec(long, int=0);
+extern char* dec(int, int=0);
+extern char* dec(unsigned long, int=0);
+extern char* dec(unsigned int, int=0);
+
+extern char* hex(long, int=0);
+extern char* hex(int, int=0);
+extern char* hex(unsigned long, int=0);
+extern char* hex(unsigned int, int=0);
+
+extern char* oct(long, int=0);
+extern char* oct(int, int=0);
+extern char* oct(unsigned long, int=0);
+extern char* oct(unsigned int, int=0);
+
+char* chr(char ch, int width = 0);
+char* str(const char* s, int width = 0);
+
+inline istream& WS(istream& str) { return ws(str); }
+
+#endif /* !_COMPAT_STREAM_H */
diff --git a/gnu/lib/libg++/iostream/streambuf.C b/gnu/lib/libg++/iostream/streambuf.C
new file mode 100644
index 00000000000..0038f39190e
--- /dev/null
+++ b/gnu/lib/libg++/iostream/streambuf.C
@@ -0,0 +1,666 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991, 1992 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#define _STREAM_COMPAT
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "ioprivate.h"
+#include <string.h>
+
+void streambuf::_un_link()
+{
+ if (_flags & _S_LINKED) {
+ streambuf **f;
+ for (f = &_list_all; *f != NULL; f = &(*f)->xchain()) {
+ if (*f == this) {
+ *f = xchain();
+ break;
+ }
+ }
+ _flags &= ~_S_LINKED;
+ }
+}
+
+void streambuf::_link_in()
+{
+ if ((_flags & _S_LINKED) == 0) {
+ _flags |= _S_LINKED;
+ xchain() = _list_all;
+ _list_all = this;
+ }
+}
+
+// Return minimum _pos markers
+// Assumes the current get area is the main get area.
+int streambuf::_least_marker()
+{
+ int least_so_far = _egptr - _eback;
+ for (register streammarker *mark = _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 streambuf::switch_to_main_get_area()
+{
+ char *tmp;
+ _flags &= ~_S_IN_BACKUP;
+ // Swap _egptr and _other_egptr.
+ tmp= _egptr; _egptr= _other_egptr; _other_egptr= tmp;
+ // Swap _eback and _other_gbase.
+ tmp= _eback; _eback = _other_gbase; _other_gbase = tmp;
+ _gptr = _eback;
+}
+
+// Switch current get area from main get area to (end of) backup area.
+
+void streambuf::switch_to_backup_area()
+{
+ char *tmp;
+ _flags |= _S_IN_BACKUP;
+ // Swap _egptr and _other_egptr.
+ tmp = _egptr; _egptr = _other_egptr; _other_egptr = tmp;
+ // Swap _gbase and _other_gbase.
+ tmp = _eback; _eback = _other_gbase; _other_gbase = tmp;
+ _gptr = _egptr;
+}
+
+int streambuf::switch_to_get_mode()
+{
+ if (_pptr > _pbase)
+ if (overflow(EOF) == EOF)
+ return EOF;
+ if (in_backup()) {
+ _eback = _aux_limit;
+ }
+ else {
+ _eback = _base;
+ if (_pptr > _egptr)
+ _egptr = _pptr;
+ }
+ _gptr = _pptr;
+
+ setp(_gptr, _gptr);
+
+ _flags &= ~_S_CURRENTLY_PUTTING;
+ return 0;
+}
+
+void streambuf::free_backup_area()
+{
+ if (in_backup())
+ switch_to_main_get_area(); // Just in case.
+ delete [] _other_gbase;
+ _other_gbase = NULL;
+ _other_egptr = NULL;
+ _aux_limit = NULL;
+}
+
+#if 0
+int streambuf::switch_to_put_mode()
+{
+ _pbase = _gptr;
+ _pptr = _gptr;
+ _epptr = in_backup() ? _egptr : _ebuf; // wrong if line- or un-buffered?
+
+ _gptr = _egptr;
+ _eback = _egptr;
+
+ _flags |= _S_CURRENTLY_PUTTING;
+ return 0;
+}
+#endif
+
+#ifdef _G_FRIEND_BUG
+int __underflow(register streambuf *sb) { return __UNDERFLOW(sb); }
+int __UNDERFLOW(register streambuf *sb)
+#else
+int __underflow(register streambuf *sb)
+#endif
+{
+ if (sb->put_mode())
+ if (sb->switch_to_get_mode() == EOF) return EOF;
+ if (sb->_gptr < sb->_egptr)
+ return *(unsigned char*)sb->_gptr;
+ if (sb->in_backup()) {
+ sb->switch_to_main_get_area();
+ if (sb->_gptr < sb->_egptr)
+ return *sb->_gptr;
+ }
+ if (sb->have_markers()) {
+ // Append [_gbase.._egptr] to backup area.
+ int least_mark = sb->_least_marker();
+ // needed_size is how much space we need in the backup area.
+ int needed_size = (sb->_egptr - sb->_eback) - least_mark;
+ int current_Bsize = sb->_other_egptr - sb->_other_gbase;
+ int avail; // Extra space available for future expansion.
+ if (needed_size > current_Bsize) {
+ avail = 0; // 100 ?? FIXME
+ char *new_buffer = new char[avail+needed_size];
+ if (least_mark < 0) {
+ memcpy(new_buffer + avail,
+ sb->_other_egptr + least_mark,
+ -least_mark);
+ memcpy(new_buffer +avail - least_mark,
+ sb->_eback,
+ sb->_egptr - sb->_eback);
+ }
+ else
+ memcpy(new_buffer + avail,
+ sb->_eback + least_mark,
+ needed_size);
+ delete [] sb->_other_gbase;
+ sb->_other_gbase = new_buffer;
+ sb->_other_egptr = new_buffer + avail + needed_size;
+ }
+ else {
+ avail = current_Bsize - needed_size;
+ if (least_mark < 0) {
+ memmove(sb->_other_gbase + avail,
+ sb->_other_egptr + least_mark,
+ -least_mark);
+ memcpy(sb->_other_gbase + avail - least_mark,
+ sb->_eback,
+ sb->_egptr - sb->_eback);
+ }
+ else if (needed_size > 0)
+ memcpy(sb->_other_gbase + avail,
+ sb->_eback + least_mark,
+ needed_size);
+ }
+ // FIXME: Dubious arithmetic if pointers are NULL
+ sb->_aux_limit = sb->_other_gbase + avail;
+ // Adjust all the streammarkers.
+ int delta = sb->_egptr - sb->_eback;
+ for (register streammarker *mark = sb->_markers;
+ mark != NULL; mark = mark->_next)
+ mark->_pos -= delta;
+ }
+ else if (sb->have_backup())
+ sb->free_backup_area();
+ return sb->underflow();
+}
+
+#ifdef _G_FRIEND_BUG
+int __overflow(register streambuf *sb, int c) { return __OVERFLOW(sb, c); }
+int __OVERFLOW(register streambuf *sb, int c)
+#else
+int __overflow(streambuf* sb, int c)
+#endif
+{
+ return sb->overflow(c);
+}
+
+int streambuf::xsputn(register const char* s, int n)
+{
+ if (n <= 0)
+ return 0;
+ register int more = n;
+ for (;;) {
+ int count = _epptr - _pptr; // Space available.
+ if (count > 0) {
+ if (count > more)
+ count = more;
+ if (count > 20) {
+ memcpy(_pptr, s, count);
+ s += count;
+ _pptr += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else {
+ register char *p = _pptr;
+ for (register int i = count; --i >= 0; ) *p++ = *s++;
+ _pptr = p;
+ }
+ more -= count;
+ }
+ if (more == 0 || __overflow(this, (unsigned char)*s++) == EOF)
+ break;
+ more--;
+ }
+ return n - more;
+}
+
+int streambuf::padn(char pad, int count)
+{
+#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'};
+ char padbuf[PADSIZE];
+ const char *padptr;
+ register int i;
+
+ 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)
+ if (sputn(padptr, PADSIZE) != PADSIZE)
+ return EOF;
+ if (i > 0 && sputn(padptr, i) != i)
+ return EOF;
+ return pad;
+}
+
+int streambuf::xsgetn(char* s, int n)
+{
+ register int more = n;
+ for (;;) {
+ int count = _egptr - _gptr; // Data available.
+ if (count > 0) {
+ if (count > more)
+ count = more;
+ if (count > 20) {
+ memcpy(s, _gptr, count);
+ s += count;
+ _gptr += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else {
+ register char *p = _gptr;
+ for (register int i = count; --i >= 0; ) *s++ = *p++;
+ _gptr = p;
+ }
+ more -= count;
+ }
+ if (more == 0 || __underflow(this) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+int streambuf::ignore(int n)
+{
+ register int more = n;
+ for (;;) {
+ int count = _egptr - _gptr; // Data available.
+ if (count > 0) {
+ if (count > more)
+ count = more;
+ _gptr += count;
+ more -= count;
+ }
+ if (more == 0 || __underflow(this) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+int streambuf::sync()
+{
+ if (gptr() == egptr() && pptr() == pbase())
+ return 0;
+ return EOF;
+}
+
+int streambuf::pbackfail(int c)
+{
+ if (_gptr > _eback)
+ _gptr--;
+ else if (seekoff(-1, ios::cur, ios::in) == EOF)
+ return EOF;
+ if (c != EOF && *_gptr != c)
+ *_gptr = c;
+ return (unsigned char)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);
+}
+
+void streambuf::setb(char* b, char* eb, int a)
+{
+ if (_base && !(_flags & _S_USER_BUF))
+ FREE_BUF(_base);
+ _base = b;
+ _ebuf = eb;
+ if (a)
+ _flags &= ~_S_USER_BUF;
+ else
+ _flags |= _S_USER_BUF;
+}
+
+int streambuf::doallocate()
+{
+ char *buf = ALLOC_BUF(_G_BUFSIZ);
+ if (buf == NULL)
+ return EOF;
+ setb(buf, buf+_G_BUFSIZ, 1);
+ return 1;
+}
+
+void streambuf::doallocbuf()
+{
+ if (base() || (!unbuffered() && doallocate() != EOF)) return;
+ setb(_shortbuf, _shortbuf+1, 0);
+}
+
+streambuf::streambuf(int flags)
+{
+ _flags = _IO_MAGIC|flags;
+ _base = NULL;
+ _ebuf = NULL;
+ _eback = NULL;
+ _gptr = NULL;
+ _egptr = NULL;
+ _pbase = NULL;
+ _pptr = NULL;
+ _epptr = NULL;
+ _chain = NULL; // Not necessary.
+
+ _other_gbase = NULL;
+ _aux_limit = NULL;
+ _other_egptr = NULL;
+ _markers = NULL;
+ _cur_column = 0;
+}
+
+streambuf::~streambuf()
+{
+ if (_base && !(_flags & _S_USER_BUF))
+ FREE_BUF(_base);
+
+ for (register streammarker *mark = _markers;
+ mark != NULL; mark = mark->_next)
+ mark->_sbuf = NULL;
+
+}
+
+streampos
+streambuf::seekoff(streamoff, _seek_dir, int mode /*=ios::in|ios::out*/)
+{
+ return EOF;
+}
+
+int streambuf::sputbackc(char c)
+{
+ if (_gptr > _eback && (unsigned char)_gptr[-1] == (unsigned char)c) {
+ _gptr--;
+ return (unsigned char)c;
+ }
+ return pbackfail(c);
+}
+
+int streambuf::sungetc()
+{
+ if (_gptr > _eback) {
+ _gptr--;
+ return (unsigned char)*_gptr;
+ }
+ else
+ return pbackfail(EOF);
+}
+
+#if 0 /* Work in progress */
+void streambuf::collumn(int c)
+{
+ if (c == -1)
+ _collumn = -1;
+ else
+ _collumn = c - (_pptr - _pbase);
+}
+#endif
+
+
+int streambuf::get_column()
+{
+ if (_cur_column)
+ return __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()
+{
+ int result = 0;
+ for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain())
+ if (sb->overflow(EOF) == EOF)
+ result = EOF;
+ return result;
+}
+
+void streambuf::flush_all_linebuffered()
+{
+ for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain())
+ if (sb->linebuffered())
+ sb->overflow(EOF);
+}
+
+int backupbuf::underflow()
+{
+ return EOF;
+}
+
+int backupbuf::overflow(int c)
+{
+ return EOF;
+}
+
+streammarker::streammarker(streambuf *sb)
+{
+ _sbuf = sb;
+ if (!(sb->xflags() & _S_IS_BACKUPBUF)) {
+ set_streampos(sb->seekoff(0, ios::cur, ios::in));
+ _next = 0;
+ }
+ else {
+ if (sb->put_mode())
+ sb->switch_to_get_mode();
+ if (((backupbuf*)sb)->in_backup())
+ set_offset(sb->_gptr - sb->_egptr);
+ else
+ set_offset(sb->_gptr - sb->_eback);
+
+ // Should perhaps sort the chain?
+ _next = ((backupbuf*)sb)->_markers;
+ ((backupbuf*)sb)->_markers = this;
+ }
+}
+
+streammarker::~streammarker()
+{
+ if (saving()) {
+ // Unlink from sb's chain.
+ register streammarker **ptr = &((backupbuf*)_sbuf)->_markers;
+ for (; ; ptr = &(*ptr)->_next)
+ if (*ptr == NULL)
+ break;
+ else if (*ptr == this) {
+ *ptr = _next;
+ return;
+ }
+ }
+#if 0
+ if _sbuf has a backup area that is no longer needed, should we delete
+ it now, or wait until underflow()?
+#endif
+}
+
+#define BAD_DELTA EOF
+
+int streammarker::delta(streammarker& other_mark)
+{
+ if (_sbuf != other_mark._sbuf)
+ return BAD_DELTA;
+ if (saving() && other_mark.saving())
+ return _pos - other_mark._pos;
+ else if (!saving() && !other_mark.saving())
+ return _spos - other_mark._spos;
+ else
+ return BAD_DELTA;
+}
+
+int streammarker::delta()
+{
+ if (_sbuf == NULL)
+ return BAD_DELTA;
+ if (saving()) {
+ int cur_pos;
+ if (_sbuf->in_backup())
+ cur_pos = _sbuf->_gptr - _sbuf->_egptr;
+ else
+ cur_pos = _sbuf->_gptr - _sbuf->_eback;
+ return _pos - cur_pos;
+ }
+ else {
+ if (_spos == EOF)
+ return BAD_DELTA;
+ int cur_pos = _sbuf->seekoff(0, ios::cur);
+ if (cur_pos == EOF)
+ return BAD_DELTA;
+ return _pos - cur_pos;
+ }
+}
+
+int streambuf::seekmark(streammarker& mark, int delta /* = 0 */)
+{
+ if (mark._sbuf != this)
+ return EOF;
+ if (!mark.saving()) {
+ return seekpos(mark._spos, ios::in);
+ }
+ else if (mark._pos >= 0) {
+ if (in_backup())
+ switch_to_main_get_area();
+ _gptr = _eback + mark._pos;
+ }
+ else {
+ if (!in_backup())
+ switch_to_backup_area();
+ _gptr = _egptr + mark._pos;
+ }
+ return 0;
+}
+
+void streambuf::unsave_markers()
+{
+ register streammarker *mark =_markers;
+ if (_markers) {
+ 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);
+ }
+ _markers = 0;
+ }
+
+ free_backup_area();
+}
+
+int backupbuf::pbackfail(int c)
+{
+ if (_gptr <= _eback) {
+ // Need to handle a filebuf in write mode (switch to read mode). FIXME!
+
+ if (have_backup() && !in_backup()) {
+ switch_to_backup_area();
+ }
+ if (!have_backup()) {
+ // No backup buffer: allocate one.
+ // Use short buffer, if unused? (probably not) FIXME
+ int backup_size = 128;
+ _other_gbase = new char [backup_size];
+ _other_egptr = _other_gbase + backup_size;
+ _aux_limit = _other_egptr;
+ switch_to_backup_area();
+ }
+ else if (gptr() <= eback()) {
+ // Increase size of existing backup buffer.
+ size_t new_size;
+ size_t old_size = egptr() - eback();
+ new_size = 2 * old_size;
+ char* new_buf = new char [new_size];
+ memcpy(new_buf+(new_size-old_size), eback(), old_size);
+ delete [] eback();
+ setg(new_buf, new_buf+(new_size-old_size), new_buf+new_size);
+ _aux_limit = _gptr;
+ }
+ }
+ _gptr--;
+ if (c != EOF && *_gptr != c)
+ *_gptr = c;
+ return (unsigned char)*_gptr;
+}
+
+unsigned __adjust_column(unsigned start, const char *line, int count)
+{
+ register const char *ptr = line + count;
+ while (ptr > line)
+ if (*--ptr == '\n')
+ return line + count - ptr - 1;
+ return start + count;
+}
+
+int ios::readable() { return !(rdbuf()->_flags & _S_NO_READS); }
+int ios::writable() { return !(rdbuf()->_flags & _S_NO_WRITES); }
+int ios::is_open() { return rdbuf()
+ && (rdbuf()->_flags & _S_NO_READS+_S_NO_WRITES)
+ != _S_NO_READS+_S_NO_WRITES; }
+
+#if defined(linux)
+#define IO_CLEANUP ;
+#endif
+
+#ifdef IO_CLEANUP
+ IO_CLEANUP
+#else
+struct __io_defs {
+ __io_defs() { }
+ ~__io_defs() { streambuf::flush_all(); }
+};
+__io_defs io_defs__;
+#endif
diff --git a/gnu/lib/libg++/iostream/streambuf.h b/gnu/lib/libg++/iostream/streambuf.h
new file mode 100644
index 00000000000..6beaeb6284c
--- /dev/null
+++ b/gnu/lib/libg++/iostream/streambuf.h
@@ -0,0 +1,497 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: streambuf.h,v 1.1 1995/10/18 08:38:14 deraadt Exp $
+
+#ifndef _STREAMBUF_H
+#define _STREAMBUF_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* #define _G_IO_THROW */ /* Not implemented: ios::failure */
+
+#include <_G_config.h>
+#ifdef _G_NEED_STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#ifdef __GNUC__
+#define NULL ((void*)0)
+#else
+#define NULL (0)
+#endif
+#endif
+
+class ostream; class streambuf; class backupbuf;
+
+// In case some header files defines these as macros.
+#undef open
+#undef close
+
+#ifdef _G_FRIEND_BUG
+extern int __UNDERFLOW(streambuf*);
+extern int __OVERFLOW(streambuf*, int);
+#endif
+extern "C" int __underflow(streambuf*);
+extern "C" int __overflow(streambuf*, int);
+
+typedef _G_off_t streamoff;
+typedef _G_off_t streampos; // Should perhaps be _G_fpos_t ?
+
+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;
+ _G_wchar_t _fill;
+ __iostate _state;
+ __iostate _exceptions;
+ int _precision;
+};
+
+#define _IOS_GOOD 0
+#define _IOS_EOF 1
+#define _IOS_FAIL 2
+#define _IOS_BAD 4
+
+#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
+
+#ifdef _STREAM_COMPAT
+enum state_value {
+ _good = _IOS_GOOD,
+ _eof = _IOS_EOF,
+ _fail = _IOS_FAIL,
+ _bad = _IOS_BAD };
+enum open_mode {
+ input = _IOS_INPUT,
+ output = _IOS_OUTPUT,
+ atend = _IOS_ATEND,
+ append = _IOS_APPEND };
+#endif
+
+class ios : public _ios_fields {
+ public:
+ typedef __fmtflags fmtflags;
+ typedef int iostate;
+ typedef int openmode;
+ typedef int streamsize;
+ enum io_state {
+ goodbit = _IOS_GOOD,
+ eofbit = _IOS_EOF,
+ failbit = _IOS_FAIL,
+ badbit = _IOS_BAD };
+ enum open_mode {
+ in = _IOS_INPUT,
+ out = _IOS_OUTPUT,
+ ate = _IOS_ATEND,
+ app = _IOS_APPEND,
+ trunc = _IOS_TRUNC,
+ nocreate = _IOS_NOCREATE,
+ noreplace = _IOS_NOREPLACE,
+ bin = _IOS_BIN };
+ enum seek_dir { beg, cur, end};
+ // ANSI: typedef enum seek_dir seekdir; etc
+ enum { skipws=01, left=02, right=04, internal=010,
+ dec=020, oct=040, hex=0100,
+ showbase=0200, showpoint=0400, uppercase=01000, showpos=02000,
+ scientific=04000, fixed=010000, unitbuf=020000, stdio=040000,
+ dont_close=0100000 //Don't delete streambuf on stream destruction
+ };
+ enum { // Masks.
+ basefield=dec+oct+hex,
+ floatfield = scientific+fixed,
+ adjustfield = left+right+internal
+ };
+
+#ifdef _G_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.
+ _G_wchar_t fill() const { return (_G_wchar_t)_fill; }
+ _G_wchar_t fill(_G_wchar_t newf)
+ {_G_wchar_t oldf = (_G_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 & mask;
+ _flags &= ~mask; return oldbits; }
+ int width() const { return _width; }
+ int width(int val) { int save = _width; _width = val; return save; }
+
+#ifdef _G_IO_THROW
+ void _throw_failure() { throw new ios::failure(this); }
+#else
+ void _throw_failure() { }
+#endif
+
+ streambuf* rdbuf() const { return _strbuf; }
+ void clear(iostate state = 0) {
+ _state = _strbuf ? state : state|badbit;
+ if (_state & _exceptions) _throw_failure(); }
+ void set(iostate flag) { _state |= flag;
+ if (_state & _exceptions) _throw_failure(); }
+ void setstate(iostate flag) { _state |= flag; // ANSI
+ if (_state & _exceptions) _throw_failure(); }
+ int good() const { return _state == 0; }
+ int eof() const { return _state & ios::eofbit; }
+ int fail() const { return _state & (ios::badbit|ios::failbit); }
+ int bad() const { return _state & ios::badbit; }
+ iostate rdstate() const { return _state; }
+ operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
+ int operator!() const { return fail(); }
+ iostate exceptions() const { return _exceptions; }
+ void exceptions(iostate enable) {
+ _exceptions = enable;
+ if (_state & _exceptions) _throw_failure(); }
+
+ static int sync_with_stdio(int on);
+ static void sync_with_stdio() { sync_with_stdio(1); }
+
+#ifdef _STREAM_COMPAT
+ void unset(state_value flag) { _state &= ~flag; }
+ void close();
+ int is_open();
+ int readable();
+ int writable();
+#endif
+
+ // Used to initialize standard streams. Not needed in this implementation.
+ class Init {
+ public:
+ Init () { }
+ };
+
+ protected:
+ ios(streambuf* sb = 0, ostream* tie = 0);
+ virtual ~ios();
+ void init(streambuf* sb) { _state=0; _strbuf=sb; }
+};
+
+#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.
+
+#define _IO_MAGIC 0xFBAD0000 /* Magic number */
+#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
+#define _IO_MAGIC_MASK 0xFFFF0000
+#define _S_USER_BUF 1 /* User owns buffer; don't delete it on close. */
+#define _S_UNBUFFERED 2
+#define _S_NO_READS 4 /* Reading not allowed */
+#define _S_NO_WRITES 8 /* Writing not allowd */
+#define _S_EOF_SEEN 0x10
+#define _S_ERR_SEEN 0x20
+#define _S_DELETE_DONT_CLOSE 0x40
+#define _S_LINKED 0x80 // Set if linked (using _chain) to streambuf::_list_all.
+#define _S_IN_BACKUP 0x100
+#define _S_LINE_BUF 0x200
+#define _S_TIED_PUT_GET 0x400 // Set if put and get pointer logicly tied.
+#define _S_CURRENTLY_PUTTING 0x800
+#define _S_IS_APPENDING 0x1000
+#define _S_IS_BACKUPBUF 0x4000
+#define _S_IS_FILEBUF 0x8000
+
+// 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 {
+ friend class streambuf;
+#ifdef _G_FRIEND_BUG
+ friend int __UNDERFLOW(streambuf*);
+#else
+ friend int __underflow(streambuf*);
+#endif
+ struct streammarker *_next; // Only if saving()
+ streambuf *_sbuf; // Only valid if saving().
+ streampos _spos; // -2: means that _pos is valid.
+ void set_streampos(streampos sp) { _spos = sp; }
+ void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); }
+ // If _pos >= 0, it points to _buf->Gbase()+_pos.
+ // if _pos < 0, it points to _buf->eBptr()+_pos.
+ int _pos;
+ public:
+ streammarker(streambuf *sb);
+ ~streammarker();
+ int saving() { return _spos == -2; }
+ int delta(streammarker&);
+ int delta();
+};
+
+struct __streambuf {
+ // NOTE: If this is changed, also change __FILE in stdio/stdio.h!
+ int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
+ char* _gptr; /* Current get pointer */
+ char* _egptr; /* End of get area. */
+ char* _eback; /* Start of putback+get area. */
+ char* _pbase; /* Start of put area. */
+ char* _pptr; /* Current put pointer. */
+ char* _epptr; /* End of put area. */
+ char* _base; /* Start of reserve area. */
+ char* _ebuf; /* End of reserve area. */
+ struct streambuf *_chain;
+
+ // The following fields are used to support backing up and undo.
+ friend class streammarker;
+ char *_other_gbase; // Pointer to start of non-current get area.
+ char *_aux_limit; // Pointer to first valid character of backup area,
+ char *_other_egptr; // Pointer to end of non-current get area.
+ streammarker *_markers;
+
+#define __HAVE_COLUMN /* temporary */
+ // 1+column number of pbase(); 0 is unknown.
+ unsigned short _cur_column;
+ char _unused;
+ char _shortbuf[1];
+};
+
+extern unsigned __adjust_column(unsigned start, const char *line, int count);
+
+struct streambuf : public __streambuf {
+ friend class ios;
+ friend class istream;
+ friend class ostream;
+ friend class streammarker;
+#ifdef _G_FRIEND_BUG
+ friend int __UNDERFLOW(streambuf*);
+#else
+ friend int __underflow(streambuf*);
+#endif
+ protected:
+ static streambuf* _list_all; /* List of open streambufs. */
+ streambuf*& xchain() { return _chain; }
+ void _un_link();
+ void _link_in();
+ char* gptr() const { return _gptr; }
+ char* pptr() const { return _pptr; }
+ char* egptr() const { return _egptr; }
+ char* epptr() const { return _epptr; }
+ char* pbase() const { return _pbase; }
+ char* eback() const { return _eback; }
+ char* base() const { return _base; }
+ char* ebuf() const { return _ebuf; }
+ int blen() const { return _ebuf - _base; }
+ void xput_char(char c) { *_pptr++ = c; }
+ int xflags() { return _flags; }
+ int xflags(int f) { int fl = _flags; _flags = f; return fl; }
+ void xsetflags(int f) { _flags |= f; }
+ void xsetflags(int f, int mask) { _flags = (_flags & ~mask) | (f & mask); }
+ void gbump(int n) { _gptr += n; }
+ void pbump(int n) { _pptr += n; }
+ void setb(char* b, char* eb, int a=0);
+ void setp(char* p, char* ep) { _pbase=_pptr=p; _epptr=ep; }
+ void setg(char* eb, char* g, char *eg) { _eback=eb; _gptr=g; _egptr=eg; }
+ char *shortbuf() { return _shortbuf; }
+
+ int in_backup() { return _flags & _S_IN_BACKUP; }
+ // The start of the main get area: FIXME: wrong for write-mode filebuf?
+ char *Gbase() { return in_backup() ? _other_gbase : _eback; }
+ // The end of the main get area:
+ char *eGptr() { return in_backup() ? _other_egptr : _egptr; }
+ // The start of the backup area:
+ char *Bbase() { return in_backup() ? _eback : _other_gbase; }
+ char *Bptr() { return _aux_limit; }
+ // The end of the backup area:
+ char *eBptr() { return in_backup() ? _egptr : _other_egptr; }
+ char *Nbase() { return _other_gbase; }
+ char *eNptr() { return _other_egptr; }
+ int have_backup() { return _other_gbase != NULL; }
+ int have_markers() { return _markers != NULL; }
+ int _least_marker();
+ void switch_to_main_get_area();
+ void switch_to_backup_area();
+ void free_backup_area();
+ void unsave_markers(); // Make all streammarkers !saving().
+ int put_mode() { return _flags & _S_CURRENTLY_PUTTING; }
+ int switch_to_get_mode();
+
+ streambuf(int flags=0);
+ public:
+ static int flush_all();
+ static void flush_all_linebuffered(); // Flush all line buffered files.
+ virtual int underflow() = 0; // Leave public for now
+ virtual int overflow(int c = EOF) = 0; // Leave public for now
+ virtual int doallocate();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+ virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
+ int seekmark(streammarker& mark, int delta = 0);
+ int sputbackc(char c);
+ int sungetc();
+ virtual ~streambuf();
+ int unbuffered() { return _flags & _S_UNBUFFERED ? 1 : 0; }
+ int linebuffered() { return _flags & _S_LINE_BUF ? 1 : 0; }
+ void unbuffered(int i)
+ { if (i) _flags |= _S_UNBUFFERED; else _flags &= ~_S_UNBUFFERED; }
+ void linebuffered(int i)
+ { if (i) _flags |= _S_LINE_BUF; else _flags &= ~_S_LINE_BUF; }
+ int allocate() { // For AT&T compatibility
+ if (base() || unbuffered()) return 0;
+ else return doallocate(); }
+ // Allocate a buffer if needed; use _shortbuf if appropriate.
+ void allocbuf() { if (base() == NULL) doallocbuf(); }
+ void doallocbuf();
+ virtual int sync();
+ virtual int pbackfail(int c);
+ virtual streambuf* setbuf(char* p, int len);
+ int in_avail() { return _egptr - _gptr; }
+ int out_waiting() { return _pptr - _pbase; }
+ virtual int xsputn(const char* s, int n);
+ int sputn(const char* s, int n) { return xsputn(s, n); }
+ int padn(char pad, int n); // Emit 'n' copies of 'pad'.
+ virtual int xsgetn(char* s, int n);
+ int sgetn(char* s, int n) { return xsgetn(s, n); }
+ int ignore(int);
+ virtual int get_column();
+ virtual int set_column(int);
+ long sgetline(char* buf, _G_size_t n, char delim, int putback_delim);
+ int sbumpc() {
+ if (_gptr >= _egptr && __underflow(this) == EOF) return EOF;
+ else return *(unsigned char*)_gptr++; }
+ int sgetc() {
+ if (_gptr >= _egptr && __underflow(this) == EOF) return EOF;
+ else return *(unsigned char*)_gptr; }
+ int snextc() {
+ if (_gptr >= _egptr && __underflow(this) == EOF) return EOF;
+ else return _gptr++, sgetc(); }
+ int sputc(int c) {
+ if (_pptr >= _epptr) return __overflow(this, (unsigned char)c);
+ else return *_pptr++ = c, (unsigned char)c; }
+ void stossc() { if (_gptr < _egptr) _gptr++; }
+ int vscan(char const *fmt0, _G_va_list ap, ios* stream = NULL);
+ int scan(char const *fmt0 ...);
+ int vform(char const *fmt0, _G_va_list ap);
+ int form(char const *fmt0 ...);
+#if 0 /* Work in progress */
+ int collumn(); // Current collumn number (of put pointer). -1 is unknown.
+ void collumn(int c); // Set collumn number of put pointer to c.
+#endif
+};
+
+// A backupbuf is a streambuf with full backup and savepoints on reading.
+// All standard streambufs in the GNU iostream library are backupbufs.
+
+// A backupbuf may have two get area:
+// - The main get area, and (sometimes) the putback area.
+// Whichever one of these contains the gptr is the current get area;
+// the other one is the non-current get area.
+
+class backupbuf : public streambuf {
+ friend class streammarker;
+ protected:
+ backupbuf(int flags=0) : streambuf(flags|_S_IS_BACKUPBUF) { }
+ public:
+ virtual int pbackfail(int c);
+ virtual int underflow();
+ virtual int overflow(int c = EOF);
+};
+
+struct __file_fields {
+ short _fileno;
+ int _blksize;
+ _G_off_t _offset;
+// char* _save_gptr; char* _save_egptr;
+};
+
+class filebuf : public backupbuf {
+ protected:
+ struct __file_fields _fb;
+ 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);
+ ~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 _fb._fileno >= 0; }
+ int fd() const { return is_open() ? _fb._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);
+ int xsputn(const char* s, int n);
+ int xsgetn(char* s, int n);
+ virtual int sync();
+ protected: // See documentation in filebuf.C.
+// virtual int pbackfail(int c);
+ int is_reading() { return eback() != egptr(); }
+ char* cur_ptr() { return is_reading() ? gptr() : pptr(); }
+ /* System's idea of pointer */
+ char* file_ptr() { return eGptr(); }
+ int do_write(const char *data, int to_do);
+ int do_flush() { return do_write(_pbase, _pptr-_pbase); }
+ // Low-level operations (Usually invoke system calls.)
+ virtual _G_ssize_t sys_read(char* buf, _G_size_t size);
+ virtual _G_fpos_t sys_seek(_G_fpos_t, _seek_dir);
+ virtual _G_ssize_t sys_write(const void*, long);
+ virtual int sys_stat(void*); // Actually, a (struct stat*)
+ virtual int sys_close();
+};
+
+inline ios::ios(streambuf* sb /* = 0 */, ostream* tie_to /* = 0 */) {
+ _state = sb ? ios::goodbit : ios::badbit; _exceptions=0;
+ _strbuf=sb; _tie = tie_to; _width=0; _fill=' ';
+ _flags=ios::skipws|ios::dec; _precision=6; }
+inline ios::~ios() {
+ if (!(_flags & (unsigned int)ios::dont_close)) delete _strbuf; }
+
+#endif /* _STREAMBUF_H */
diff --git a/gnu/lib/libg++/iostream/strstream.C b/gnu/lib/libg++/iostream/strstream.C
new file mode 100644
index 00000000000..d5a57137d52
--- /dev/null
+++ b/gnu/lib/libg++/iostream/strstream.C
@@ -0,0 +1,237 @@
+// This is part of the iostream library, providing input/output for C++.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "ioprivate.h"
+#include <strstream.h>
+
+static void* default_alloc(_G_size_t size)
+{
+ return (void*)new char[size];
+}
+
+static void default_free(void* ptr)
+{
+ delete [] (char*)ptr;
+}
+
+istrstream::istrstream(const char *cp, int n)
+{
+ init(new strstreambuf(cp, n));
+}
+
+ostrstream::ostrstream()
+{
+ init(new strstreambuf());
+}
+
+strstreambase::strstreambase(char *cp, int n, int mode)
+{
+ char *pstart;
+ if (mode == ios::app || mode == ios::ate)
+ pstart = cp + strlen(cp);
+ else
+ pstart = cp;
+ init(new strstreambuf(cp, n, pstart));
+}
+
+char *strstreambuf::str()
+{
+ freeze(1);
+ return base();
+}
+
+_G_size_t strstreambuf::pcount()
+{
+ _G_size_t put_len = pptr() - pbase();
+ if (put_len < _len) put_len = _len;
+ return put_len;
+}
+
+int strstreambuf::overflow(int c /* = EOF */)
+{
+ const int flush_only = c == EOF;
+ if (_flags & _S_NO_WRITES)
+ return flush_only ? 0 : EOF;
+ size_t pos = pptr() - pbase();
+ size_t get_pos = gptr() - pbase();
+ if (pos > _len) _len = pos;
+ if (pos >= blen() + flush_only) {
+ char *new_buf;
+ size_t new_size = 2 * blen();
+ if (frozen()) /* not allowed to enlarge */
+ return EOF;
+ new_buf = (char*)(*_allocate_buffer)(new_size);
+ memcpy(new_buf, base(), blen());
+ if (new_buf == NULL) {
+// __ferror(fp) = 1;
+ return EOF;
+ }
+#if 0
+ if (lenp == &_len) /* use '\0'-filling */
+ memset(new_buf + pos, 0, blen() - pos);
+#endif
+ if (_base) {
+ (*_free_buffer)(_base);
+ _base = NULL; // So setb() won't try to delete _base.
+ }
+ setb(new_buf, new_buf + new_size, 1);
+ }
+
+ setp(base(), ebuf());
+ pbump(pos);
+ setg(base(), base() + get_pos, base() + _len);
+ if (!flush_only) {
+ *pptr() = (unsigned char) c;
+ pbump(1);
+ }
+ return c;
+}
+
+int strstreambuf::underflow()
+{
+ size_t ppos = pptr() - pbase();
+ if (ppos > _len) _len = ppos;
+ setg(base(), gptr(), base() + _len);
+ if (gptr() < egptr())
+ return *gptr();
+ else
+ return EOF;
+}
+
+
+void strstreambuf::init_dynamic(_alloc_type alloc, _free_type free,
+ int initial_size)
+
+{
+ _len = 0;
+ if (initial_size < 16)
+ initial_size = 16;
+ _allocate_buffer = alloc ? alloc : default_alloc;
+ _free_buffer = free ? free : default_free;
+ char * buf = (char*)(*_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)
+{
+ 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
+ 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 (int 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
+ }
+ setb(ptr, ptr+size);
+ if (pstart) {
+ setp(ptr, ebuf());
+ pbump(pstart-ptr);
+ setg(ptr, ptr, pstart);
+ }
+ else {
+ setp(ptr, ptr);
+ setg(ptr, ptr, ebuf());
+ }
+ _len = egptr() - ptr;
+}
+
+void strstreambuf::init_static (const char *ptr, int size)
+{
+ init_static((char*)ptr, size, NULL);
+ xsetflags(_S_NO_WRITES);
+}
+
+strstreambuf::~strstreambuf()
+{
+ if (_base && !(_flags & _S_USER_BUF))
+ (_free_buffer)(_base);
+ _base = NULL;
+}
+
+streampos strstreambuf::seekoff(streamoff off, _seek_dir dir,
+ int mode /*=ios::in|ios::out*/)
+{
+ size_t cur_size = pcount();
+ streampos new_pos = EOF;
+
+ // Move the get pointer, if requested.
+ if (mode & ios::in) {
+ switch (dir) {
+ case ios::end:
+ off += cur_size;
+ break;
+ case ios::cur:
+ off += gptr() - pbase();
+ break;
+ default: /*case ios::beg: */
+ break;
+ }
+ if (off < 0 || (size_t)off > cur_size)
+ return EOF;
+ setg(base(), base() + off, base() + cur_size);
+ new_pos = off;
+ }
+
+ // Move the put pointer, if requested.
+ if (mode & ios::out) {
+ switch (dir) {
+ case ios::end:
+ off += cur_size;
+ break;
+ case ios::cur:
+ off += pptr() - pbase();
+ break;
+ default: /*case ios::beg: */
+ break;
+ }
+ if (off < 0 || (size_t)off > cur_size)
+ return EOF;
+ pbump(base() + off - pptr());
+ new_pos = off;
+ }
+ return new_pos;
+}
+
+int strstreambuf::pbackfail(int c)
+{
+ if ((_flags & _S_NO_WRITES) && c != EOF)
+ return EOF;
+ return backupbuf::pbackfail(c);
+}
diff --git a/gnu/lib/libg++/iostream/strstream.h b/gnu/lib/libg++/iostream/strstream.h
new file mode 100644
index 00000000000..9302a60ee59
--- /dev/null
+++ b/gnu/lib/libg++/iostream/strstream.h
@@ -0,0 +1,105 @@
+// This is part of the iostream library, providing -*- C++ -*- input/output.
+// Copyright (C) 1991 Per Bothner.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free
+// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id: strstream.h,v 1.1 1995/10/18 08:38:14 deraadt Exp $
+
+#ifndef __STRSTREAM_H
+#define __STRSTREAM_H
+#ifdef __GNUG__
+#pragma interface
+#endif
+#include <iostream.h>
+
+class strstreambuf : public backupbuf {
+ _G_size_t _len; // The current length is max(_len, _pptr-_pbase).
+ typedef void *(*_alloc_type)(_G_size_t);
+ typedef void (*_free_type)(void*);
+ _alloc_type _allocate_buffer;
+ _free_type _free_buffer;
+ void init_dynamic(_alloc_type alloc, _free_type free,
+ int initial_size = 128);
+ void init_static(char *ptr, int size, char *pstart);
+ void init_static(const char *ptr, int size);
+ protected:
+ int is_static() const { return _allocate_buffer == (_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)(_G_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_static(ptr, size); }
+ strstreambuf(const unsigned char *ptr, int size)
+ { init_static((const char*)ptr, size); }
+#ifndef _G_BROKEN_SIGNED_CHAR
+ 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_static((const char*)ptr, size); }
+#endif
+ // Note: frozen() is always true if is_static().
+ int frozen() { return _flags & _S_USER_BUF ? 1 : 0; }
+ void freeze(int n=1)
+ { if (!is_static())
+ { if (n) _flags |= _S_USER_BUF; else _flags &= ~_S_USER_BUF; } }
+ _G_size_t pcount();
+ char *str();
+ virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
+};
+
+class strstreambase : virtual public ios {
+ public:
+ strstreambuf* rdbuf() { return (strstreambuf*)_strbuf; }
+ protected:
+ strstreambase() { }
+ strstreambase(char *cp, int n, int mode=ios::out);
+};
+
+class istrstream : public strstreambase, public istream {
+ public:
+ istrstream(const char*, int=0);
+};
+
+class ostrstream : public strstreambase, public ostream {
+ public:
+ ostrstream();
+ ostrstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
+ _G_size_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
+ char *str() { return ((strstreambuf*)_strbuf)->str(); }
+ void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
+ int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
+};
+
+class strstream : public strstreambase, public iostream {
+ public:
+ strstream() : strstreambase() { init(new strstreambuf()); }
+ strstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
+ _G_size_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
+ char *str() { return ((strstreambuf*)_strbuf)->str(); }
+ void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
+ int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
+};
+
+#endif /*!__STRSTREAM_H*/