+++ /dev/null
-
- 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.
-\f
- 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.
-\f
- 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.
-\f
- 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
-\f
- 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!
+++ /dev/null
-# $Id: Makefile,v 1.1.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>
+++ /dev/null
-libg++ version 2.4
-
-complete, unmodified libg++ sources are available from prep.ai.mit.edu.
+++ /dev/null
-// 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
- //
-
- register int l;
- for (l = 0;
- randomStateTable[l][0] != -1 && randomStateTable[l][1] < size;
- l++);
-
- if (randomStateTable[l][1] == -1) {
- l--;
- }
-
- initialTableEntry = l;
-
- stateSize = randomStateTable[ initialTableEntry ][ 1 ];
- auxSize = randomStateTable[ initialTableEntry ][ 2 ];
-
- //
- // Allocate the state table & the auxillary table in a single malloc
- //
-
- state = new 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);
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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));
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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());
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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 */
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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) );
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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);
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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);
- int i;
- for ( i=r->siz-1; i >= longer->siz; i-- )
- r->s[i] = 0;
- for ( ; i >= shorter->siz; i-- )
- r->s[i] = longer->s[i];
- 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);
- int i;
- for ( i=r->siz-1; i >= longer->siz; i-- )
- r->s[i] = 0;
- for ( ; i >= shorter->siz; i-- )
- r->s[i] = (longer == x ? x->s[i] : -y->s[i]);
- 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);
- int i;
- for ( 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);
- int i;
- for ( 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;
- int i;
- for ( i=0; i < ilow; i++, rs+=u, xsl+=u, xsr+=u )
- *rs = 0;
- for ( ; i < ihigh; i++, rs+=u, xsl+=u, xsr+=u )
- *rs = (*xsl << xl) + ((*xsr >> xr) & xrmask);
- *rs = (y > 0 ? (*xsl << xl) : ((*xsr >> xr) & xrmask));
- rs += u;
- for ( ; ++i < r->siz; rs+=u )
- *rs = 0;
- return r;
-}
-
-_Fix negate(_Fix x, _Fix r)
-{
- if ( r == NULL )
- r = new_Fix(x->len);
- uint32 carry = 1;
- int i;
- for ( 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();
-}
-
+++ /dev/null
-//
-// Fix.h : variable length fixed point data type
-//
-// $Id: Fix.h,v 1.2 1995/12/21 11:09:10 niklas 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(const 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;
- int i;
- for ( 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(const Fix& y)
-{
- rep = y.rep; rep->ref++;
-}
-
-inline Fix::Fix(int len, const Fix& y)
-{
- if ( len < _Fix_min_length || len > _Fix_max_length )
- error("illegal length in declaration");
- rep = new_Fix((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
+++ /dev/null
-// 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(); }
-
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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(); }
-
+++ /dev/null
-// 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.2 1995/12/21 11:09:11 niklas 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) & (long)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
+++ /dev/null
-/*
-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);
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
-}
-\f
-/* 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;
- }
-}
+++ /dev/null
-/* 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.1.1 1995/10/18 08:38:16 deraadt Exp $
-*/
-\f
-/* 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
+++ /dev/null
-
-/*
-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) );
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
- int i;
- for (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);
-}
-
+++ /dev/null
-// 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.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 */
+++ /dev/null
-/*
-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()() ) );
-}
-
-
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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);
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-# $Id: Makefile,v 1.2 1995/12/14 03:42: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 | grep curses
-
-.include <bsd.lib.mk>
+++ /dev/null
-/*
-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()));
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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);
- }
- }
- }
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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
-{
- _obstack_chunk* ch;
- for (ch = chunk;
- ch != 0 && (obj < (void*)ch || obj >= (void*)(ch->limit));
- ch = ch->prev);
-
- return ch != 0;
-}
-
-int Obstack::OK()
-{
- int v = chunksize > 0; // valid size
- v &= alignmentmask != 0; // and alignment
- v &= chunk != 0;
- v &= objectbase >= chunk->contents;
- v &= nextfree >= objectbase;
- v &= nextfree <= chunklimit;
- v &= chunklimit == chunk->limit;
- _obstack_chunk* p = chunk;
- // allow lots of chances to find bottom!
- long x = MAXLONG;
- while (p != 0 && x != 0) { --x; p = p->prev; }
- v &= x > 0;
- if (!v)
- (*lib_error_handler)("Obstack", "invariant failure");
- return v;
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-/* $Id: Pix.h,v 1.1.1.1 1995/10/18 08:38:17 deraadt Exp $ */
-
-#ifndef _Pix_h
-#define _Pix_h 1
-typedef void* Pix;
-#endif
+++ /dev/null
-
-/*
-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);
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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 );
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include <Random.h>
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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);
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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);
-
+++ /dev/null
-// 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.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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include <RndInt.h>
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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*/
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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;
- }
- }
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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));
-}
-
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
- int i;
- for (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()]);
- int l;
- for (l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
- r.rep = Salloc(r.rep, ss, l, l);
-}
-
-String common_suffix(const String& x, const String& y, int startpos) return r;
-{
- const char* xchars = x.chars();
- const char* ychars = y.chars();
- const char* xs = &(xchars[x.length() + startpos]);
- const char* botx = xchars;
- const char* ys = &(ychars[y.length() + startpos]);
- const char* boty = ychars;
- int l;
- for (l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
- r.rep = Salloc(r.rep, ++xs, l, l);
-}
-
-#else
-
-String replicate(char c, int n)
-{
- String w;
- w.rep = Sresize(w.rep, n);
- char* p = w.rep->s;
- while (n-- > 0) *p++ = c;
- *p = 0;
- return w;
-}
-
-String replicate(const String& y, int n)
-{
- String w;
- int len = y.length();
- w.rep = Sresize(w.rep, n * len);
- char* p = w.rep->s;
- while (n-- > 0)
- {
- ncopy(y.chars(), p, len);
- p += len;
- }
- *p = 0;
- return w;
-}
-
-String common_prefix(const String& x, const String& y, int startpos)
-{
- String r;
- const char* xchars = x.chars();
- const char* ychars = y.chars();
- const char* xs = &(xchars[startpos]);
- const char* ss = xs;
- const char* topx = &(xchars[x.length()]);
- const char* ys = &(ychars[startpos]);
- const char* topy = &(ychars[y.length()]);
- 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;
-}
-
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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() );
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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) );
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-/* $Id: _G_config.h,v 1.1.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 */
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include <builtin.h>
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
-}
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include <compare.h>
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
- char *p;
- for (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;
-
- int i;
- for (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
+++ /dev/null
-/*
-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" 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;
-}
-
+++ /dev/null
-/*
-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);
+++ /dev/null
-/*
-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;
- }
- }
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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();
- }
-}
-
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.DLDeque.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-#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);
-}
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.FPQueue.h"
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.FPStack.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-#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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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);
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
-
-
-
+++ /dev/null
-// 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
+++ /dev/null
-#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);
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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);
- }
- }
- }
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.SLQueue.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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);
- }
- }
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.SLStack.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-#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);
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
-
-
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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();
- }
- }
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.XPDeque.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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();
-}
-
-
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.XPQueue.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
- }
- }
-}
-
+++ /dev/null
-// 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
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include "<T>.XPStack.h"
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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
+++ /dev/null
-/*
-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;
-}
-
+++ /dev/null
-/*
-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;
+++ /dev/null
-/*
-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;
-}
+++ /dev/null
-#ifdef __GNUG__
-#pragma implementation
-#endif
-#include <math.h>
+++ /dev/null
-// 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
+++ /dev/null
-/* $Id: new.h,v 1.1.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
+++ /dev/null
-/* $Id: osfcn.h,v 1.1.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
+++ /dev/null
-/*
-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;
- }
- }
-}
+++ /dev/null
-/* 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;
-
-
-\f
-/* 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);
-}
-
-
-\f
-/* 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;
- }
-}
-
-
-\f
-/* 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;
-}
-
-
-\f
-#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 *) ®_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;
-}
-
-
-\f
-/* 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 */
-
-
-\f
-#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 */
+++ /dev/null
-/* 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.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];
- };
-
-
-\f
-#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 */
+++ /dev/null
-major=2
-minor=0
+++ /dev/null
-/*
-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;
- }
- }
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-/*
-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;
-}
+++ /dev/null
-/*
-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 */
-
-
+++ /dev/null
-// 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.2 1995/12/17 13:30:58 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)
-
-#ifndef __NetBSD__ /* XXX */
-#define MAXFLOAT 1.7014117331926443e+38
-#endif /* ! __NetBSD__ */
-#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
-
+++ /dev/null
-# 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"
+++ /dev/null
-#!/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;
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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.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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/*
-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;
-}
+++ /dev/null
-// 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.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
+++ /dev/null
-// 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);
- }
- }
-}
+++ /dev/null
-// 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.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*/
-
+++ /dev/null
-// 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;
+++ /dev/null
-#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 */
+++ /dev/null
-/*
- * 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.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
+++ /dev/null
-// 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
+++ /dev/null
-// 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.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*/
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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.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 */
+++ /dev/null
-// -*- 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;
-}
+++ /dev/null
-// -*- 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.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*/
+++ /dev/null
-// 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.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
-
+++ /dev/null
-// 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
+++ /dev/null
-// 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.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*/
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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
-}
+++ /dev/null
-// 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.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)*/
+++ /dev/null
-// 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();
-}
+++ /dev/null
-// 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.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();
-};
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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.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 */
+++ /dev/null
-// 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
-#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5 // XXX I'm not sure it was
- // introduced in 2.5
-extern char vt_filebuf[1] asm(UNDERSCORE "_vt$7filebuf");
-#else
-extern char vt_filebuf[1] asm(UNDERSCORE "_vt$filebuf");
-#endif
-#else
-#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5 // XXX I'm not sure it was
- // introduced in 2.5
-extern char vt_filebuf[1] asm(UNDERSCORE "_vt.7filebuf");
-#else
-extern char vt_filebuf[1] asm(UNDERSCORE "_vt.filebuf");
-#endif
-#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
-#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5 // XXX I'm not sure it was
- // introduced in 2.5
-extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt$8stdiobuf");
-#else
-extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt$stdiobuf");
-#endif
-#else
-#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5 // XXX I'm not sure it was
- // introduced in 2.5
-extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt.8stdiobuf");
-#else
-extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt.stdiobuf");
-#endif
-#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;
+++ /dev/null
-// 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
-}
+++ /dev/null
-#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);
-}
+++ /dev/null
-// $Id: stream.h,v 1.1.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 */
+++ /dev/null
-// 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
+++ /dev/null
-// 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.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 */
+++ /dev/null
-// 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.
- int s;
- for (; 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);
-}
+++ /dev/null
-// 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.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*/